Пример #1
0
def test_compose_cmd_args(cmd_flags, expect_args):
    client = KubeHelmClient()
    init_cmd_args = fake_init_cmd_args.copy()
    composed_cmd_args = client._compose_cmd_args(
        init_cmd_args, fake_chart_path, fake_values_path,
        fake_post_renderer_config_path, cmd_flags)
    assert composed_cmd_args == expect_args
Пример #2
0
    def render(self, namespace="default", bcs_inject_data=None):
        client = KubeHelmClient(helm_bin=settings.HELM_BIN)
        # 针对rollback的diff,不比对平台注入的信息
        if not bcs_inject_data:
            content, notes = client.template(
                files=self.chartVersionSnapshot.files,
                name=self.app.name,
                namespace=namespace,
                parameters=self.parameters,
                valuefile=self.generate_valuesyaml(self.app.project_id,
                                                   self.app.namespace_id,
                                                   self.app.cluster_id),
                cluster_id=self.app.cluster_id,
            )
        else:
            content, notes = client.template_with_ytt_renderer(
                files=self.chartVersionSnapshot.files,
                name=self.app.name,
                namespace=namespace,
                parameters=self.parameters,
                valuefile=self.generate_valuesyaml(self.app.project_id,
                                                   self.app.namespace_id,
                                                   self.app.cluster_id),
                cluster_id=self.app.cluster_id,
                bcs_inject_data=bcs_inject_data)

        return content, notes
Пример #3
0
    def render(self, namespace="default"):
        client = KubeHelmClient(helm_bin=settings.HELM_BIN)
        content, notes = client.template(files=self.chartVersionSnapshot.files,
                                         name=self.app.name,
                                         namespace=namespace,
                                         parameters=self.parameters,
                                         valuefile=self.generate_valuesyaml(
                                             self.app.project_id,
                                             self.app.namespace_id))

        return content, notes
Пример #4
0
    def create(self, validated_data):
        """ 生成应用的预览数据,这个时候应用没有创建,release也没有创建 """
        namespace_info = self.get_ns_info_by_id(validated_data["namespace_info"])

        check_cluster_perm(
            user=self.context["request"].user,
            project_id=namespace_info["project_id"],
            cluster_id=namespace_info["cluster_id"],
            request=self.context["request"]
        )

        # prepare parameters
        parameters = merge_rancher_answers(validated_data["get_answers"], validated_data["get_customs"])

        valuefile = get_valuefile_with_bcs_variable_injected(
            access_token=self.context["request"].user.token.access_token,
            project_id=namespace_info["project_id"],
            namespace_id=namespace_info["id"],
            valuefile=validated_data["valuefile"],
            cluster_id=namespace_info["cluster_id"]
        )
        client = KubeHelmClient(helm_bin=settings.HELM_BIN)
        try:
            content, notes = client.template(
                files=validated_data["chart_version"].files,
                namespace=namespace_info["name"],
                name=validated_data.get("name"),
                parameters=parameters,
                valuefile=valuefile,
            )
        except helm_exceptions.HelmBaseException as e:
            raise ParseError(str(e))

        # inject bcs info
        now = datetime.datetime.now()
        username = self.context["request"].user.username
        content = bcs_info_injector.inject_bcs_info(
            access_token=self.access_token,
            project_id=self.project_id,
            cluster_id=namespace_info["cluster_id"],
            namespace_id=namespace_info["id"],
            namespace=namespace_info["name"],
            creator=username,
            updator=username,
            created_at=now,
            updated_at=now,
            resources=content,
            version=validated_data["chart_version"].version
        )
        return {
            "content": preview_parse(content, namespace_info["name"]),
            "notes": notes
        }
Пример #5
0
def test_do_install(settings, mock_run_command_with_retry):
    release_name = "test-example"
    namespace = "test"
    chart_url = "http://repo.example.com/charts/example-0.1.0.tgz"
    options = [
        {
            "--values": "bcs.yaml"
        },
        {
            "--values": "bcs-saas.yaml"
        },
        {
            "--username": "******"
        },
        {
            "--password": "******"
        },
        "--atomic",
    ]

    client = KubeHelmClient()
    client.do_install_or_upgrade("install",
                                 release_name,
                                 namespace,
                                 chart_url,
                                 options=options)
    mock_run_command_with_retry.assert_called_with(
        max_retries=0,
        cmd_args=[
            settings.HELM3_BIN,
            "install",
            release_name,
            "--namespace",
            namespace,
            chart_url,
            "--values",
            "bcs.yaml",
            "--values",
            "bcs-saas.yaml",
            "--username",
            "admin",
            "--password",
            "admin",
            "--atomic",
        ],
    )
Пример #6
0
 def make_helm_client(self):
     """组装携带kubeconfig的helm client"""
     options = self.make_kubectl_options()
     cluster = kubectl.Cluster(
         name=self.cluster_id,
         cert=options.pop('client-certificate'),
         server=options.pop('server'),
     )
     user = kubectl.User(name=constants.BCS_USER_NAME,
                         token=options['token'])
     context = kubectl.Context(name=constants.BCS_USER_NAME,
                               user=user,
                               cluster=cluster)
     # NOTE: 这里直接使用helm3 client bin
     kube_config = kubectl.KubeConfig(contexts=[context])
     with kube_config.as_tempfile() as filename:
         helm_client = KubeHelmClient(
             helm_bin=settings.HELM3_BIN,
             kubeconfig=filename,
         )
         yield helm_client
Пример #7
0
    def create(self, validated_data):
        """ 生成应用的预览数据,这个时候应用没有创建,release也没有创建 """
        namespace_info = self.get_ns_info_by_id(validated_data["namespace_info"])

        cluster_id = namespace_info["cluster_id"]
        check_cluster_perm(
            user=self.context["request"].user,
            project_id=namespace_info["project_id"],
            cluster_id=cluster_id,
            request=self.context["request"],
        )

        # prepare parameters
        parameters = merge_rancher_answers(validated_data["get_answers"], validated_data["get_customs"])

        valuefile = get_valuefile_with_bcs_variable_injected(
            access_token=self.context["request"].user.token.access_token,
            project_id=namespace_info["project_id"],
            namespace_id=namespace_info["id"],
            valuefile=validated_data["valuefile"],
            cluster_id=cluster_id,
        )

        # inject bcs info
        now = datetime.datetime.now()
        username = self.context["request"].user.username

        # 组装注入的参数
        bcs_inject_data = bcs_helm_utils.BCSInjectData(
            source_type="helm",
            creator=username,
            updator=username,
            version=validated_data["chart_version"].version,
            project_id=self.project_id,
            app_id=self.context["request"].project.cc_app_id,
            cluster_id=cluster_id,
            namespace=namespace_info["name"],
            stdlog_data_id=bcs_helm_utils.get_stdlog_data_id(self.project_id),
            image_pull_secret=bcs_helm_utils.provide_image_pull_secrets(namespace_info["name"]),
        )
        client = KubeHelmClient(helm_bin=settings.HELM3_BIN)
        try:
            extra_params = {"cmd_flags": validated_data["cmd_flags"]}
            content, notes = client.template_with_ytt_renderer(
                files=validated_data["chart_version"].files,
                namespace=namespace_info["name"],
                name=validated_data.get("name"),
                parameters=parameters,
                valuefile=valuefile,
                cluster_id=cluster_id,
                bcs_inject_data=bcs_inject_data,
                **extra_params
            )
        except helm_exceptions.HelmBaseException:
            # raise ParseError(str(e))
            # NOTE: 现阶段为防止出现未测试到的情况,允许出错时,按照先前流程渲染;后续删除
            content, notes = _template_with_bcs_renderer(
                client,
                validated_data["chart_version"].files,
                validated_data.get("name"),
                namespace_info["name"],
                namespace_info["id"],
                parameters,
                valuefile,
                cluster_id,
                username,
                now,
                validated_data["chart_version"].version,
                self.access_token,
                self.project_id,
            )

        return {"content": preview_parse(content, namespace_info["name"]), "notes": notes}
Пример #8
0
    def create(self, validated_data):
        """ 应用更新时的预览数据,这个时候目标release还没有创建 """
        instance = App.objects.get(id=self.app_id)

        check_cluster_perm(
            user=self.context["request"].user,
            project_id=instance.project_id,
            cluster_id=instance.cluster_id,
            request=self.context["request"],
        )

        # 标记Chart中的values.yaml是否发生变化,用于提醒用户
        chart_version_changed = False

        # prepare parameters
        parameters = merge_rancher_answers(validated_data["get_answers"], validated_data["get_customs"])

        chart_version_id = validated_data["upgrade_verion"]
        chart_version_id = int(chart_version_id)
        if chart_version_id == KEEP_TEMPLATE_UNCHANGED:
            files = instance.release.chartVersionSnapshot.files
        else:
            chart_version_changed = True
            chart_version = ChartVersion.objects.get(id=chart_version_id)
            files = chart_version.files

        valuefile = get_valuefile_with_bcs_variable_injected(
            access_token=self.context["request"].user.token.access_token,
            project_id=instance.project_id,
            namespace_id=instance.namespace_id,
            valuefile=validated_data["valuefile"],
            cluster_id=instance.cluster_id,
        )

        now = datetime.datetime.now()
        username = self.context["request"].user.username
        # 组装注入的参数
        bcs_inject_data = bcs_helm_utils.BCSInjectData(
            source_type="helm",
            creator=username,
            updator=username,
            version=instance.release.chartVersionSnapshot.version,
            project_id=self.project_id,
            app_id=self.context["request"].project.cc_app_id,
            cluster_id=instance.cluster_id,
            namespace=instance.namespace,
            stdlog_data_id=bcs_helm_utils.get_stdlog_data_id(self.project_id),
            image_pull_secret=bcs_helm_utils.provide_image_pull_secrets(instance.namespace),
        )
        # 默认为使用helm3 client
        client = KubeHelmClient(helm_bin=settings.HELM3_BIN)
        try:
            content, notes = client.template_with_ytt_renderer(
                files=files,
                namespace=instance.namespace,
                name=instance.name,
                parameters=parameters,
                valuefile=valuefile,
                cluster_id=instance.cluster_id,
                bcs_inject_data=bcs_inject_data,
            )
        except helm_exceptions.HelmBaseException:
            # raise ParseError(str(e))
            # NOTE: 现阶段为防止出现未测试到的情况,允许出错时,按照先前流程渲染;后续删除
            content, notes = _template_with_bcs_renderer(
                client,
                files,
                instance.name,
                instance.namespace,
                instance.namespace_id,
                parameters,
                valuefile,
                instance.cluster_id,
                username,
                now,
                instance.release.chartVersionSnapshot.version,
                self.access_token,
                instance.project_id,
            )

        # compute diff
        old_content = instance.release.content
        if not old_content:
            old_content, _ = instance.render_app(
                username=self.context["request"].user.username, access_token=self.access_token
            )
        difference = simple_diff(old_content, content, instance.namespace)
        return {
            "content": preview_parse(content, instance.namespace),
            "notes": notes,
            "difference": difference,
            "chart_version_changed": chart_version_changed,
            "old_content": old_content,
            "new_content": content,
        }
Пример #9
0
    def create(self, validated_data):
        """ 应用更新时的预览数据,这个时候目标release还没有创建 """
        instance = App.objects.get(id=self.app_id)

        check_cluster_perm(user=self.context["request"].user,
                           project_id=instance.project_id,
                           cluster_id=instance.cluster_id,
                           request=self.context["request"])

        # 标记Chart中的values.yaml是否发生变化,用于提醒用户
        chart_version_changed = False

        # prepare parameters
        parameters = merge_rancher_answers(validated_data["get_answers"],
                                           validated_data["get_customs"])

        chart_version_id = validated_data["upgrade_verion"]
        chart_version_id = int(chart_version_id)
        if chart_version_id == KEEP_TEMPLATE_UNCHANGED:
            files = instance.release.chartVersionSnapshot.files
        else:
            chart_version_changed = True
            chart_version = ChartVersion.objects.get(id=chart_version_id)
            files = chart_version.files

        valuefile = get_valuefile_with_bcs_variable_injected(
            access_token=self.context["request"].user.token.access_token,
            project_id=instance.project_id,
            namespace_id=instance.namespace_id,
            valuefile=validated_data["valuefile"])
        client = KubeHelmClient(helm_bin=settings.HELM_BIN)
        try:
            content, notes = client.template(
                files=files,
                namespace=instance.namespace,
                name=instance.name,
                parameters=parameters,
                valuefile=valuefile,
            )
        except helm_exceptions.HelmBaseException as e:
            raise ParseError(str(e))

        # inject bcs info
        now = datetime.datetime.now()
        content = bcs_info_injector.inject_bcs_info(
            access_token=self.access_token,
            project_id=instance.project_id,
            cluster_id=instance.cluster_id,
            namespace_id=instance.namespace_id,
            namespace=instance.namespace,
            creator=instance.creator,
            updator=self.context["request"].user.username,
            created_at=instance.created,
            updated_at=now,
            resources=content,
            version=instance.release.chartVersionSnapshot.version,
        )

        # compute diff
        old_content = instance.release.content
        if not old_content:
            old_content, _ = instance.render_app(
                username=self.context["request"].user.username,
                access_token=self.access_token)
        difference = simple_diff(old_content, content, instance.namespace)
        return {
            "content": preview_parse(content, instance.namespace),
            "notes": notes,
            "difference": difference,
            "chart_version_changed": chart_version_changed,
            "old_content": old_content
        }
Пример #10
0
def mock_make_helm_client(access_token=None, project_id=None, cluster_id=None):
    """创建连接k8s集群的client"""
    yield KubeHelmClient(), None