Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ProviderArgs are not optional and can't be left as empty string #19

Open
diegosasw opened this issue Aug 16, 2023 · 9 comments
Open

ProviderArgs are not optional and can't be left as empty string #19

diegosasw opened this issue Aug 16, 2023 · 9 comments
Labels
linear Sync with Linear

Comments

@diegosasw
Copy link

diegosasw commented Aug 16, 2023

I need to use explicit organizationId + token without relying on environment variables.
So I would like to explicitly create a Provider associated to Event Store Cloud which I can later use to explicitly associate to some resources (e.g: the event store cloud project, cluster, etc.)

The problem is that there are no optional ProviderArgs despite the documentation suggesting so
See

export interface ProviderArgs {

and https://developers.eventstore.com/cloud/automation/#provider-configuration

Which are the default clientId, tokenStore, identityProviderUrl and url I should provide?

    const eventStoreDbProvider = new eventstore.Provider(
      `${args.prefix}-eventstoredb-provider`,
      {
        token: args.eventStoreDbToken,
        organizationId: args.eventStoreDbOrganizationId,
        clientId: "",
        tokenStore: "",
        identityProviderUrl: "",
        url: ""
      },
      {
        parent: this
      }
    );

The above would cause

error: Could not automatically download and install resource plugin 'pulumi-resource-eventstorecloud' at version v0.2.8, install the plugin using pulumi plugin install resource eventstorecloud v0.2.8 --server https://github.com/EventStore/pulumi-eventstorecloud/releases/download/0.2.8: error downloading provider eventstorecloud to file: failed to download plugin: eventstorecloud-0.2.8: 404 HTTP error fetching plugin from https://github.com/EventStore/pulumi-eventstorecloud/releases/download/0.2.8/pulumi-resource-eventstorecloud-v0.2.8-windows-amd64.tar.gz

but I am not using .NET SDK nor Go, but Typescript/NodeJs and the documentation says

For projects that use .NET and Go Pulumi SDK you have to install the provider before trying to update the stack.

Is this also needed for Typescript?

CLO-434

@diegosasw
Copy link
Author

diegosasw commented Aug 16, 2023

I found this https://github.com/EventStore/terraform-provider-eventstorecloud/blob/63704ce71c909347fa1012a2d046cd706a7dd0ac/client/client.go#L72

which seems to imply that the identityProviderUrl is https://identity.eventstore.com (https://identity.eventstore.com/.well-known/openid-configuration is available)
and has some default hardcoded valuesif clientId is empty.

But still don't know what to put under tokenStore and url, which are mandatory as per

export interface ProviderArgs {
    clientId: pulumi.Input<string>;
    identityProviderUrl: pulumi.Input<string>;
    organizationId: pulumi.Input<string>;
    token: pulumi.Input<string>;
    tokenStore: pulumi.Input<string>;
    url: pulumi.Input<string>;
}

Any sample using the Pulumi's event store cloud provider would be much appreciated

PS: Today I was unable to test it as event store cloud provisioning seems to be disable for up to 24-48 hours until they review a request form.

@alexeyzimarev
Copy link
Member

Check this https://github.com/EventStore/terraform-provider-eventstorecloud/blob/0e216bcb18ba60ac28eed471ceac5150cf4bb094/client/client.go#L70-L82

These can be empty strings, and the TF provider will set them.

@diegosasw
Copy link
Author

diegosasw commented Aug 18, 2023

url cannot be empty string.

I am getting

eventstorecloud:index:Project (my-eventstore):
    error: 1 error occurred:
        * URL is required

when creating

const project = new esc.Project(
  "my-eventstore",
  {
    name: "my-project"
  },
  { parent: this, provider: eventStoreProvider }
);

Which is expected as per url validation https://github.com/EventStore/terraform-provider-eventstorecloud/blob/0e216bcb18ba60ac28eed471ceac5150cf4bb094/client/client.go#L23

The event store provider is

// Empty optional values as per https://github.com/EventStore/pulumi-eventstorecloud/issues/19
const eventStoreProvider  = new eventstore.Provider(
  "my-provider",
  {
    token: args.eventStoreDbToken, // this is read from config secret eventstorecloud:token
    organizationId: args.eventStoreDbOrganizationId, // this is read from config (not a secret) eventstorecloud:organizationId
    clientId: "",
    tokenStore: "",
    identityProviderUrl: "",
    url: ""
  },
  {
    parent: this
  }
);

If I pass any random url value

eventstorecloud:index:Project (my-eventstore):
    error: 1 error occurred:
        * cannot create path "": mkdir : The system cannot find the path specified.

Which URL is this supposed to be?

An empty tokenStore may also cause problems as per https://github.com/EventStore/terraform-provider-eventstorecloud/blob/0e216bcb18ba60ac28eed471ceac5150cf4bb094/client/client.go#L28

@diegosasw diegosasw changed the title ProviderArgs are not optional ProviderArgs are not optional and can't be left as empty string Aug 18, 2023
@alexeyzimarev
Copy link
Member

alexeyzimarev commented Aug 18, 2023

If it's a bug, it's the generator bug. These values are optional in Terraform as far as I can see. You can find the URL in the Terraform provider code, which I posted earlier. Same for the client id:

	identityProviderURL := opts.IdentityProviderURL
	if strings.TrimSpace(identityProviderURL) == "" {
		identityProviderURL = "https://identity.eventstore.com"
	}
	parsedIdentityProviderURL, err := url.Parse(identityProviderURL)
	if err != nil {
		return nil, fmt.Errorf("invalid identity provider URL: %q, %w", identityProviderURL, err)
	}

	clientID := opts.ClientID
	if strings.TrimSpace(clientID) == "" {
		clientID = "OraYp3cFES9O8aWuQtnqi1A7m534iTwt"
	}

Token store is basically the path where the token will be stored on disk.

@diegosasw
Copy link
Author

diegosasw commented Aug 18, 2023

That's the identityProviderUrl, not the url, which I don't even know what is it or why is needed. Same as the tokenStore. See below terraform requiring a value for url

func (config *Config) validate() error {
	if strings.TrimSpace(config.URL) == "" {
		return errors.New("URL is required")
	}

	if _, err := os.Stat(config.TokenStore); err != nil {
		if os.IsNotExist(err) {
			err := os.MkdirAll(config.TokenStore, 0700)
			if err != nil {
				return fmt.Errorf("cannot create path %q: %w", config.TokenStore, err)
			}

			return nil
		}

		return fmt.Errorf("error reading Token Store %q: %w", config.TokenStore, err)
	}

	return nil
}
export interface ProviderArgs {
    clientId: pulumi.Input<string>;
    identityProviderUrl: pulumi.Input<string>;
    organizationId: pulumi.Input<string>;
    token: pulumi.Input<string>;
    tokenStore: pulumi.Input<string>; // What's this?
    url: pulumi.Input<string>; // What's this?
}

@alexeyzimarev
Copy link
Member

alexeyzimarev commented Aug 28, 2023

As I mentioned before, the token store is the location on disk where the refresh token would be stored locally.

The url parameter is the URL of the ES Cloud API. If it defined in Terraform provider like this, so it is required, but it has a default value:

"url": {
    Type:        schema.TypeString,
    Required:    true,
    DefaultFunc: schema.EnvDefaultFunc("ESC_URL", "https://api.eventstore.cloud"),
},

@alexeyzimarev
Copy link
Member

Here's the default token store:

defaultTokenStore = filepath.Join(os.Getenv("HOME"), ".esctf", "tokens")

@alexeyzimarev
Copy link
Member

Btw, the TypeScript code for provider indeed has this issue, and, I believe, it's the Pulumi generator issue. I know it's a bad excuse, but here how the .NET SDK code looks like:

var merged = CustomResourceOptions.Merge(defaultOptions, options);

There are no pre-checks there. And here's the TypeScript code:

        opts = opts || {};
        {
            if ((!args || args.clientId === undefined) && !opts.urn) {
                throw new Error("Missing required property 'clientId'");
            }
            if ((!args || args.identityProviderUrl === undefined) && !opts.urn) {
                throw new Error("Missing required property 'identityProviderUrl'");
            }
            if ((!args || args.organizationId === undefined) && !opts.urn) {
                throw new Error("Missing required property 'organizationId'");
            }
            if ((!args || args.token === undefined) && !opts.urn) {
                throw new Error("Missing required property 'token'");
            }
            if ((!args || args.tokenStore === undefined) && !opts.urn) {
                throw new Error("Missing required property 'tokenStore'");
            }
            if ((!args || args.url === undefined) && !opts.urn) {
                throw new Error("Missing required property 'url'");
            }
            resourceInputs["clientId"] = args ? args.clientId : undefined;
            resourceInputs["identityProviderUrl"] = args ? args.identityProviderUrl : undefined;
            resourceInputs["organizationId"] = args ? args.organizationId : undefined;
            resourceInputs["token"] = args ? args.token : undefined;
            resourceInputs["tokenStore"] = args ? args.tokenStore : undefined;
            resourceInputs["url"] = args ? args.url : undefined;
        }
        opts = pulumi.mergeOptions(utilities.resourceOptsDefaults(), opts);

You can see that the first check the options, and then do the merge. It should be in reverse.

@alexeyzimarev alexeyzimarev added the linear Sync with Linear label Aug 28, 2023
@diegosasw
Copy link
Author

Thank you.
The workaround with explicit values works well

const eventStoreDbProvider = new eventstore.Provider(
  `foo`,
  {
    token: args.eventStoreDbToken,
    organizationId: args.eventStoreDbOrganizationId,
    clientId: "OraYp3cFES9O8aWuQtnqi1A7m534iTwt", // explicit, should be able to leave it blank
    tokenStore: path.join(os.homedir(), ".esctf", "tokens"), // explicit, should be able to leave it blank
    identityProviderUrl: "https://identity.eventstore.com", // explicit, should be able to leave it blank
    url: "https://api.eventstore.cloud" // explicit, should be able to leave it blank
  },
  {
    parent: this
  }
);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
linear Sync with Linear
Projects
None yet
Development

No branches or pull requests

2 participants