summaryrefslogtreecommitdiffstats
path: root/snaps/config/vm_inst.py
diff options
context:
space:
mode:
Diffstat (limited to 'snaps/config/vm_inst.py')
-rw-r--r--snaps/config/vm_inst.py166
1 files changed, 166 insertions, 0 deletions
diff --git a/snaps/config/vm_inst.py b/snaps/config/vm_inst.py
new file mode 100644
index 0000000..6a63e33
--- /dev/null
+++ b/snaps/config/vm_inst.py
@@ -0,0 +1,166 @@
+# Copyright (c) 2017 Cable Television Laboratories, Inc. ("CableLabs")
+# and others. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+from snaps.config.network import PortConfig
+
+
+class VmInstanceConfig(object):
+ """
+ Class responsible for holding configuration setting for a VM Instance
+ """
+
+ def __init__(self, **kwargs):
+ """
+ Constructor
+ :param name: the name of the VM
+ :param flavor: the VM's flavor name
+ :param port_settings: the port configuration settings (required)
+ :param security_group_names: a set of names of the security groups to
+ add to the VM
+ :param floating_ip_settings: the floating IP configuration settings
+ :param sudo_user: the sudo user of the VM that will override the
+ instance_settings.image_user when trying to
+ connect to the VM
+ :param vm_boot_timeout: the amount of time a thread will wait
+ for an instance to boot
+ :param vm_delete_timeout: the amount of time a thread will wait
+ for an instance to be deleted
+ :param ssh_connect_timeout: the amount of time a thread will wait
+ to obtain an SSH connection to a VM
+ :param cloud_init_timeout: the amount of time a thread will wait for
+ cloud-init to complete
+ :param availability_zone: the name of the compute server on which to
+ deploy the VM (optional)
+ :param volume_names: a list of the names of the volume to attach
+ (optional)
+ :param userdata: the string contents of any optional cloud-init script
+ to execute after the VM has been activated.
+ This value may also contain a dict who's key value
+ must contain the key 'cloud-init_file' which denotes
+ the location of some file containing the cloud-init
+ script
+ """
+ self.name = kwargs.get('name')
+ self.flavor = kwargs.get('flavor')
+ self.sudo_user = kwargs.get('sudo_user')
+ self.userdata = kwargs.get('userdata')
+
+ self.port_settings = list()
+ port_settings = kwargs.get('ports')
+ if not port_settings:
+ port_settings = kwargs.get('port_settings')
+ if port_settings:
+ for port_setting in port_settings:
+ if isinstance(port_setting, dict):
+ self.port_settings.append(PortConfig(**port_setting))
+ elif isinstance(port_setting, PortConfig):
+ self.port_settings.append(port_setting)
+
+ if kwargs.get('security_group_names'):
+ if isinstance(kwargs['security_group_names'], list):
+ self.security_group_names = kwargs['security_group_names']
+ elif isinstance(kwargs['security_group_names'], set):
+ self.security_group_names = kwargs['security_group_names']
+ elif isinstance(kwargs['security_group_names'], str):
+ self.security_group_names = [kwargs['security_group_names']]
+ else:
+ raise VmInstanceConfigError(
+ 'Invalid data type for security_group_names attribute')
+ else:
+ self.security_group_names = set()
+
+ self.floating_ip_settings = list()
+ floating_ip_settings = kwargs.get('floating_ips')
+ if not floating_ip_settings:
+ floating_ip_settings = kwargs.get('floating_ip_settings')
+ if floating_ip_settings:
+ for floating_ip_config in floating_ip_settings:
+ if isinstance(floating_ip_config, FloatingIpConfig):
+ self.floating_ip_settings.append(floating_ip_config)
+ else:
+ self.floating_ip_settings.append(FloatingIpConfig(
+ **floating_ip_config['floating_ip']))
+
+ self.vm_boot_timeout = kwargs.get('vm_boot_timeout', 900)
+ self.vm_delete_timeout = kwargs.get('vm_delete_timeout', 300)
+ self.ssh_connect_timeout = kwargs.get('ssh_connect_timeout', 180)
+ self.cloud_init_timeout = kwargs.get('cloud_init_timeout', 300)
+ self.availability_zone = kwargs.get('availability_zone')
+ self.volume_names = kwargs.get('volume_names')
+
+ if self.volume_names and not isinstance(self.volume_names, list):
+ raise VmInstanceConfigError('volume_names must be a list')
+
+ if not self.name or not self.flavor:
+ raise VmInstanceConfigError(
+ 'Instance configuration requires the attributes: name, flavor')
+
+ if len(self.port_settings) == 0:
+ raise VmInstanceConfigError(
+ 'Instance configuration requires port settings (aka. NICS)')
+
+
+class FloatingIpConfig(object):
+ """
+ Class responsible for holding configuration settings for a floating IP
+ """
+
+ def __init__(self, **kwargs):
+ """
+ Constructor
+ :param name: the name of the floating IP
+ :param port_name: the name of the router to the external network
+ :param router_name: the name of the router to the external network
+ :param subnet_name: the name of the subnet on which to attach the
+ floating IP
+ :param provisioning: when true, this floating IP can be used for
+ provisioning
+
+ TODO - provisioning flag is a hack as I have only observed a single
+ Floating IPs that actually works on an instance. Multiple floating IPs
+ placed on different subnets from the same port are especially
+ troublesome as you cannot predict which one will actually connect.
+ For now, it is recommended not to setup multiple floating IPs on an
+ instance unless absolutely necessary.
+ """
+ self.name = kwargs.get('name')
+ self.port_name = kwargs.get('port_name')
+ self.port_id = kwargs.get('port_id')
+ self.router_name = kwargs.get('router_name')
+ self.subnet_name = kwargs.get('subnet_name')
+ if kwargs.get('provisioning') is not None:
+ self.provisioning = kwargs['provisioning']
+ else:
+ self.provisioning = True
+
+ # if not self.name or not self.port_name or not self.router_name:
+ if not self.name or not self.router_name:
+ raise FloatingIpConfigError(
+ 'The attributes name, port_name and router_name are required')
+
+ if not self.port_name and not self.port_id:
+ raise FloatingIpConfigError(
+ 'The attributes port_name or port_id are required')
+
+
+class VmInstanceConfigError(Exception):
+ """
+ Exception to be thrown when an VM instance settings are incorrect
+ """
+
+
+class FloatingIpConfigError(Exception):
+ """
+ Exception to be thrown when an VM instance settings are incorrect
+ """