crd2pulumi icon indicating copy to clipboard operation
crd2pulumi copied to clipboard

There is no CronTabDefinition method if I follow your exemple

Open Kamaradeivanov opened this issue 4 years ago • 5 comments

Hello, if I use crd2pulumi to generate a nodejs code, I can't create the crd resource beacause there is no MyCrdDefinition method.

I have follow your exemple here : https://github.com/pulumi/crd2pulumi#examples

I run the command bellow :

crd2pulumi --nodejsPath ./crontabs resourcedefinition.yaml

But there is no crontabs.stable.CronTabDefinition() method in my code

import * as crontabs from "./crontabs"
import * as pulumi from "@pulumi/pulumi"

// Register the CronTab CRD.
const cronTabDefinition = new crontabs.stable.CronTabDefinition("my-crontab-definition")

I have the following error :

Property 'CronTabDefinition' does not exist on type 'typeof 

Kamaradeivanov avatar Jan 28 '21 10:01 Kamaradeivanov

Can you share the generated code in `"./crontabs" so we can help diagnose?

EvanBoyle avatar Jan 28 '21 18:01 EvanBoyle

Hi, I have the same problem. as you can see my stable does not have a CronTabDefinition function I leave all files as-is (just generated)

// crontabs/index.ts
export * from "./provider";
import * as stable from "./stable";
import * as types from "./types";
export {stable, types};
// crontabs/stable/index.ts
import * as v1 from "./v1";
export {v1};
// crontabs/stable/v1/index.ts
export * from "./cronTab";
// crontabs/stable/v1/cronTab.ts
import * as pulumi from "@pulumi/pulumi";
import * as inputs from "../../types/input";
import * as outputs from "../../types/output";
import * as utilities from "../../utilities";
import {ObjectMeta} from "../../meta/v1";

export class CronTab extends pulumi.CustomResource {
    /**
     * Get an existing CronTab resource's state with the given name, ID, and optional extra
     * properties used to qualify the lookup.
     *
     * @param name The _unique_ name of the resulting resource.
     * @param id The _unique_ provider ID of the resource to lookup.
     * @param opts Optional settings to control the behavior of the CustomResource.
     */
    public static get(name: string, id: pulumi.Input<pulumi.ID>, opts?: pulumi.CustomResourceOptions): CronTab {
        return new CronTab(name, undefined as any, { ...opts, id: id });
    }

    /** @internal */
    public static readonly __pulumiType = 'kubernetes:stable.example.com/v1:CronTab';

    /**
     * Returns true if the given object is an instance of CronTab.  This is designed to work even
     * when multiple copies of the Pulumi SDK have been loaded into the same process.
     */
    public static isInstance(obj: any): obj is CronTab {
        if (obj === undefined || obj === null) {
            return false;
        }
        return obj['__pulumiType'] === CronTab.__pulumiType;
    }

    public readonly apiVersion!: pulumi.Output<"stable.example.com/v1" | undefined>;
    public readonly kind!: pulumi.Output<"CronTab" | undefined>;
    public readonly metadata!: pulumi.Output<ObjectMeta | undefined>;
    public readonly spec!: pulumi.Output<outputs.stable.v1.CronTabSpec | undefined>;

    /**
     * Create a CronTab resource with the given unique name, arguments, and options.
     *
     * @param name The _unique_ name of the resource.
     * @param args The arguments to use to populate this resource's properties.
     * @param opts A bag of options that control this resource's behavior.
     */
    constructor(name: string, args?: CronTabArgs, opts?: pulumi.CustomResourceOptions) {
        let inputs: pulumi.Inputs = {};
        if (!(opts && opts.id)) {
            inputs["apiVersion"] = "stable.example.com/v1";
            inputs["kind"] = "CronTab";
            inputs["metadata"] = args ? args.metadata : undefined;
            inputs["spec"] = args ? args.spec : undefined;
        } else {
            inputs["apiVersion"] = undefined /*out*/;
            inputs["kind"] = undefined /*out*/;
            inputs["metadata"] = undefined /*out*/;
            inputs["spec"] = undefined /*out*/;
        }
        if (!opts) {
            opts = {}
        }

        if (!opts.version) {
            opts.version = utilities.getVersion();
        }
        super(CronTab.__pulumiType, name, inputs, opts);
    }
}

/**
 * The set of arguments for constructing a CronTab resource.
 */
export interface CronTabArgs {
    readonly apiVersion?: pulumi.Input<"stable.example.com/v1">;
    readonly kind?: pulumi.Input<"CronTab">;
    readonly metadata?: pulumi.Input<ObjectMeta>;
    readonly spec?: pulumi.Input<inputs.stable.v1.CronTabSpec>;
}

// crontabs/provider.ts
import * as pulumi from "@pulumi/pulumi";
import * as utilities from "./utilities";

export class Provider extends pulumi.ProviderResource {
    /** @internal */
    public static readonly __pulumiType = 'crds';

    /**
     * Returns true if the given object is an instance of Provider.  This is designed to work even
     * when multiple copies of the Pulumi SDK have been loaded into the same process.
     */
    public static isInstance(obj: any): obj is Provider {
        if (obj === undefined || obj === null) {
            return false;
        }
        return obj['__pulumiType'] === Provider.__pulumiType;
    }


    /**
     * Create a Provider resource with the given unique name, arguments, and options.
     *
     * @param name The _unique_ name of the resource.
     * @param args The arguments to use to populate this resource's properties.
     * @param opts A bag of options that control this resource's behavior.
     */
    constructor(name: string, args?: ProviderArgs, opts?: pulumi.ResourceOptions) {
        let inputs: pulumi.Inputs = {};
        {
        }
        if (!opts) {
            opts = {}
        }

        if (!opts.version) {
            opts.version = utilities.getVersion();
        }
        super(Provider.__pulumiType, name, inputs, opts);
    }
}

/**
 * The set of arguments for constructing a Provider resource.
 */
export interface ProviderArgs {
}
// crontabs/utilities.ts
export function getEnv(...vars: string[]): string | undefined {
    for (const v of vars) {
        const value = process.env[v];
        if (value) {
            return value;
        }
    }
    return undefined;
}

export function getEnvBoolean(...vars: string[]): boolean | undefined {
    const s = getEnv(...vars);
    if (s !== undefined) {
        // NOTE: these values are taken from https://golang.org/src/strconv/atob.go?s=351:391#L1, which is what
        // Terraform uses internally when parsing boolean values.
        if (["1", "t", "T", "true", "TRUE", "True"].find(v => v === s) !== undefined) {
            return true;
        }
        if (["0", "f", "F", "false", "FALSE", "False"].find(v => v === s) !== undefined) {
            return false;
        }
    }
    return undefined;
}

export function getEnvNumber(...vars: string[]): number | undefined {
    const s = getEnv(...vars);
    if (s !== undefined) {
        const f = parseFloat(s);
        if (!isNaN(f)) {
            return f;
        }
    }
    return undefined;
}

export function getVersion(): string {
    let version = require('./package.json').version;
    // Node allows for the version to be prefixed by a "v", while semver doesn't.
    // If there is a v, strip it off.
    if (version.indexOf('v') === 0) {
        version = version.slice(1);
    }
    return version;
}
// crontabs/types/index.ts
import * as input from "./input";
import * as output from "./output";
export {input, output};
// crontabs/types/input.ts
import * as pulumi from "@pulumi/pulumi";
import * as inputs from "../types/input";
import * as outputs from "../types/output";

import {ObjectMeta} from "../meta/v1";

export namespace stable {
    export namespace v1 {
        export interface CronTabSpec {
            cronSpec?: pulumi.Input<string>;
            image?: pulumi.Input<string>;
            replicas?: pulumi.Input<number>;
        }
    }
}

// crontabs\types\output.ts
import * as pulumi from "@pulumi/pulumi";
import * as inputs from "../types/input";
import * as outputs from "../types/output";

import {ObjectMeta} from "../meta/v1";

export namespace stable {
    export namespace v1 {
        export interface CronTabSpec {
            cronSpec?: string;
            image?: string;
            replicas?: number;
        }
    }
}

kingpeti avatar Jan 30 '21 23:01 kingpeti

Also running into this. Looking through the source code, it seems like the feature simply doesn't exist despite being documented.

edit: it was deleted after 1.0.4. Can we please put it back? :)

For now, I've worked around this by reverting to 1.0.4.

https://github.com/pulumi/crd2pulumi/compare/1.0.4...master#diff-1289fd8409c271981d453ebe81cff3116c85bf8d674aa4e4c0986f200a02518eL79

tmehlinger avatar Feb 08 '21 17:02 tmehlinger

Indeed I can generate the Definition file with version 1.0.4 but I encounter another issue :'( .

For exmple, I try to generate a CRD from the file of prometheus servicemonitor

Everithing goes fine with the command crd2pulumi --nodejsPath ./crontabs resourcedefinition.yaml

But when I try to use it from pulumi with the following code :

  const serviceMonitorDefinitionCrd = new ServiceMonitorDefinition(
    'ServiceMonitorCRD',
    {
      provider,
    }
  );

I get the following error :

  kubernetes:apiextensions.k8s.io/v1:CustomResourceDefinition (ServiceMonitorCRD):
    error: resource servicemonitors.monitoring.coreos.com was not successfully created by the Kubernetes API server : CustomResourceDefinition.apiextensions.k8s.io "servicemonitors.monitoring.coreos.com" is invalid: spec.validation.openAPIV3Schema.properties[spec].properties[endpoints].items.properties[targetPort].type: Required value: must not be empty for specified object fields

Here is the generated part that raise the error :

targetPort: {
  anyOf: [
    {
      type: 'integer',
    },
    {
      type: 'string',
    },
  ],
  description:
    'Name or number of the target port of the Pod behind the Service, the port must be specified with container port property. Mutually exclusive with port.',
  x_kubernetes_int_or_string: true,
},

It's looks like an error due to multiple type definition.

If you want more error exmple, almost all CRD from this repo raise the same error https://github.com/prometheus-operator/kube-prometheus/tree/master/manifests/setup

Kamaradeivanov avatar Feb 12 '21 10:02 Kamaradeivanov

Guys this issue is still active almost a year after, this is not serious at all. Your tool crd2pulumi is clearly unusable for our company. We try to used it to manage a prometheus-stack but with the recent issue regarding the last-applied-configuration we cant even update our stack from pulumi .... We will move to another solution to manage our kubernetes cluster, probably a real gitops tools like argocd.

Kamaradeivanov avatar Dec 07 '21 11:12 Kamaradeivanov

We do not intend on supporting this feature in crd2pulumi. This tool is meant for generating strongly typed SDKs from a given CRD manifest.

rquitales avatar Sep 13 '24 23:09 rquitales