pulumi / pulumi-kubernetes

A Pulumi resource provider for Kubernetes to manage API resources and workloads in running clusters
https://www.pulumi.com/docs/reference/clouds/kubernetes/
Apache License 2.0
404 stars 114 forks source link

Error creating `CustomResource` with configuration NOT under `spec` #1694

Open stanislav-zaprudskiy opened 3 years ago

stanislav-zaprudskiy commented 3 years ago

Creating a Kubernetes custom resource which expects its specification under a custom key, e.g. under .configuration key (compared to the typical .spec key), fails complaining that that required key is missing.

Also, Pulumi does not show that key in diff (it shows others keys, however, e.g. .kind, .metadata, etc).

Steps to reproduce

postgres_operator = Chart(
    "postgres-operator",
    ChartOpts(
        chart="postgres-operator",
        version="1.7.0",
        fetch_opts=FetchOpts(
            repo="https://opensource.zalando.com/postgres-operator/charts/postgres-operator/"
        ),
        namespace="default",
    )
)

Expected: chart is installed Actual: chart is not installed, with the following error:

error: resource postgres-operator/postgres-operator was not successfully created by the Kubernetes API server : OperatorConfiguration.acid.zalan.do "postgres-operator" is invalid: configuration: Required value

Additional notes

Applying the following transformation, which rewrites .configuration into .spec, fixes the issue:

def change_configuration_to_spec(obj):
    if (
        obj["kind"] == "CustomResourceDefinition"
        and obj["metadata"]["name"] == "operatorconfigurations.acid.zalan.do"
    ):
        for version in obj["spec"]["versions"]:
            if version["additionalPrinterColumns"]:
                for column in version["additionalPrinterColumns"]:
                    if (
                        column["jsonPath"]
                            and column["jsonPath"].startswith(".configuration")
                    ):
                        column["jsonPath"] = re.sub(
                            r'^\.configuration',
                            '.spec',
                            column["jsonPath"]
                        )

            new_required = []
            for req in version["schema"]["openAPIV3Schema"]["required"]:
                if req == "configuration":
                    req = "spec"
                new_required.append(req)
            version["schema"]["openAPIV3Schema"]["required"] = new_required

            version["schema"]["openAPIV3Schema"]["properties"]["spec"] = (
                version["schema"]["openAPIV3Schema"]["properties"]
                ["configuration"])
            del (version["schema"]["openAPIV3Schema"]["properties"]
                 ["configuration"])

    if obj["kind"] == "OperatorConfiguration":
        obj["spec"] = obj["configuration"]
        del obj["configuration"]
stanislav-zaprudskiy commented 3 years ago

Just for completeness - transformation makes the chart manifests installable, but the operator itself doesn't work as it is looking for .configration key in the CR.

mikhailshilkov commented 3 years ago

@lblackstone Could you please take a look?

lblackstone commented 3 years ago

Interesting -- I wonder if this issue is specific to Python. Have you tried with any of the other SDKs?