Exemplo n.º 1
0
def get_yaml_all(filename):
    with open(filename,'r') as input_file:
        return list(yaml.safe_load_all(input_file))
def main():

    global cpx_count
    global output_yaml

    parser = argparse.ArgumentParser(
        description=
        'Taking service yamls or name as input. And namespace in case service names is provided'
    )
    parser.add_argument(
        'ServiceList',
        action="store",
        help=
        'Please provide comma seperated list of service yamls or names to convert into SML'
    )
    parser.add_argument(
        'Namespace',
        action="store",
        nargs='?',
        help='Please provide namespace in which services are deployed')
    svcs = parser.parse_args().ServiceList.split(',')
    namespace = parser.parse_args().Namespace

    converted_yamls_dict_list = []

    if (".yaml" not in svcs[0]):
        '''
        Code for connecting to Kubenetes Cluster
        '''
        if not namespace:
            logger.error(
                "Please provide namespace as well in which services are deployed while starting the script"
            )
            sys.exit(0)
        prompts = chain(
            ["Do you want to connect to a Remote Kubernetes Cluster? (Y/N): "],
            repeat("Invaild input. Please respond with (Y/N): "))
        remote_access = validate_input(prompts, "yesORno")
        if remote_access.lower() == 'n':
            prompts = chain([
                'Do you want to use default kubeconfig file present at "/root/.kube/config"? (Y/N): '
            ], repeat("Invaild input. Please respond with (Y/N): "))
            default_kube_config = validate_input(prompts, "yesORno")
            if default_kube_config.lower() == "y":
                kube_config_path = "/root/.kube/config"
            else:
                prompts = chain(
                    ["Please provide path of kubeconfig file: "],
                    repeat(
                        "This path doesn't exist! Please provide a valid kubeconfig file path: "
                    ))
                kube_config_path = validate_input(prompts, "path")
            config.load_kube_config(config_file=kube_config_path)
            v1 = client.CoreV1Api()
        elif remote_access.lower() == 'y':
            prompts = chain([
                "Do you want to use Bearer Token for connecting to a Remote Kubernetes Cluster? (Y/N): "
            ], repeat("Invaild input. Please respond with (Y/N): "))
            use_bearer_token = validate_input(prompts, "yesORno")
            if use_bearer_token.lower() == "y":
                configuration = client.Configuration()
                bearer_token = input(
                    "Please provide bearer token key of SA having permission to access given service: "
                )
                configuration.api_key = {
                    "authorization": "Bearer " + bearer_token
                }
                prompts = chain(
                    ["Please provide API server <IP:PORT>: "],
                    repeat(
                        "Invaild input. Please provide valid IP and port in format <IP:PORT>: "
                    ))
                api_server = validate_input(prompts, "apiServerIPPort")
                configuration.host = 'https://' + api_server
                configuration.verify_ssl = False
                v1 = client.CoreV1Api(client.ApiClient(configuration))
            elif use_bearer_token.lower() == "n":
                prompts = chain(
                    ["Please provide path of kubeconfig file: "],
                    repeat(
                        "This path doesn't exist! Please provide a valid kubeconfig file path: "
                    ))
                kube_config_path = validate_input(prompts, "path")
                config.load_kube_config(config_file=kube_config_path)
                v1 = client.CoreV1Api()

    app_frontend_svc_name = input(
        "Please provide name of the service exposed to tier-1: ")
    app_hostname = input("Please provide hostname for exposing \"" +
                         app_frontend_svc_name + "\" service: ")

    if not namespace:
        namespace = "default"
    '''
    Coverting YAMLs to SML YAMLs
    '''
    for svc in svcs:
        if (".yaml" in svc):
            '''
            When applcation YAMLs is provided as input.
            '''
            with open(svc, 'r') as stream:
                try:
                    yaml_dictionaries = yaml.safe_load_all(stream)
                    for yaml_instance in yaml_dictionaries:
                        if yaml_instance:
                            converted_yamls_dict_list.extend(
                                convert_yaml_to_sml(yaml_instance,
                                                    app_frontend_svc_name,
                                                    app_hostname))
                except Exception as e:
                    logger.error(
                        "Retrieving yaml from service yamls provided failed with error: {}"
                        .format(e))
                    sys.exit("Please ensure service yaml is in proper format")
        else:
            '''
            When service name running in Kubernetes cluster is provided as input.
            '''
            try:
                service = v1.read_namespaced_service(svc, namespace)
            except Exception as e:
                logger.error(
                    "Retrieving service from KubeAPI server failed with error: {}"
                    .format(e))
                sys.exit("Please ensure service name and namespace is correct")
            service = service.__dict__
            service = convert_kube_object_to_dict(service)
            #           service = OrderedDict([('apiVersion',service['apiVersion']),
            #                            ('kind',service['kind']),
            #                            ('metadata',service['metadata']),
            #                            ('spec',service['spec']),
            converted_yamls_dict_list.extend(
                convert_yaml_to_sml(service, app_frontend_svc_name,
                                    app_hostname))
    '''
    Checking if required HELM is there or not.
    '''
    helm_ver = subprocess.run(["helm version"],
                              shell=True,
                              capture_output=True).stdout.decode('utf-8')
    matchObj = re.search(r'Version:"v3.*', helm_ver, re.M | re.I)
    if not matchObj:
        logger.error("Couldn't find Helm with version 3.x and above.")
        sys.exit(
            "Please install Helm 3.x and put it in the PATH. This https://github.com/citrix/citrix-helm-charts/blob/master/Helm_Installation_version_3.md can be followed for the same."
        )

    subprocess.run(
        ["helm repo add citrix https://citrix.github.io/citrix-helm-charts/"],
        shell=True,
        capture_output=True)
    '''
    Getting ADM details
    '''
    prompts = chain(['Citrix ADM required? (Y/N): '],
                    repeat("Invaild input. Please respond with (Y/N): "))
    adm_required = validate_input(prompts, "yesORno")
    if adm_required.lower() == "y":
        prompts = chain([
            'Please provide IP of ADM Agent(svcIP of container agent) for Citrix ADC CPX: '
        ], repeat("Invaild IP. Please enter and IPv4 IP: "))
        cpx_adm_agent_ip = validate_input(prompts, "ip")
        adm_secret = input(
            "Please provide name of K8s Secret created using ADM Agent credentials. Press ENTER for 'admlogin': "******"admlogin"
    '''
    Adding CPX yamls
    '''
    for i in range(1, cpx_count + 1):
        if adm_required.lower() == "y":
            output = subprocess.run([
                "helm template " + chart_name + str(i) +
                " citrix/citrix-cloud-native --set cpx.enabled=true,cpx.license.accept=yes,cpx.ingressClass[0]="
                + cpx_ingress_class + str(i) +
                ",cpx.coeConfig.required=true,cpx.coeConfig.timeseries.metrics.enable=true,cpx.coeConfig.distributedTracing.enable=true,cpx.coeConfig.endpoint.server="
                + cpx_adm_agent_ip + ",cpx.ADMSettings.ADMIP=" +
                cpx_adm_agent_ip + ",cpx.ADMSettings.loginSecret=" +
                adm_secret + " -n " + namespace + " > temp.yaml"
            ],
                                    shell=True,
                                    capture_output=True)
            #            output = subprocess.run(["helm template "+ chart_name + str(i) + " citrix/citrix-cloud-native --set cpx.enabled=true,cpx.license.accept=yes,cpx.ingressClass[0]="+cpx_ingress_class+str(i)+",cpx.coeConfig.required=true,cpx.coeConfig.timeseries.metrics.enable=true,cpx.coeConfig.distributedTracing.enable=true,cpx.coeConfig.endpoint.server="+ cpx_adm_agent_ip +",cpx.ADMSettings.ADMIP=" + cpx_adm_agent_ip +",cpx.ADMSettings.loginSecret=" + adm_secret + " -n "+namespace+" > temp.yaml"],shell=True,capture_output=True)
            if output.stderr:
                logger.error("Helm chart command failed with error {}".format(
                    output.stderr))
                sys.exit("Please ensure you have provided proper inputs.")
        else:
            output = subprocess.run([
                "helm template " + chart_name + str(i) +
                " citrix/citrix-cloud-native --set cpx.enabled=true,cpx.license.accept=yes,cpx.ingressClass[0]="
                + cpx_ingress_class + str(i) + " -n " + namespace +
                " > temp.yaml"
            ],
                                    shell=True,
                                    capture_output=True)
            if output.stderr:
                logger.error("Helm chart command failed with error {}".format(
                    output.stderr))
                sys.exit("Please ensure you have provided proper inputs.")

        with open('temp.yaml', 'r') as stream:
            yaml_dictionaries = list(yaml.safe_load_all(stream))
        if i > 1:
            list_to_remove = []
            for yaml_instance in yaml_dictionaries:
                if yaml_instance['kind'] == "ServiceAccount" or yaml_instance[
                        'kind'] == "ClusterRole" or yaml_instance[
                            'kind'] == "ClusterRoleBinding":
                    list_to_remove.append(yaml_instance)
                elif yaml_instance['kind'] == "Deployment":
                    yaml_instance['spec']['template']['spec'][
                        'serviceAccountName'] = re.sub(
                            "sml" + str(i), "sml1", yaml_instance['spec']
                            ['template']['spec']['serviceAccountName'])
                elif yaml_instance['kind'] == "Service":
                    yaml_instance['metadata']['labels']['citrix-adc'] = 'cpx'
            yaml_dictionaries = [
                x for x in yaml_dictionaries if x not in list_to_remove
            ]
            converted_yamls_dict_list.extend(yaml_dictionaries)
        else:
            for yaml_instance in yaml_dictionaries:
                if yaml_instance['kind'] == "Service":
                    yaml_instance['metadata']['labels']['citrix-adc'] = 'cpx'
            converted_yamls_dict_list.extend(yaml_dictionaries)


#    rbac = manifestCreator.rbac()
#    rbac = rbac.createRbac()
#    converted_yamls_dict_list.extend(rbac)
#        cpx_cic_yaml = manifestCreator.cpxCic({"name":chart_name+str(i),"ingressClass":cpx_ingress_class+str(i)})
#        cpx_cic_yaml = cpx_cic_yaml.create()
#        converted_yamls_dict_list.extend(cpx_cic_yaml)
    '''
    Getting details for Tier-1 ADC
    '''
    prompts = chain(
        ['Citrix Ingress Controller for tier-1 ADC required? (Y/N): '],
        repeat("Invaild input. Please respond with (Y/N): "))
    create_cic = validate_input(prompts, "yesORno")
    if create_cic.lower() == "y":
        prompts = chain(['Please provide tier-1 ADC NSIP: '],
                        repeat("Invaild IP. Please enter and IPv4 IP: "))
        ns_ip = validate_input(prompts, "ip")
        prompts = chain(['Please provide tier-1 ADC VIP: '],
                        repeat("Invaild IP. Please enter and IPv4 IP: "))
        ns_vip = validate_input(prompts, "ip")
        ns_secret = input(
            "Please provide name of K8s Secret created using ADC credentials. Press ENTER for 'nslogin': "******"nslogin"
        if adm_required.lower() == "y":
            prompts = chain([
                'Please provide IP of ADM Agent(podIP of container agent) for Citrix ADC VPX/MPX: '
            ], repeat("Invaild IP. Please enter and IPv4 IP: "))
            vpx_adm_agent_ip = validate_input(prompts, "ip")

        app_frontend_svc_port = input(
            "Please provide port used to expose CPX service to Tier-1 ADC: ")
        prompts = chain(
            [
                "Please provide protocol used to expose CPX service to Tier-1 ADC (tcp/udp/http/https/grpc): "
            ],
            repeat(
                "Invaild protocol. Please choose a protocol from (tcp/udp/http/https/grpc): "
            ))
        app_frontend_svc_protocol = validate_input(prompts, "protocol")

        if app_frontend_svc_protocol == "grpc":
            app_frontend_svc_protocol = "tcp"

        if app_frontend_svc_protocol == "https":
            tls = input("Please give secret-name for TLS certificate for \"" +
                        app_frontend_svc_name + "\" svc: ")
        else:
            tls = ""

        if adm_required.lower() == "y":
            output = subprocess.run([
                "helm template " + chart_name +
                " citrix/citrix-cloud-native --set cic.enabled=true,cic.nsIP="
                + ns_ip + ",cic.nsVIP=" + ns_vip +
                ",cic.license.accept=yes,cic.adcCredentialSecret=" +
                ns_secret + ",cic.ingressClass[0]=" + vpx_ingress_class +
                ",cic.coeConfig.required=true,cic.coeConfig.timeseries.metrics.enable=true,cic.coeConfig.timeseries.port=5563,cic.coeConfig.distributedTracing.enable=true,cic.coeConfig.transactions.enable=true,cic.coeConfig.transactions.port=5557,cic.coeConfig.endpoint.server="
                + vpx_adm_agent_ip + " -n " + namespace + " > temp.yaml"
            ],
                                    shell=True,
                                    capture_output=True)
            if output.stderr:
                logger.error("Helm chart command failed with error {}".format(
                    output.stderr))
                sys.exit("Please ensure you have provided proper inputs.")

            ingress_yaml = manifestCreator.ingress({
                "name":
                tier1_ingress_name,
                "protocol":
                app_frontend_svc_protocol.lower(),
                "ingressClass":
                vpx_ingress_class,
                "tls":
                tls,
                "admRequired":
                True,
                "serviceDetails": {
                    app_hostname: [{
                        "serviceName":
                        "sml" + str(frontend_cpx_count) + "-cpx-service",
                        "servicePort":
                        app_frontend_svc_port
                    }]
                }
            })
        else:
            output = subprocess.run([
                "helm template " + chart_name +
                " citrix/citrix-cloud-native --set cic.enabled=true,cic.nsIP="
                + ns_ip + ",cic.nsVIP=" + ns_vip +
                ",cic.license.accept=yes,cic.adcCredentialSecret=" +
                ns_secret + ",cic.ingressClass[0]=" + vpx_ingress_class +
                " -n " + namespace + " > temp.yaml"
            ],
                                    shell=True,
                                    capture_output=True)
            if output.stderr:
                logger.error("Helm chart command failed with error {}".format(
                    output.stderr))
                sys.exit("Please ensure you have provided proper inputs.")

            ingress_yaml = manifestCreator.ingress({
                "name":
                tier1_ingress_name,
                "protocol":
                app_frontend_svc_protocol.lower(),
                "ingressClass":
                vpx_ingress_class,
                "tls":
                tls,
                "serviceDetails": {
                    app_hostname: [{
                        "serviceName":
                        "sml" + str(frontend_cpx_count) + "-cpx-service",
                        "servicePort":
                        app_frontend_svc_port
                    }]
                }
            })
        with open('temp.yaml', 'r') as stream:
            yaml_dictionaries = list(yaml.safe_load_all(stream))
        converted_yamls_dict_list.extend(yaml_dictionaries)

        ingress_yaml = ingress_yaml.create()
        converted_yamls_dict_list.append(ingress_yaml)
    '''
    Deleting temp.yaml which got created via Helm
    '''
    my_file = Path("temp.yaml")
    if my_file.is_file():
        os.remove("temp.yaml")
    '''
    Writing dictionay of YAML into a .yaml file
    '''
    write_dictionaries_into_yaml(converted_yamls_dict_list, output_yaml)
Exemplo n.º 3
0
def test_load_all():
    gen = yaml.safe_load_all("{x: 1, z: 3, y: 2}\n--- {}\n")
    assert isinstance(gen, GeneratorType)
    ordered_data, empty_dict = gen
    assert empty_dict == {}
    assert ordered_data == data
Exemplo n.º 4
0
def main():

    global cpx_count
    global output_yaml

    parser = argparse.ArgumentParser(
        description=
        'Taking service yamls or name as input. And namespace in case service names is provided'
    )
    parser.add_argument(
        'ServiceList',
        action="store",
        help=
        'Please provide comma seperated list of service yamls or names to convert into SML'
    )
    parser.add_argument(
        'Namespace',
        action="store",
        nargs='?',
        help='Please provide namespace in which services are deployed')
    svcs = parser.parse_args().ServiceList.split(',')
    namespace = parser.parse_args().Namespace

    converted_yamls_dict_list = []

    if (".yaml" not in svcs[0]):
        if not namespace:
            logger.error(
                "Please provide namespace as well in which services are deployed while starting the script"
            )
            sys.exit(0)
        prompts = chain(
            ["Do you want to connect to a Remote Kubernetes Cluster? (Y/N): "],
            repeat("Invaild input. Please respond with (Y/N): "))
        remote_access = validate_input(prompts, "yesORno")
        if remote_access.lower() == 'n':
            prompts = chain([
                'Do you want to use default kubeconfig file present at "/root/.kube/config"? (Y/N): '
            ], repeat("Invaild input. Please respond with (Y/N): "))
            default_kube_config = validate_input(prompts, "yesORno")
            if default_kube_config.lower() == "y":
                kube_config_path = "/root/.kube/config"
            else:
                prompts = chain(
                    ["Please provide path of kubeconfig file: "],
                    repeat(
                        "This path doesn't exist! Please provide a valid kubeconfig file path: "
                    ))
                kube_config_path = validate_input(prompts, "path")
            config.load_kube_config(config_file=kube_config_path)
            v1 = client.CoreV1Api()
        elif remote_access.lower() == 'y':
            prompts = chain([
                "Do you want to use Bearer Token for connecting to a Remote Kubernetes Cluster? (Y/N): "
            ], repeat("Invaild input. Please respond with (Y/N): "))
            use_bearer_token = validate_input(prompts, "yesORno")
            if use_bearer_token.lower() == "y":
                configuration = client.Configuration()
                bearer_token = input(
                    "Please provide bearer token key of SA having permission to access given service: "
                )
                configuration.api_key = {
                    "authorization": "Bearer " + bearer_token
                }
                prompts = chain(
                    ["Please provide API server <IP:PORT>: "],
                    repeat(
                        "Invaild input. Please provide valid IP and port in format <IP:PORT>: "
                    ))
                api_server = validate_input(prompts, "apiServerIPPort")
                configuration.host = 'https://' + api_server
                configuration.verify_ssl = False
                v1 = client.CoreV1Api(client.ApiClient(configuration))
            elif use_bearer_token.lower() == "n":
                prompts = chain(
                    ["Please provide path of kubeconfig file: "],
                    repeat(
                        "This path doesn't exist! Please provide a valid kubeconfig file path: "
                    ))
                kube_config_path = validate_input(prompts, "path")
                config.load_kube_config(config_file=kube_config_path)
                v1 = client.CoreV1Api()

    app_frontend_svc_name = input(
        "Please provide name of the service exposed to tier-1: ")
    app_hostname = input("Please provide hostname for exposing \"" +
                         app_frontend_svc_name + "\" service: ")

    for svc in svcs:
        if (".yaml" in svc):
            with open(svc, 'r') as stream:
                try:
                    yaml_dictionaries = yaml.safe_load_all(stream)
                    for yaml_instance in yaml_dictionaries:
                        if yaml_instance:
                            converted_yamls_dict_list.extend(
                                convert_yaml_to_sml(yaml_instance,
                                                    app_frontend_svc_name,
                                                    app_hostname))
                except Exception as e:
                    logger.error(
                        "Retrieving yaml from service yamls provided failed with error: {}"
                        .format(e))
                    sys.exit("Please ensure service yaml is in proper format")
        else:
            try:
                service = v1.read_namespaced_service(svc, namespace)
            except Exception as e:
                logger.error(
                    "Retrieving service from KubeAPI server failed with error: {}"
                    .format(e))
                sys.exit("Please ensure service name and namespace is correct")
            service = service.__dict__
            service = convert_kube_object_to_dict(service)
            #           service = OrderedDict([('apiVersion',service['apiVersion']),
            #                            ('kind',service['kind']),
            #                            ('metadata',service['metadata']),
            #                            ('spec',service['spec']),
            converted_yamls_dict_list.extend(
                convert_yaml_to_sml(service, app_frontend_svc_name,
                                    app_hostname))
    '''
    Adding CPX yamls
    '''
    rbac = manifestCreator.rbac()
    rbac = rbac.createRbac()
    converted_yamls_dict_list.extend(rbac)
    for i in range(1, cpx_count + 1):
        cpx_cic_yaml = manifestCreator.cpxCic({
            "name":
            cpx_ingress_name + str(i),
            "ingressClass":
            ingress_class + str(i)
        })
        cpx_cic_yaml = cpx_cic_yaml.create()
        converted_yamls_dict_list.extend(cpx_cic_yaml)
    '''
    Writing dictionay of YAML into a .yaml file
    '''
    write_dictionaries_into_yaml(converted_yamls_dict_list, output_yaml)