gns3-server/gns3server/schemas/controller/computes.py

187 lines
5.3 KiB
Python

#
# Copyright (C) 2020 GNS3 Technologies Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import uuid
from pydantic import BaseModel, Field, SecretStr, validator
from typing import List, Optional, Union
from enum import Enum
from .nodes import NodeType
from .base import DateTimeModelMixin
class Protocol(str, Enum):
"""
Protocol supported to communicate with a compute.
"""
http = "http"
https = "https"
class ComputeBase(BaseModel):
"""
Data to create a compute.
"""
protocol: Protocol
host: str
port: int = Field(..., gt=0, le=65535)
user: str = None
password: Optional[SecretStr] = None
name: Optional[str] = None
class Config:
use_enum_values = True
class ComputeCreate(ComputeBase):
"""
Data to create a compute.
"""
compute_id: Union[str, uuid.UUID] = None
class Config:
schema_extra = {
"example": {
"name": "My compute",
"host": "127.0.0.1",
"port": 3080,
"user": "user",
"password": "password"
}
}
@validator("compute_id", pre=True, always=True)
def default_compute_id(cls, v, values):
if v is not None:
return v
else:
protocol = values.get("protocol")
host = values.get("host")
port = values.get("port")
return uuid.uuid5(uuid.NAMESPACE_URL, f"{protocol}://{host}:{port}")
@validator("name", pre=True, always=True)
def generate_name(cls, name, values):
if name is not None:
return name
else:
protocol = values.get("protocol")
host = values.get("host")
port = values.get("port")
user = values.get("user")
if user:
# due to random user generated by 1.4 it's common to have a very long user
if len(user) > 14:
user = user[:11] + "..."
return f"{protocol}://{user}@{host}:{port}"
else:
return f"{protocol}://{host}:{port}"
class ComputeUpdate(ComputeBase):
"""
Data to update a compute.
"""
protocol: Optional[Protocol] = None
host: Optional[str] = None
port: Optional[int] = Field(None, gt=0, le=65535)
user: Optional[str] = None
password: Optional[SecretStr] = None
class Config:
schema_extra = {
"example": {
"host": "10.0.0.1",
"port": 8080,
}
}
class Capabilities(BaseModel):
"""
Capabilities supported by a compute.
"""
version: str = Field(..., description="Compute version number")
node_types: List[NodeType] = Field(..., description="Node types supported by the compute")
platform: str = Field(..., description="Platform where the compute is running (Linux, Windows or macOS)")
cpus: int = Field(..., description="Number of CPUs on this compute")
memory: int = Field(..., description="Amount of memory on this compute")
disk_size: int = Field(..., description="Disk size on this compute")
class Compute(DateTimeModelMixin, ComputeBase):
"""
Data returned for a compute.
"""
compute_id: Union[str, uuid.UUID]
name: str
connected: Optional[bool] = Field(None, description="Whether the controller is connected to the compute or not")
cpu_usage_percent: Optional[float] = Field(None, description="CPU usage of the compute", ge=0, le=100)
memory_usage_percent: Optional[float] = Field(None, description="Memory usage of the compute", ge=0, le=100)
disk_usage_percent: Optional[float] = Field(None, description="Disk usage of the compute", ge=0, le=100)
last_error: Optional[str] = Field(None, description="Last error found on the compute")
capabilities: Optional[Capabilities] = None
class Config:
orm_mode = True
class ComputeVirtualBoxVM(BaseModel):
"""
VirtualBox VM from compute.
"""
vmname: str = Field(..., description="VirtualBox VM name")
ram: int = Field(..., description="VirtualBox VM memory")
class ComputeVMwareVM(BaseModel):
"""
VMware VM from compute.
"""
vmname: str = Field(..., description="VMware VM name")
class ComputeDockerImage(BaseModel):
"""
Docker image from compute.
"""
image: str = Field(..., description="Docker image name")
class AutoIdlePC(BaseModel):
"""
Data for auto Idle-PC request.
"""
platform: str = Field(..., description="Cisco platform")
image: str = Field(..., description="Image path")
ram: int = Field(..., description="Amount of RAM in MB")
class Config:
schema_extra = {"example": {"platform": "c7200", "image": "/path/to/c7200_image.bin", "ram": 256}}