Skip to content

Commit

Permalink
fix: use lazy loaded client to allow for dynamic creds
Browse files Browse the repository at this point in the history
  • Loading branch information
kaplan-michael committed Feb 13, 2024
1 parent 15d754d commit ea2f0c6
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 67 deletions.
2 changes: 1 addition & 1 deletion go.mod
Expand Up @@ -19,7 +19,7 @@ require (
k8s.io/client-go v0.29.1
k8s.io/kubectl v0.29.1
k8s.io/utils v0.0.0-20240102154912-e7106e64919e
sigs.k8s.io/controller-runtime v0.17.0
sigs.k8s.io/controller-runtime v0.17.1
)

replace github.com/imdario/mergo => github.com/imdario/mergo v0.3.16
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Expand Up @@ -384,8 +384,8 @@ k8s.io/kubectl v0.29.1 h1:rWnW3hi/rEUvvg7jp4iYB68qW5un/urKbv7fu3Vj0/s=
k8s.io/kubectl v0.29.1/go.mod h1:SZzvLqtuOJYSvZzPZR9weSuP0wDQ+N37CENJf0FhDF4=
k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ=
k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/controller-runtime v0.17.0 h1:fjJQf8Ukya+VjogLO6/bNX9HE6Y2xpsO5+fyS26ur/s=
sigs.k8s.io/controller-runtime v0.17.0/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s=
sigs.k8s.io/controller-runtime v0.17.1 h1:V1dQELMGVk46YVXXQUbTFujU7u4DQj6YUj9Rb6cuzz8=
sigs.k8s.io/controller-runtime v0.17.1/go.mod h1:+MngTvIQQQhfXtwfdGw/UOQ/aIaqsYywfCINOtwMO/s=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
sigs.k8s.io/kustomize/api v0.16.0 h1:/zAR4FOQDCkgSDmVzV2uiFbuy9bhu3jEzthrHCuvm1g=
Expand Down
44 changes: 32 additions & 12 deletions internal/provider/olm_v0_operator_resource.go
Expand Up @@ -7,7 +7,6 @@ import (
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/kaplan-michael/terraform-provider-olm/internal/olm/installer"
olmapiv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
"strings"
)
Expand All @@ -17,7 +16,7 @@ var _ resource.Resource = &Operatorv0Resource{}

// Operatorv0Resource struct.
type Operatorv0Resource struct {
client *installer.Client // olm client
provider *OLMProvider // olm provider
}

// NewOperatorv0Resource instantiates the resource with the Kubernetes client.
Expand Down Expand Up @@ -92,30 +91,37 @@ func (r *Operatorv0Resource) Configure(ctx context.Context, req resource.Configu
if req.ProviderData == nil {
return
}
client, ok := req.ProviderData.(*installer.Client)
p, ok := req.ProviderData.(*OLMProvider)
if !ok {
resp.Diagnostics.AddError(
"Unexpected Data Source Configure Type",
fmt.Sprintf("Expected *installer.Client, got: %T. Please report this issue to the provider developers.", req.ProviderData),
fmt.Sprintf("Expected *provider.Provider, got: %T. Please report this issue to the provider developers.", req.ProviderData),
)
return
}

r.client = client
r.provider = p

}

// Create method for Operatorv0Resource.
func (r *Operatorv0Resource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {

var plan Operatorv0ResourceModel
diags := req.Plan.Get(ctx, &plan)
resp.Diagnostics.Append(diags...)
if resp.Diagnostics.HasError() {
return
}

client, err := r.provider.getClient()
if err != nil {
resp.Diagnostics.AddError("Failed to get client", err.Error())
return
}

// Get the subscription resources
resources, err := r.client.GetSubscriptionResources(
resources, err := client.GetSubscriptionResources(
plan.Name.ValueString(),
plan.Namespace.ValueString(),
plan.Channel.ValueString(),
Expand All @@ -133,7 +139,7 @@ func (r *Operatorv0Resource) Create(ctx context.Context, req resource.CreateRequ
}

// Create the Operator
operatorStatus, err := r.client.InstallOperator(ctx, resources)
operatorStatus, err := client.InstallOperator(ctx, resources)
if err != nil {
resp.Diagnostics.AddError(
"Failed to install Operator",
Expand Down Expand Up @@ -170,8 +176,16 @@ func (r *Operatorv0Resource) Read(ctx context.Context, req resource.ReadRequest,
return
}

client, err := r.provider.getClient()

// If client can't be initialized due to missing config, clear the state
if err != nil {
resp.State.RemoveResource(ctx)
return
}

// Get the subscription resources
resources, err := r.client.GetSubscriptionResources(
resources, err := client.GetSubscriptionResources(
state.Name.ValueString(),
state.Namespace.ValueString(),
state.Channel.ValueString(),
Expand All @@ -189,7 +203,7 @@ func (r *Operatorv0Resource) Read(ctx context.Context, req resource.ReadRequest,
}

// Get the current status
status, err := r.client.GetSubscriptionStatus(ctx, resources)
status, err := client.GetSubscriptionStatus(ctx, resources)
if err != nil {
// The resource is not found, which we can assume is because it was deleted.
// Remove the resource from the state and return.
Expand Down Expand Up @@ -231,8 +245,14 @@ func (r *Operatorv0Resource) Delete(ctx context.Context, req resource.DeleteRequ
return
}

client, err := r.provider.getClient()
if err != nil {
resp.Diagnostics.AddError("Failed to get client", err.Error())
return
}

// Get the subscription resources
resources, err := r.client.GetSubscriptionResources(
resources, err := client.GetSubscriptionResources(
state.Name.ValueString(),
state.Namespace.ValueString(),
state.Channel.ValueString(),
Expand All @@ -250,14 +270,14 @@ func (r *Operatorv0Resource) Delete(ctx context.Context, req resource.DeleteRequ
}

// Delete Operator using OLM client
err = r.client.UninstallOperator(ctx, resources)
err = client.UninstallOperator(ctx, resources)
if err != nil {
resp.Diagnostics.AddError("Failed to delete Operator", err.Error())
return
}

// Get the current status to verify deletion
_, err = r.client.GetSubscriptionStatus(ctx, resources)
_, err = client.GetSubscriptionStatus(ctx, resources)
if err != nil {
// The resource is already deleted/not found, which is the desired outcome.
// Remove the resource from the state and return.
Expand Down
50 changes: 37 additions & 13 deletions internal/provider/olm_v0_resource.go
Expand Up @@ -7,7 +7,6 @@ import (
"github.com/hashicorp/terraform-plugin-framework/resource/schema"
"github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault"
"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/kaplan-michael/terraform-provider-olm/internal/olm/installer"
"strings"
)

Expand All @@ -16,7 +15,7 @@ var _ resource.Resource = &OLMv0Resource{}

// OLMv0Resource struct.
type OLMv0Resource struct {
client *installer.Client // olm client
provider *OLMProvider // olm provider
}

// NewOLMv0Resource instantiates the resource with the Kubernetes client.
Expand Down Expand Up @@ -65,7 +64,7 @@ func (r *OLMv0Resource) Configure(ctx context.Context, req resource.ConfigureReq
if req.ProviderData == nil {
return
}
client, ok := req.ProviderData.(*installer.Client)
p, ok := req.ProviderData.(*OLMProvider)
if !ok {
resp.Diagnostics.AddError(
"Unexpected Data Source Configure Type",
Expand All @@ -74,7 +73,7 @@ func (r *OLMv0Resource) Configure(ctx context.Context, req resource.ConfigureReq
return
}

r.client = client
r.provider = p

}

Expand All @@ -87,12 +86,16 @@ func (r *OLMv0Resource) Create(ctx context.Context, req resource.CreateRequest,
return
}

olmStatus, err := r.client.InstallVersion(ctx, plan.Namespace.ValueString(), plan.Version.ValueString())
client, err := r.provider.getClient()
if err != nil {
resp.Diagnostics.AddError("Failed to get client", err.Error())
return
}

olmStatus, err := client.InstallVersion(ctx, plan.Namespace.ValueString(), plan.Version.ValueString())
if err != nil {
resp.Diagnostics.AddError(
"Failed to install OLM",
fmt.Sprintf("Failed to install OLM: %v", err),
)
"Failed to install OLM", err.Error())
return
}

Expand All @@ -119,8 +122,17 @@ func (r *OLMv0Resource) Read(ctx context.Context, req resource.ReadRequest, resp
if resp.Diagnostics.HasError() {
return
}

client, err := r.provider.getClient()

// If client can't be initialized due to missing config, clear the state
if err != nil {
resp.State.RemoveResource(ctx)
return
}

// Get the current status
status, err := r.client.GetStatus(ctx, state.Version.ValueString())
status, err := client.GetStatus(ctx, state.Version.ValueString())
if err != nil {
// The resource is not found, which we can assume is because it was deleted.
// Remove the resource from the state and return.
Expand Down Expand Up @@ -164,16 +176,22 @@ func (r *OLMv0Resource) Update(ctx context.Context, req resource.UpdateRequest,
return
}

client, err := r.provider.getClient()
if err != nil {
resp.Diagnostics.AddError("Failed to get client", err.Error())
return
}

// Check if the version has changed
if plan.Version != state.Version {
// Uninstall the current version
err := r.client.UninstallVersion(ctx, state.Version.ValueString())
err := client.UninstallVersion(ctx, state.Version.ValueString())
if err != nil {
resp.Diagnostics.AddError("Failed to uninstall the current OLM version", err.Error())
return
}
// Install the new version
olmStatus, err := r.client.InstallVersion(ctx, plan.Namespace.ValueString(), plan.Version.ValueString())
olmStatus, err := client.InstallVersion(ctx, plan.Namespace.ValueString(), plan.Version.ValueString())
if err != nil {
resp.Diagnostics.AddError("Failed to install the new OLM version", err.Error())
return
Expand Down Expand Up @@ -203,15 +221,21 @@ func (r *OLMv0Resource) Delete(ctx context.Context, req resource.DeleteRequest,
return
}

client, err := r.provider.getClient()
if err != nil {
resp.Diagnostics.AddError("Failed to get client", err.Error())
return
}

// Delete OLM using OLM client
err := r.client.UninstallVersion(ctx, state.Version.ValueString())
err = client.UninstallVersion(ctx, state.Version.ValueString())
if err != nil {
resp.Diagnostics.AddError("Failed to delete OLM", err.Error())
return
}

// Get the current status to verify deletion
_, err = r.client.GetStatus(ctx, state.Version.ValueString())
_, err = client.GetStatus(ctx, state.Version.ValueString())
if err != nil {
// The resource is already deleted/not found, which is the desired outcome.
// Remove the resource from the state and return.
Expand Down

0 comments on commit ea2f0c6

Please sign in to comment.