def build_express_config(du): """write config file""" express_config = "{}/{}.conf".format( globals.CONFIG_DIR, "{}".format(du['url'].replace('https://', ''))) sys.stdout.write( "--> Building configuration file: {}\n".format(express_config)) encryption = Encryption(globals.ENCRYPTION_KEY_FILE) try: express_config_fh = open(express_config, "w") express_config_fh.write("manage_hostname|false\n") express_config_fh.write("manage_resolver|false\n") express_config_fh.write("dns_resolver1|8.8.8.8\n") express_config_fh.write("dns_resolver2|8.8.4.4\n") express_config_fh.write("os_tenant|{}\n".format(du['tenant'])) express_config_fh.write("du_url|{}\n".format(du['url'])) express_config_fh.write("os_username|{}\n".format(du['username'])) express_config_fh.write("os_password|{}\n".format( encryption.decrypt_password(du['password']))) express_config_fh.write("os_region|{}\n".format(du['region'])) express_config_fh.write("proxy_url|-\n".format(du['region_proxy'])) express_config_fh.close() except: sys.stdout.write( "ERROR: failed to build configuration file: {}\n{}\n".format( express_config, sys.exc_info())) return (None) # validate config was written if not os.path.isfile(express_config): return (None) return (express_config)
def get_config(): config_values = { } # get Packet credentials sys.stdout.write("\nPlease enter credentials for Packet.Net:\n") project_id = user_io.read_kbd("--> Project ID", [], '', True, True) if project_id == "q": return '' api_key = user_io.read_kbd("--> API Key", [], '', False, True) if api_key == "q": return '' # get Platform9 credentials sys.stdout.write("\nPlease enter credentials for Platform9.Com:\n") pf9_region_url = user_io.read_kbd("--> PMK Region URL", [], '', True, True) if pf9_region_url == "q": return '' pf9_username = user_io.read_kbd("--> Username", [], '', True, True) if pf9_username == "q": return '' pf9_password = user_io.read_kbd("--> Password", [], '', False, True) if pf9_password == "q": return '' pf9_tenant = user_io.read_kbd("--> Tenant", [], 'service', True, True) if pf9_tenant == "q": return '' pf9_region = user_io.read_kbd("--> Region Name", [], 'RegionOne', True, True) if pf9_region == "q": return '' pf9_express_cli_branch = user_io.read_kbd("--> Express-CLI Branch", [], 'tomchris/restructure', True, True) if pf9_express_cli_branch == "q": return '' # initialize encryption encryption = Encryption(globals.ENCRYPTION_KEY_FILE) # update config (encrypt api_key) config_values['pkt_project_id'] = project_id config_values['pkt_api_key'] = encryption.encrypt_string(api_key) config_values['pf9_region_url'] = pf9_region_url config_values['pf9_username'] = pf9_username config_values['pf9_password'] = encryption.encrypt_string(pf9_password) config_values['pf9_tenant'] = pf9_tenant config_values['pf9_region'] = pf9_region config_values['pf9_express_cli_branch'] = pf9_express_cli_branch sys.stdout.write("\n") return(config_values)
def test_encryption(self): """Test wizard encryption class""" self.log = logging.getLogger(inspect.currentframe().f_code.co_name) print(self.log) # make sure keyfile does not exist tmpfile = "/tmp/keyfile.tmp" if os.path.isfile(tmpfile): try: os.remove(tmpfile) except: self.assertTrue(False) encryption = Encryption(tmpfile) original_string = "This is a test string" encrypted_string = encryption.encrypt_password(original_string) unencrypted_string = encryption.decrypt_password(encrypted_string) self.assertTrue(unencrypted_string == original_string)
def discover_region_clusters(discover_target): num_clusters_discovered = 0 num_clusters_created = 0 if discover_target['du_type'] in ['Kubernetes', 'KVM/Kubernetes']: sys.stdout.write("--> Discovering clusters for {} region: {}\n".format( discover_target['du_type'], discover_target['url'])) encryption = Encryption(globals.ENCRYPTION_KEY_FILE) project_id, token = du_utils.login_du(discover_target['url'], discover_target['username'], discover_target['password'], discover_target['tenant']) if project_id: # discover existing clusters discovered_clusters = pmk_utils.discover_du_clusters( discover_target['url'], discover_target['du_type'], project_id, token) # get existing/user-defined clusters for region defined_clusters = datamodel.get_clusters(discover_target['url']) # create any missing clusters for cluster in defined_clusters: cluster_flag = datamodel.cluster_in_array( cluster['du_url'], cluster['name'], discovered_clusters) if not datamodel.cluster_in_array(cluster['du_url'], cluster['name'], discovered_clusters): pmk_utils.create_cluster(discover_target['url'], project_id, token, cluster) num_clusters_created += 1 num_clusters_discovered += 1 if num_clusters_created > 0: discovered_clusters = pmk_utils.discover_du_clusters( discover_target['url'], discover_target['du_type'], project_id, token) for cluster in discovered_clusters: datamodel.write_cluster(cluster) return (num_clusters_created, num_clusters_discovered)
def main(): args = _parse_args() # validate installation directory init_install_dir() # initialize encryption/decryption key (keyfile) if args.key: init_keyfile(args.key[0]) sys.exit(0) # initialize encryption encryption = Encryption(globals.ENCRYPTION_KEY_FILE) # encryption functions if args.encrypt: sys.stdout.write("Encrypted string: {}\n".format( encryption.encrypt_string(args.encrypt[0]))) sys.exit(0) elif args.unencrypt: sys.stdout.write("Decrypted string: {}\n".format( encryption.decrypt_string(args.unencrypt[0]))) sys.exit(0) # display banner (if no commandline arguments passed) if not len(sys.argv) > 1: motd() # prompt user for Packet & Platform9 credentials (if config_file is missing) if not os.path.isfile(globals.CONFIG_FILE): config_values = interview.get_config() if config_values: write_config(config_values) # read config file app_config = read_config() # update ctx globals.ctx['packet']['project_id'] = app_config.get( 'packet.net', 'project_id') globals.ctx['packet']['token'] = encryption.decrypt_string( app_config.get('packet.net', 'token')) globals.ctx['platform9']['region_url'] = app_config.get( 'platform9.net', 'region_url') globals.ctx['platform9']['username'] = app_config.get( 'platform9.net', 'username') globals.ctx['platform9']['password'] = encryption.decrypt_string( app_config.get('platform9.net', 'password')) globals.ctx['platform9']['tenant'] = app_config.get( 'platform9.net', 'tenant') globals.ctx['platform9']['region'] = app_config.get( 'platform9.net', 'region') globals.ctx['platform9']['express_cli_branch'] = app_config.get( 'platform9.net', 'express_cli_branch') # validate encryption if not globals.ctx['packet']['token']: fail("failed to decrypt API key") # init packet cloud packet_cloud = PacketCloud(globals.ctx['packet']['token'], globals.ctx['packet']['project_id']) # validate credentials valid_creds = packet_cloud.validate_creds() if not valid_creds: try: os.remove(globals.CONFIG_FILE) except: sys.stdout.write( "ERROR: failed to remove config file with invalid credentials: {}\n" .format(globals.CONFIG_FILE)) fail("failed to login into Packet.net with the supplied credentials\n") # manage debug parameters if args.debug and args.debug[0] == "skip_launch": globals.flag_skip_launch = True if args.debug and args.debug[0] == "stop_after_launch": globals.flag_stop_after_launch = True # run function (based on commandline args) if args.apply: packet_cloud.run_action(args.apply[0]) elif args.delete: if not packet_cloud.delete_instance(args.delete[0]): fail("failed to delete instance") sys.stdout.write("instance deleted\n") elif args.dump: packet_cloud.dump_device_record(args.dump[0]) elif args.show and args.show[0] == "plan": packet_cloud.show_plans() elif args.show and args.show[0] == "os": packet_cloud.show_operating_systems() elif args.show and args.show[0] == "facility": packet_cloud.show_facilities() elif args.show and args.show[0] == "server": packet_cloud.show_devices() # exit cleanly sys.exit(0)
def run_action(self, spec_file): if not os.path.isfile(spec_file): sys.stdout.write( "ERROR: failed to open spec file: {}".format(spec_file)) return (None) with open(spec_file) as json_file: spec_actions = json.load(json_file) required_keys = ['actions'] for key_name in required_keys: if not key_name in spec_actions: sys.stdout.write( "ERROR: missing required key in spec file: {}".format( key_name)) return (None) # initialize flags flag_launched = False flag_assimilated = False # loop over actions (run sequentially/synchronously) instance_uuids = [] assimilated_servers = {} for action in spec_actions['actions']: if 'operation' not in action: sys.stdout.write( "ERROR: invalid json syntax, missing: operation\n") continue # invoke action-specific functions if action['operation'] == "imported-instances": flag_assimilated = True assimilated_servers = action['instances'] print("assimilated_servers = {}".format(assimilated_servers)) sys.stdout.write("\n[Validating Assimilated Instances]\n") if action['operation'] == "launch-instance": flag_launched = True required_keys = [ 'num_instances', 'hostname_base', 'plan', 'facility', 'operating_system', 'userdata', 'customdata', 'ip_addresses' ] for key_name in required_keys: if not key_name in action: sys.stdout.write( "ERROR: missing required key in spec file: {}". format(key_name)) return (None) instance_uuids = self.launch_batch_instances(action) if instance_uuids: sys.stdout.write("\n[Waiting for All Instances to Boot]\n") all_instances_booted, boot_time = self.wait_for_instances( instance_uuids) if all_instances_booted: sys.stdout.write( "--> all instances booted successfully, boot time = {} seconds\n\n" .format(boot_time)) self.show_devices(instance_uuids) else: sys.stdout.write("--> TIMEOUT exceeded\n") sys.exit(0) # manage network_type if not globals.flag_skip_launch: if 'network_mode' in action and action[ 'network_mode'] == "hybrid": sys.stdout.write( "\n[Setting {} Network Mode - All Instances]\n" .format(action['network_mode'])) if not self.set_batch_hybrid_mode(instance_uuids): sys.stdout.write( "ERROR: failed to set one or more nodes to hybrid mode\n" ) sys.exit(0) # vlan assignment if 'k8s_vlan_tag' in action and action[ 'k8s_vlan_tag'] != "": sys.stdout.write( "\n[Configuring Layer-2 Networking - All Instances]\n" ) self.assign_batch_vlan(instance_uuids, action['k8s_vlan_tag']) # early exit (if global flag is set) if globals.flag_stop_after_launch: sys.stdout.write( "\nEarly Exit (globals.flag_stop_after_launch = {})\n" .format(globals.flag_stop_after_launch)) sys.exit(0) elif action['operation'] == "pf9-build-cluster": required_keys = [ 'cluster', 'ssh_username', 'ssh_key', 'masters', 'workers' ] for key_name in required_keys: if not key_name in action: sys.stdout.write( "ERROR: missing required key in spec file: {}". format(key_name)) return (None) if action[key_name] == "": sys.stdout.write( "ERROR: required key cannot be null: {}".format( key_name)) return (None) # initialize encryption encryption = Encryption(globals.ENCRYPTION_KEY_FILE) # initialize/login in Platform9 PMK sys.stdout.write("\n[Initializing PMK Integration]\n") from pf9_pmk import PMK pf9 = PMK(globals.ctx['platform9']['region_url'], globals.ctx['platform9']['username'], globals.ctx['platform9']['password'], globals.ctx['platform9']['tenant']) # validate login to Platform9 if not pf9.validate_login(): sys.stdout.write( "ERROR: failed to login to PMK region: {} (user={}/tenant={})\n" .format(globals.ctx['platform9']['region_url'], globals.ctx['platform9']['username'], globals.ctx['platform9']['tenant'])) return (None) else: sys.stdout.write( "--> logged into PMK region: {} (user={}/tenant={})\n". format(globals.ctx['platform9']['region_url'], globals.ctx['platform9']['username'], globals.ctx['platform9']['tenant'])) # build node list node_list = [] for node in action['masters']: if flag_launched: tmp_public_ip = self.get_public_ip(node['hostname']) elif flag_assimilated: tmp_public_ip = assimilated_servers[node['hostname']] else: sys.stdout.write( "WARNING: invalid condition: either flag_launched or flag_assimilated must be set\n" ) continue node_entry = { "hostname": node['hostname'], "node_ip": node['node_ip'], "node_ip_mask": node['node_ip_mask'], "node_ip_interface": node['interface'], "public_ip": tmp_public_ip, "node_type": "master" } node_list.append(node_entry) for node in action['workers']: if flag_launched: tmp_public_ip = self.get_public_ip(node['hostname']) elif flag_assimilated: tmp_public_ip = assimilated_servers[node['hostname']] else: sys.stdout.write( "WARNING: invalid condition: either flag_launched or flag_assimilated must be set\n" ) continue node_entry = { "hostname": node['hostname'], "node_ip": node['node_ip'], "node_ip_mask": node['node_ip_mask'], "node_ip_interface": node['interface'], "public_ip": tmp_public_ip, "node_type": "worker" } node_list.append(node_entry) table_title = "\n-------------- Kubernetes Cluster Configuration --------------" table_columns = [ "Name", "Master VIP", "VIP Interface", "Services CIDR", "Containers CIDR", "MetalLB Range" ] table_rows = [[ action['cluster']['name'], action['cluster']['master_vip_ipv4'], action['cluster']['master_vip_iface'], action['cluster']['services_cidr'], action['cluster']['containers_cidr'], action['cluster']['metallb_cidr'] ]] reports.display_table(table_title, table_columns, table_rows) table_title = "\n-------------- Kubernetes Cluster Nodes --------------" table_columns = [ "Hostname", "Node Type", "Node IP", "Public IP" ] table_rows = [] for node in node_list: node_entry = [ node['hostname'], node['node_type'], node['node_ip'], node['public_ip'] ] table_rows.append(node_entry) reports.display_table(table_title, table_columns, table_rows) # assign ip address (node_ip) to Ethernet interface if not globals.flag_skip_launch and flag_launched: sys.stdout.write( "\n[Setting IP Address for K8s Backend - All Instances]\n" ) self.set_batch_ip_address(instance_uuids, node_list, action['ssh_username'], action['ssh_key']) # build Kubernetes cluster on PMK pf9.onboard_cluster(globals.ctx['platform9']['region_url'], globals.ctx['platform9']['username'], globals.ctx['platform9']['password'], globals.ctx['platform9']['tenant'], globals.ctx['platform9']['region'], action['cluster'], node_list, action['ssh_username'], action['ssh_key'])