diff --git a/apis/v1beta1/types.go b/apis/v1beta1/types.go index dec7aec..c79c43d 100644 --- a/apis/v1beta1/types.go +++ b/apis/v1beta1/types.go @@ -13,6 +13,42 @@ import ( type ProviderConfigSpec struct { // Credentials required to authenticate to this provider. Credentials ProviderCredentials `json:"credentials"` + + // +kubebuilder:validation:Optional + Configuration ProviderConfiguration `json:"config"` +} + +// ProviderConfiguration for configuring the terraform provider +// see https://registry.terraform.io/providers/linode/linode/latest/docs#configuration-reference +type ProviderConfiguration struct { + // +kubebuilder:validation:Optional + UserAgentPrefix string `json:"ua_prefix"` + // +kubebuilder:validation:Optional + SkipInstanceReadyPoll bool `json:"skip_instance_ready_poll"` + // +kubebuilder:validation:Optional + SkipInstanceDeletePoll bool `json:"skip_instance_delete_poll"` + // +kubebuilder:validation:Optional + SkipImplicitReboots bool `json:"skip_implicit_reboots"` + // +kubebuilder:validation:Optional + DisableInternalCache bool `json:"disable_internal_cache"` + // +kubebuilder:validation:Optional + MinRetryDelayms int `json:"min_retry_delay_ms"` + // +kubebuilder:validation:Optional + MaxRetryDelayms int `json:"max_retry_delay_ms"` + // +kubebuilder:validation:Optional + EventPollms int `json:"event_poll_ms"` + // +kubebuilder:validation:Optional + LKEEventPollms int `json:"lke_event_poll_ms"` + // +kubebuilder:validation:Optional + LKENodeReadyPollms int `json:"lke_node_ready_poll_ms"` + // +kubebuilder:validation:Optional + ObjAccessKey string `json:"obj_access_key"` + // +kubebuilder:validation:Optional + ObjSecretKey string `json:"obj_secret_key"` + // +kubebuilder:validation:Optional + ObjUseTempKeys bool `json:"obj_use_temp_keys"` + // +kubebuilder:validation:Optional + ObjForceDelete bool `json:"obj_bucket_force_delete"` } // ProviderCredentials required to authenticate. diff --git a/apis/v1beta1/zz_generated.deepcopy.go b/apis/v1beta1/zz_generated.deepcopy.go index 09df2c1..beb2cca 100644 --- a/apis/v1beta1/zz_generated.deepcopy.go +++ b/apis/v1beta1/zz_generated.deepcopy.go @@ -75,6 +75,7 @@ func (in *ProviderConfigList) DeepCopyObject() runtime.Object { func (in *ProviderConfigSpec) DeepCopyInto(out *ProviderConfigSpec) { *out = *in in.Credentials.DeepCopyInto(&out.Credentials) + out.Configuration = in.Configuration } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProviderConfigSpec. @@ -161,6 +162,21 @@ func (in *ProviderConfigUsageList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProviderConfiguration) DeepCopyInto(out *ProviderConfiguration) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProviderConfiguration. +func (in *ProviderConfiguration) DeepCopy() *ProviderConfiguration { + if in == nil { + return nil + } + out := new(ProviderConfiguration) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ProviderCredentials) DeepCopyInto(out *ProviderCredentials) { *out = *in diff --git a/internal/clients/linode.go b/internal/clients/linode.go index 1fd139c..28e7423 100644 --- a/internal/clients/linode.go +++ b/internal/clients/linode.go @@ -55,6 +55,62 @@ type SetupConfig struct { TerraformProvider *schema.Provider } +func prepareTerraformProviderConfiguration(creds map[string]string, pc v1beta1.ProviderConfiguration) map[string]any { + var config map[string]any + + if v, ok := creds[keyToken]; ok { + config[keyToken] = v + } + if v, ok := creds[keyURL]; ok { + config[keyURL] = v + } + if v, ok := creds[keyVersion]; ok { + config[keyVersion] = v + } + + // Set the booleans as is. + config["obj_bucket_force_delete"] = pc.ObjForceDelete + config["obj_use_temp_keys"] = pc.ObjUseTempKeys + config["skip_instance_ready_poll"] = pc.SkipInstanceReadyPoll + config["skip_instance_delete_poll"] = pc.SkipInstanceDeletePoll + config["skip_implicit_reboots"] = pc.SkipImplicitReboots + config["disable_internal_cache"] = pc.DisableInternalCache + + // do not want to override terraform defaults + if len(pc.UserAgentPrefix) > 0 { + config["ua_prefix"] = pc.UserAgentPrefix + } + + if pc.MinRetryDelayms > 0 { + config["min_retry_delay_ms"] = pc.MinRetryDelayms + } + + if pc.MaxRetryDelayms > 0 { + config["max_retry_delay_ms"] = pc.MaxRetryDelayms + } + + if pc.EventPollms > 0 { + config["event_poll_ms"] = pc.MaxRetryDelayms + } + + if pc.LKEEventPollms > 0 { + config["lke_event_poll_ms"] = pc.LKEEventPollms + } + + if pc.LKENodeReadyPollms > 0 { + config["lke_node_ready_poll_ms"] = pc.LKENodeReadyPollms + } + + if len(pc.ObjAccessKey) > 0 { + config["obj_access_key"] = pc.ObjAccessKey + } + + if len(pc.ObjSecretKey) > 0 { + config["obj_secret_key"] = pc.ObjSecretKey + } + return config +} + // TerraformSetupBuilder builds Terraform a terraform.SetupFn function which // returns Terraform provider setup configuration func TerraformSetupBuilder(tfProvider *schema.Provider) terraform.SetupFn { @@ -84,18 +140,13 @@ func TerraformSetupBuilder(tfProvider *schema.Provider) terraform.SetupFn { return ps, errors.Wrap(err, errUnmarshalCredentials) } - // set provider configuration - ps.Configuration = map[string]any{} - if v, ok := creds[keyToken]; ok { - ps.Configuration[keyToken] = v - } - if v, ok := creds[keyURL]; ok { - ps.Configuration[keyURL] = v - } - if v, ok := creds[keyVersion]; ok { - ps.Configuration[keyVersion] = v + if pc.Spec.Configuration.ObjForceDelete && !pc.Spec.Configuration.ObjUseTempKeys && (pc.Spec.Configuration.ObjAccessKey == "" || pc.Spec.Configuration.ObjSecretKey == "") { + return ps, errors.Wrap(err, "if obj_bucket_force_delete is set, then set obj_use_temp_keys or obj_access_key and obj_secret_key") } + // set provider configuration + ps.Configuration = prepareTerraformProviderConfiguration(creds, pc.Spec.Configuration) + return ps, errors.Wrap(configureNoForkLinodeclient(ctx, &ps, *tfProvider), "failed to configure the no-fork linode client") } } diff --git a/package/crds/linode.upbound.io_providerconfigs.yaml b/package/crds/linode.upbound.io_providerconfigs.yaml index d9c77fd..8692eb7 100644 --- a/package/crds/linode.upbound.io_providerconfigs.yaml +++ b/package/crds/linode.upbound.io_providerconfigs.yaml @@ -51,6 +51,40 @@ spec: spec: description: A ProviderConfigSpec defines the desired state of a ProviderConfig. properties: + config: + description: |- + ProviderConfiguration for configuring the terraform provider + see https://registry.terraform.io/providers/linode/linode/latest/docs#configuration-reference + properties: + disable_internal_cache: + type: boolean + event_poll_ms: + type: integer + lke_event_poll_ms: + type: integer + lke_node_ready_poll_ms: + type: integer + max_retry_delay_ms: + type: integer + min_retry_delay_ms: + type: integer + obj_access_key: + type: string + obj_bucket_force_delete: + type: boolean + obj_secret_key: + type: string + obj_use_temp_keys: + type: boolean + skip_implicit_reboots: + type: boolean + skip_instance_delete_poll: + type: boolean + skip_instance_ready_poll: + type: boolean + ua_prefix: + type: string + type: object credentials: description: Credentials required to authenticate to this provider. properties: