def get_cloud_driver_context(self, cloud_manager): if cloud_manager: if cloud_manager.name not in self.driver_contexts: if cloud_manager.type.lower() == "openstack": _("... Building context") context = OSDriverContext(OSClient(cloud_manager.path, cloud_manager.username, cloud_manager.tenant, cloud_manager.password)) __() elif cloud_manager.type.lower() == "stub": context = StubDriverContext() else: error('%s type of CLOUD MANAGER IS UNKNOWN!', cloud_manager.type) raise IntegrityException if context.authenticated(): self.driver_contexts[cloud_manager.name] = context self.cloud_manager.set_authenticated(cloud_manager.name) else: self.driver_contexts[cloud_manager.name] = None self.cloud_manager.set_authenticated(cloud_manager.name, False) output() warn('Cloud manager %s failed authentication.', cloud_manager.name) return self.driver_contexts[cloud_manager.name] else: error('No driver found for None cloud manager') raise IntegrityException
def obtain_entity_to_add(self): name = string_input('Name', default='demo') if name == Cluster.UNNAMED_CLUSTER: error('This is a reserved name.') return None cmm = self.obtain_entity_name(self.minicloud.cloud_manager) return Cluster(name, cmm) if cmm else None
def connect(self): output('\nPlease enter the name of the instance you would like to connect to.') try: fip = None instance = self.obtain_entity(filter_f=self.is_active) if instance: fip = self.manager.get_instance_fip(instance) if fip is None: if boolean_input('This instance is not publicly routable yet.\n' 'Do you want to make it routable'): fip = self.make_instance_routable(instance) if fip is None: output('No instance connected to.') return output('%s is publicly routable via %s', instance.name, fip) output() suggested_username, suggested_password = self.get_suggested_instance_credentials(instance) output('Connecting to %s...', fip) username = string_input('Username', default=suggested_username) password = string_input('Password', default=suggested_password) # connect self.manager.connect_to_instance(instance, username, password) output() output('Successfully established a connection.\n' 'Returning to MiniCloud now.') except DoesNotExistException: output('No instance connected to.') except MiniCloudException: error('Connecting to the instance failed.')
def remove_entity(self): entity = self.obtain_entity(filter_f=self.manager.filter_for_remove) if entity: return self.check_for_remove(entity) and self.manager.deep_remove(entity) else: error("This entity does not exist") return False
def get_cloud_manager(self, cluster_name): cluster = self.cluster_manager.get(cluster_name) if cluster: cloud_manager = self.cloud_manager.get(cluster.cloud_manager_name) return cloud_manager error('No cloud manager found for cluster \'%s\'.', cluster_name) raise IntegrityException
def flavor(self, cloud_flavor=None): _('... Retrieving flavor') flavor = self._nova.flavors(cloud_flavor['id']) __() if len(flavor) > 0: return flavor[0] else: error('Flavor %s not found!', cloud_flavor) return None
def check_for_remove(self, network): if network.external: error('You can\'t delete this network as it is external.') return False else: routers = self.manager.get_routers(network) if routers: output('The network is attached to router %s. Detaching it.', routers[0].name) self.detach(network) return True
def image(self, cloud_image=None): _('... Retrieving image') image = self._nova.images(cloud_image['id']) __() if len(image) > 0: return image[0] else: error('Image %s not found!', cloud_image) error('All retrieved images are: %s', self.images()) return None
def update_entity(self, entity, data): try: ctx = self.get_entity_driver_context(entity) if ctx and ctx.authenticated(): return self.reconfig_entity(ctx, entity, data) else: raise IntegrityException except MiniCloudException as e: error('Failed to update %s \'%s\'.', self.entity_name(), entity.name) raise e
def __init__(self, db, table): self.db = db self.table = table try: self._db = dataset.connect(db) self._store = self._db[table] except OperationalError as e: error('%s: %s: Can\'t connect to %s', self.__class__.__name__, e.message, db) raise DatabaseException
def topologize(self): try: s, n = self.get_topology(6 * ' ') new_line() if n: output_no_newline(s) else: output('There is no topology to show.') except MiniCloudException: error('Failed to topologize.')
def obtain_cidr(): cidr = None while True: cidr = string_input('CIDR') if cidr == 'none': return None elif not Network.check_cidr(cidr): error('This is not a valid (IPv4) CIDR. Please enter again, or give \'none\'') else: break return cidr
def remove_entity(self, entity): try: ctx = self.get_entity_driver_context(entity) if ctx and ctx.authenticated(): self.delete_entity(ctx, entity) else: raise IntegrityException except MiniCloudException as e: error('Failed to delete %s \'%s\'.', self.entity_name(), entity.name) raise e
def add(self): output() output('Please enter the data of the %s you would like to add.', self.entity_name) try: if self.add_entity(): output('%s added.', self.entity_name.title()) else: output('No %s added.', self.entity_name) except IntegrityException: error('You can\'t add this %s as it breaks data integrity.', self.entity_name) except MiniCloudException: error('Adding the %s failed', self.entity_name)
def add(self, entity): name = entity.name if name: if not self.get(name): entity = self.add_entity(entity) self.entity_cache[name] = entity return entity else: error('Name %s already exists.' % name) raise IntegrityException else: error('Can\'t give empty name.') raise IntegrityException
def list(self, deep_list=False): try: print all_e = self.manager.list(deep_list) if not all_e: output('You currently have no %ss provisioned.', self.entity_name) else: output('You currently have %d %s%s provisioned:', len(all_e), self.entity_name, 's' if len(all_e) > 1 else '') for e in all_e: output(e) except MiniCloudException: error('List failed.')
def make_instance_routable(self, instance): fip = self.manager.get_instance_fip(instance) if fip: output('The instance is already routable as %s', fip) return fip network = self.manager.get_instance_network(instance) routers = self.network_manager.get_routers(network) if routers: router = routers[0] else: output('The instance\'s network (\'' + network.name + '\') has no router attached to it.') router = self.make_network_routable(network) if not router: return None external_networks = self.network_manager.external_networks(router) if not external_networks: if not self.network_manager.external_networks(): error('You unfortunately have no external networks') if boolean_input('Do you want to create an external network'): new_name = string_input('Please enter the network name') new_cidr = '169.169.10.0/24' # fixed for now external_network = Network(new_name, new_cidr, True, router, instance.cloud_manager) self.network_manager.add(external_network) else: return None external_network = self.obtain_entity_from_manager( self.network_manager, 'Please enter the name of the external network you want to route from', self.network_manager.external, skip_questioning_if_only_one_entity=True) if external_network: output('Uplinking router.') self.router_manager.uplink(router, external_network) elif len(external_networks) == 1: external_network = external_networks[0] else: output('\nWhich network do you want to make the instance routable to?') network_idx = self.network_manager.obtain_entity_name(filter=self.network_manager.external) external_network = external_networks[network_idx] if external_network and self.check_instance_is_ready(instance): fip = self.manager.make_routable(instance, external_network) return fip
def list_entities(self, name=None, deep_list=False, parent_name=None): try: l = [] for cm in self.cloud_manager.list(): ctx = self.get_cloud_driver_context(cm) if ctx and ctx.authenticated(): for cloud_entity in self.get_entities(ctx, name, deep_list): entity = self.entity(cm, ctx, cloud_entity) if not parent_name or entity.is_child(parent_name): l.append(entity) return l except MiniCloudException as e: error('Failed to list %ss.', self.entity_name()) return list()
def detach_from_router(self, subnet, router): if router is None: error('detach_to_router: there is no router') raise IntegrityException if subnet is None: error('detach_to_router: there is no subnet') raise IntegrityException _('... Detaching from router') self._neutron.remove_router_interface(router['id'], subnet['id']) # invalidate the port cache if router['id'] in self.ports_cache: del self.ports_cache[router['id']] __()
def make_routable(self): output('\nPlease enter the name of the instance you would like to make routable') try: instance = self.obtain_entity(filter_f=self.is_active_and_not_routable) if instance: fip = self.make_instance_routable(instance) if fip: output('%s is publicly routable via %s', instance.name, fip) return output('No instance made routable.') except DoesNotExistException: output('Invalid instance') except MiniCloudException: error('Making instance routable failed.')
def update(self): if not self.update_supported(): output('Not supported, sorry') return # else output() output('Please enter the name of the %s you would like to update.', self.entity_name) try: if self.update_entity(): output('%s updated.', self.entity_name.title()) else: output('No %s updated.', self.entity_name) except DoesNotExistException: output('No %s updated.', self.entity_name) except IntegrityException: error('You can\'t update this %s as it breaks data integrity.', self.entity_name) except MiniCloudException: error('Updating the %s failed.', self.entity_name)
def public_ips(self): try: ext_net = self.obtain_entity( 'which external network do you want to see listed', self.manager.external) if ext_net: output('\nPublic IP\'s:') fips = self.manager.get_floating_ips(ext_net) for fip in fips: fip_ip = fip['floating_ip_address'] fixed_ip = fip['fixed_ip_address'] if fixed_ip: instance = self.instance_manager.get_instance_by_ip(fixed_ip) output('%s\tin use by \'%s\'', fip_ip, instance.name) else: output('%s\tfree', fip_ip) except MiniCloudException: error('Listing public IPs failed.')
def get_entity_driver_context(self, entity): if entity.cloud_manager: return self.get_cloud_driver_context(entity.cloud_manager) elif hasattr(entity, 'cluster_name') and entity.cluster_name: cluster = self.cluster_manager.get(entity.cluster_name) if cluster: entity.cloud_manager = self.cloud_manager.get(cluster.cloud_manager_name) return self.get_cloud_driver_context(entity.cloud_manager) # as fallback, take the single cloud manager if there is only one cloud_manager = self.cloud_manager.get_singleton() if cloud_manager: # good, can proceed entity.cloud_manager = cloud_manager entity.cluster_name = Cluster.UNNAMED_CLUSTER return self.get_cloud_driver_context(cloud_manager) error('No driver context can be selected for %s.', entity.name) raise IntegrityException
def attach(self): try: network = self.obtain_entity( '\nWhich network would you like to attach', self.manager.non_external) if network: router = self.obtain_entity_from_manager( self.router_manager, 'Please enter the name of the router to attach to', skip_questioning_if_only_one_entity=True) if router: if router in self.manager.get_routers(network): error('This network is already attached to router %s.', router.name) else: self.manager.attach_network_to_router(network, router) output('Network attached.') return output('No network attached.') except DoesNotExistException: output('No network attached.') except MiniCloudException: error('Attaching the network failed.')
def remove(self): output() output('Please enter the name of the %s you would like to remove.', self.entity_name) try: if self.remove_entity(): output('%s removed.', self.entity_name.title()) else: output('No %s removed.', self.entity_name) except DoesNotExistException: output('No %s removed.', self.entity_name) except IntegrityException: error('You can\'t remove this %s as it breaks data integrity.', self.entity_name) except InUseException: error('You can\'t remove this %s as it is in use.', self.entity_name) except MiniCloudException: error('Removing the %s failed.', self.entity_name)
def connect_to_instance(self, instance, username, password): fip = self.get_instance_fip(instance) if fip is None: error('Instance %s has no FIP allocated to.' % instance.name) raise IntegrityException try_c = 1 while try_c >= 0: try: ssh_client = SSHClient() ssh_client.set_missing_host_key_policy(AutoAddPolicy()) ssh_client.connect(fip, username=username, password=password) return except Exception as e: if try_c: output('Retrying...') try_c -= 1 else: error('SSH error connecting to instance %s: %s', instance.name, e) error('There may be a Security Group constraint?') raise MiniCloudException
def detach(self, network=None): try: if network is None: network = self.obtain_entity( '\nWhich network would you like to detach', self.manager.non_external) if network: routers = self.manager.get_routers(network) if len(routers) == 1: self.manager.detach_network_from_router(network, routers[0]) output('Network detached.') return elif len(routers) > 1: error('Multiple routers detected which is not implemented yet, sorry.') else: error('Can\'t detach as there is no router attached.') output('No network detached.') except DoesNotExistException: output('No network detached.') except MiniCloudException: error('Detaching the network failed.')
from core.core_in import boolean_error from core.core_out import error, fatal_error from core.core_types import DatabaseException __author__ = 'Kris Sterckx' try: import MySQLdb try: import dataset # http://dataset.readthedocs.org/en/latest/ from sqlalchemy.exc import OperationalError except ImportError as e: error('%s: Can\'t import a critical module.', e.message) error('Please give: pip install dataset') fatal_error() except ImportError as e: error('%s: Can\'t import a critical module.', e.message) error('Please install python-mysqldb (e.g. using sudo apt-get install)\n') error('Meanwhile, continuing with dummy persistency; THIS WILL NOT FUNCTION PROPERLY!') if boolean_error('Are you sure you want to continue experimenting with this software'): print class MySQLdb: def __init__(self): pass class dataset: def __init__(self):
def add_entity(self): name = string_input('Name') cluster_name = self.obtain_entity_name(self.cluster_manager, choose_from_display=True, allow_none=True) flavor = self.obtain_entity_from_manager( self.manager.flavor_manager, 'Which flavor do you want to boot?', choose_from_display=True, return_immediately_if_no_entity=True) if not flavor: error('No flavor found.') return None image = self.obtain_entity_from_manager( self.manager.image_manager, 'Which image do you want to boot?', choose_from_display=True, return_immediately_if_no_entity=True) if not image: error('No image found.') return None output('\nScanning security groups.') nova_sgs = self.manager.nova_sg_manager.list() public_ssh_sg = None for sg in nova_sgs: if sg.name == "public_ssh": public_ssh_sg = sg break if not public_ssh_sg and boolean_input("No public_ssh security group was found. Would you like to create it"): sg = NovaSg('public_ssh', 'sg for ssh access', self.manager.get_cloud_manager(cluster_name)) sg.add_rule(NovaSgRule('tcp', 22, 22, '0.0.0.0/0')) self.manager.nova_sg_manager.add(sg) nova_sg = self.obtain_entity_from_manager( self.manager.nova_sg_manager, 'Which nova security group do you want to boot with?', choose_from_display=True, return_immediately_if_no_entity=True) if not nova_sg: error('No Nova Security Group found.') return None network = self.obtain_entity_from_manager( self.network_manager, 'Which network do you want to boot in?', self.network_manager.non_external, choose_from_display=True, return_immediately_if_no_entity=True) if not network: error('No network found.') return None make_routable = boolean_input('\nDo you want this instance to be routable') output() instance = Instance(name, cluster_name, flavor, image, nova_sg, network) self.manager.add(instance) if make_routable: fip = self.make_instance_routable(instance) if fip: output('Instance is routable as %s.', fip) return instance
from core.core_types import IntegrityException, MiniCloudException __author__ = 'Kris Sterckx' try: from paramiko import SSHClient, AutoAddPolicy except ImportError as import_e: class SSHClient: def __init__(self): pass class AutoAddPolicy: def __init__(self): pass error('Can\'t import a critical module %s.', import_e.message) error('Please give: pip install paramiko') fatal_error() class InstanceManager(CloudResourceManager): def __init__(self, minicloud): super(InstanceManager, self).__init__(minicloud) self.network_manager = self.minicloud.network_manager self.flavor_manager = self.minicloud.flavor_manager self.image_manager = self.minicloud.image_manager self.nova_sg_manager = self.minicloud.nova_sg_manager @staticmethod def entity_name(): return 'instance'