Пример #1
0
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)
Пример #2
0
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)
Пример #3
0
    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)
Пример #4
0
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)
Пример #5
0
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)
Пример #6
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'])