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 check_instance_is_ready(self, instance): active = self.manager.check_status(instance, 'BUILD', negative_check=True) if not active: output('Waiting for instance to be active...') while not active: time.sleep(1) active = self.manager.check_status(instance, 'BUILD', negative_check=True) return True
def drop_all(self): if boolean_input('Are you ABSOLUTELY sure you want to do this', default=False): if boolean_input('Once again, ABSOLUTELY sure', default=False): self.manager.drop(boolean_input('Do you want to clean up the deployed data also (Y)' ' or is pure db clear sufficient (n)')) output('All data is cleared.') return # else output('Aborted.')
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 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 __init__(self, start=False): output('Welcome to MiniCloud!\n') super(MiniCloudMgnt, self).__init__(self.setup_minicloud()) self.cloud_mgnt = CloudMgnt(self) self.cluster_mgnt = ClusterMgnt(self) self.instance_mgnt = InstanceMgnt(self) self.network_mgnt = NetworkMgnt(self) self.router_mgnt = RouterMgnt(self) self.first_topology = True if start: self.manage_entities()
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 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 make_network_routable(self, network): router = None if self.router_manager.list() and boolean_input('Do you want to attach to existing router'): 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) elif boolean_input('Do you want to create a router'): name = string_input('Name') output('Creating router.') router = Router(name, cloud_manager=network.cloud_manager) self.router_manager.add(router) if router: output('Attaching network.') self.network_manager.attach_network_to_router(network, router) return router
def obtain_entity_name(self, manager=None, input_string=None, filter_f=None, choose_from_display=False, allow_none=False, skip_questioning_if_only_one_entity=False, return_immediately_if_no_entity=False): name = None if not manager: manager = self.manager if not input_string: input_string = manager.entity_title() + ' name' if choose_from_display: output() # skip line first, is nicer names = manager.list_entity_names(filter_f) if names and choose_from_display: name_idx = choice_input_list(input_string, names, add_none=allow_none, zero_based_return=True, skip_line=False) if name_idx == len(names): return None else: return names[name_idx] else: if not names: if return_immediately_if_no_entity: return None else: def_name = 'none' elif len(names) == 1: if skip_questioning_if_only_one_entity: return names[0] else: def_name = names[0] else: def_name = 'show' while True: name = string_input(input_string, default=def_name) if name == 'show': if len(name) > 0: for n in names: print n output('or give \'none\' to return.') else: output('Nothing to show.') elif name == 'none': return None else: if name in names: break else: output('%s is not a valid %s, pls re-enter or give \'none\'.', (name, manager.entity_name())) return name
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 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 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 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 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 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.')
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 print_header(): output('\n== MINICLOUD v1.0 ==\n\n')
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 end_program(): output('Thanks for using MiniCloud.\n' 'Enjoy your day.')
def setup_minicloud(): database = None try: output('Setting up MiniCloud ...') database = MiniCloudMgnt.obtain_db_credentials('MINICLOUD_DB_HOST', 'MINICLOUD_DB_USERNAME', 'MINICLOUD_DB_PASSWORD', 'MINICLOUD_DB_NAME') mc = MiniCloud(database) print if mc.system.get_setting('first_use') is None: mc.system.set_setting('first_use', datetime.datetime.now().strftime('%d-%m-%Y')) output('This is the first use of MiniCloud!') else: output('The first use of MiniCloud was %s!', mc.system.get_setting('first_use')) return mc except DatabaseException as e: output(e) output('Please make sure you have a MySql server running,\n' 'the MiniCloud database is present and users are provisioned.\n\n' 'Install mysql-server\n\n' 'give: mysql -u root -p\n' '<password>\n\n' 'mysql> CREATE DATABASE %s;', database.database) if database.username != 'root': output('mysql> CREATE USER \'%s\'@\'%s\' IDENTIFIED BY \'%s\';', database.username, database.host, database.password) output('mysql> GRANT ALL PRIVILEGES ON %s.* to %s@%s;', database.database, database.username, database.host) output('mysql> FLUSH PRIVILEGES;') output('mysql> exit;') fatal_error()
def check_active(self, instance): if not self.is_active(instance): output('%s is in %s state, cannot proceed.', instance.name, instance.status) return False else: return True
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 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
def reset(self): output('Reset\'ing.') self.manager.reset() self.first_topology = True output('Done.')