Skip to content

Commit

Permalink
Continue refactoring
Browse files Browse the repository at this point in the history
Signed-off-by: Nicolas Bigler <[email protected]>
  • Loading branch information
TheBigLee committed Jan 22, 2025
1 parent dcb6fd4 commit 3d79f03
Show file tree
Hide file tree
Showing 30 changed files with 313 additions and 266 deletions.
13 changes: 7 additions & 6 deletions apis/exoscale/v1/dbaas_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import (
"strings"

xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
exoscaleoapi "github.com/exoscale/egoscale/v2/oapi"
exoscalesdk "github.com/exoscale/egoscale/v3"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
Expand All @@ -27,19 +28,19 @@ type NodeState struct {
// Name of the service node
Name string `json:"name,omitempty"`
// Role of this node.
Role exoscaleoapi.DbaasNodeStateRole `json:"role,omitempty"`
Role exoscalesdk.DBAASNodeStateRole `json:"role,omitempty"`
// State of the service node.
State exoscaleoapi.DbaasNodeStateState `json:"state,omitempty"`
State exoscalesdk.DBAASNodeStateState `json:"state,omitempty"`
}

// Notification contains a service message.
type Notification struct {
// Level of the notification.
Level exoscaleoapi.DbaasServiceNotificationLevel `json:"level,omitempty"`
Level exoscalesdk.DBAASServiceNotificationLevel `json:"level,omitempty"`
// Message contains the notification.
Message string `json:"message,omitempty"`
// Type of the notification.
Type exoscaleoapi.DbaasServiceNotificationType `json:"type,omitempty"`
Type exoscalesdk.DBAASServiceNotificationType `json:"type,omitempty"`
// Metadata contains additional data.
Metadata runtime.RawExtension `json:"metadata,omitempty"`
}
Expand All @@ -61,7 +62,7 @@ type MaintenanceSpec struct {

// DayOfWeek specifies at which weekday the maintenance is held place.
// Allowed values are [monday, tuesday, wednesday, thursday, friday, saturday, sunday, never]
DayOfWeek exoscaleoapi.DbaasServiceMaintenanceDow `json:"dayOfWeek,omitempty"`
DayOfWeek exoscalesdk.DBAASServiceMaintenanceDow `json:"dayOfWeek,omitempty"`

// TimeOfDay for installing updates in UTC.
// Format: "hh:mm:ss".
Expand Down
2 changes: 1 addition & 1 deletion apis/exoscale/v1/iam_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ type IAMKeyParameters struct {
// Zone is the name of the zone where the IAM key is created.
// The zone must be available in the S3 endpoint.
// Cannot be changed after IAMKey is created.
Zone string `json:"zone"`
Zone Zone `json:"zone"`

// +kubebuilder:validation:Required

Expand Down
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
github.com/exoscale/egoscale/v3 v3.1.8
github.com/go-logr/logr v1.4.2
github.com/go-logr/zapr v1.3.0
github.com/google/go-cmp v0.6.0
github.com/hashicorp/go-version v1.6.0
github.com/minio/minio-go/v7 v7.0.70
github.com/stretchr/testify v1.9.0
Expand Down Expand Up @@ -47,13 +48,15 @@ require (
github.com/go-playground/validator/v10 v10.9.0 // indirect
github.com/gobuffalo/flect v1.0.2 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/gofrs/uuid v4.4.0+incompatible // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.6.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/imdario/mergo v0.3.16 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLe
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU=
github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk=
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
Expand Down
25 changes: 25 additions & 0 deletions operator/common/utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package common

import (
exoscalesdk "github.com/exoscale/egoscale/v3"
exoscalev1 "github.com/vshn/provider-exoscale/apis/exoscale/v1"
)

var (
ZoneTranslation = map[exoscalev1.Zone]exoscalesdk.Endpoint{
"CH-DK-2": exoscalesdk.CHDk2,
"CH-GVA-2": exoscalesdk.CHGva2,
"DE-FRA-1": exoscalesdk.DEFra1,
"DE-MUC-1": exoscalesdk.DEMuc1,
"AT-VIE-1": exoscalesdk.ATVie1,
"AT-VIE-2": exoscalesdk.ATVie2,
"BG-SOF-1": exoscalesdk.BGSof1,
"ch-dk-2": exoscalesdk.CHDk2,
"ch-gva-2": exoscalesdk.CHGva2,
"de-fra-1": exoscalesdk.DEFra1,
"de-muc-1": exoscalesdk.DEMuc1,
"at-vie-1": exoscalesdk.ATVie1,
"at-vie-2": exoscalesdk.ATVie2,
"bg-sof-1": exoscalesdk.BGSof1,
}
)
5 changes: 4 additions & 1 deletion operator/iamkeycontroller/connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ import (
"github.com/crossplane/crossplane-runtime/pkg/event"
"github.com/crossplane/crossplane-runtime/pkg/reconciler/managed"
"github.com/crossplane/crossplane-runtime/pkg/resource"
exoscalesdk "github.com/exoscale/egoscale/v3"
"github.com/vshn/provider-exoscale/operator/common"
"github.com/vshn/provider-exoscale/operator/pipelineutil"

ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
)
Expand All @@ -25,7 +28,7 @@ func (c *connector) Connect(ctx context.Context, mg resource.Managed) (managed.E

iamKey := fromManaged(mg)

exo, err := pipelineutil.OpenExoscaleClient(ctx, c.Kube, iamKey.GetProviderConfigName())
exo, err := pipelineutil.OpenExoscaleClient(ctx, c.Kube, iamKey.GetProviderConfigName(), exoscalesdk.ClientOptWithEndpoint(common.ZoneTranslation[iamKey.Spec.ForProvider.Zone]))
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions operator/iamkeycontroller/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (p *IAMKeyPipeline) createIAMKey(ctx *pipelineContext) error {
log.Info("IAM Role doesnt exists, creating", "keyName", ctx.iamKey.Spec.ForProvider.KeyName)
autogeneratedAppcatRole := createRole(iamKey.Spec.ForProvider.KeyName, iamKey.Spec.ForProvider.Services.SOS.Buckets)

op, err := p.exoscaleClient.WithEndpoint(zoneTranslation[ctx.iamKey.Spec.ForProvider.Zone]).CreateIAMRole(ctx, *autogeneratedAppcatRole)
op, err := p.exoscaleClient.CreateIAMRole(ctx, *autogeneratedAppcatRole)

if err != nil || op.State != exoscalesdk.OperationStateSuccess {
return err
Expand All @@ -90,7 +90,7 @@ func (p *IAMKeyPipeline) createIAMKey(ctx *pipelineContext) error {
// since their API is async and it needs a moment to create the IAM Role, we need to wait for it
for i := 0; i < 10; i++ {
// send request
iamKeyCreated, err = p.exoscaleClient.WithEndpoint(zoneTranslation[ctx.iamKey.Spec.ForProvider.Zone]).CreateAPIKey(ctx, newIamKeyRequest)
iamKeyCreated, err = p.exoscaleClient.CreateAPIKey(ctx, newIamKeyRequest)
if err != nil {
time.Sleep(time.Millisecond * 500)
continue
Expand Down
4 changes: 2 additions & 2 deletions operator/iamkeycontroller/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ func (p *IAMKeyPipeline) deleteIAMKey(ctx *pipelineContext) error {

log.Info("Starting IAM key deletion", "keyName", iamKey.Spec.ForProvider.KeyName)

op, err := p.exoscaleClient.WithEndpoint(zoneTranslation[ctx.iamKey.Spec.ForProvider.Zone]).DeleteAPIKey(ctx, iamKey.Status.AtProvider.KeyID)
op, err := p.exoscaleClient.DeleteAPIKey(ctx, iamKey.Status.AtProvider.KeyID)
if err != nil || op.State != exoscalesdk.OperationStateSuccess {
return err
}
op, err = p.exoscaleClient.WithEndpoint(zoneTranslation[ctx.iamKey.Spec.ForProvider.Zone]).DeleteIAMRole(ctx, iamKey.Status.AtProvider.RoleID)
op, err = p.exoscaleClient.DeleteIAMRole(ctx, iamKey.Status.AtProvider.RoleID)
if err != nil || op.State != exoscalesdk.OperationStateSuccess {
return err
}
Expand Down
4 changes: 2 additions & 2 deletions operator/iamkeycontroller/observe.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func (p *IAMKeyPipeline) Observe(ctx context.Context, mg resource.Managed) (mana

pctx := &pipelineContext{Context: ctx, iamKey: iamKey}

apiKey, err := p.exoscaleClient.WithEndpoint(zoneTranslation[iamKey.Spec.ForProvider.Zone]).GetAPIKey(ctx, iamKey.Status.AtProvider.KeyID)
apiKey, err := p.exoscaleClient.GetAPIKey(ctx, iamKey.Status.AtProvider.KeyID)
if err != nil {
if iamKey.GetDeletionTimestamp() != nil {
return managed.ExternalObservation{ResourceExists: false}, nil
Expand Down Expand Up @@ -161,7 +161,7 @@ func (p *IAMKeyPipeline) isRoleUptodate(ctx *pipelineContext) error {

func (p *IAMKeyPipeline) observeRole(ctx *pipelineContext) (*exoscalesdk.IAMRole, error) {

respRole, err := p.exoscaleClient.WithEndpoint(zoneTranslation[ctx.iamKey.Spec.ForProvider.Zone]).GetIAMRole(ctx, ctx.iamKey.Status.AtProvider.RoleID)
respRole, err := p.exoscaleClient.GetIAMRole(ctx, ctx.iamKey.Status.AtProvider.RoleID)
if err != nil || respRole.ID == "" {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion operator/iamkeycontroller/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func (p *IAMKeyPipeline) Update(ctx context.Context, mg resource.Managed) (manag
Labels: role.Labels,
Permissions: role.Permissions,
}
_, err := p.exoscaleClient.WithEndpoint(zoneTranslation[iamKey.Spec.ForProvider.Zone]).UpdateIAMRole(ctx, iamKey.Status.AtProvider.RoleID, updateRole)
_, err := p.exoscaleClient.UpdateIAMRole(ctx, iamKey.Status.AtProvider.RoleID, updateRole)

return managed.ExternalUpdate{}, err
}
10 changes: 0 additions & 10 deletions operator/iamkeycontroller/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,6 @@ const (
var (
policyAllow = exoscalesdk.IAMServicePolicyRuleActionAllow
policyDeny = exoscalesdk.IAMServicePolicyRuleActionDeny

zoneTranslation = map[string]exoscalesdk.Endpoint{
"CH-DK-2": exoscalesdk.CHDk2,
"CH-GVA-2": exoscalesdk.CHGva2,
"DE-FRA-1": exoscalesdk.DEFra1,
"DE-MUC-1": exoscalesdk.DEMuc1,
"AT-VIE-1": exoscalesdk.ATVie1,
"AT-VIE-2": exoscalesdk.ATVie2,
"BG-SOF-1": exoscalesdk.BGSof1,
}
)

func createRole(keyName string, buckets []string) *exoscalesdk.CreateIAMRoleRequest {
Expand Down
39 changes: 39 additions & 0 deletions operator/kafkacontroller/connector.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package kafkacontroller

import (
"context"
"fmt"

"github.com/crossplane/crossplane-runtime/pkg/event"
"github.com/crossplane/crossplane-runtime/pkg/reconciler/managed"
"github.com/crossplane/crossplane-runtime/pkg/resource"
exoscalesdk "github.com/exoscale/egoscale/v3"
exoscalev1 "github.com/vshn/provider-exoscale/apis/exoscale/v1"
"github.com/vshn/provider-exoscale/operator/common"
"github.com/vshn/provider-exoscale/operator/pipelineutil"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
)

type connector struct {
Kube client.Client
Recorder event.Recorder
}

// Connect to the exoscale kafka provider.
func (c *connector) Connect(ctx context.Context, mg resource.Managed) (managed.ExternalClient, error) {
log := ctrl.LoggerFrom(ctx)
log.V(1).Info("connecting resource")

kafkaInstance, ok := mg.(*exoscalev1.Kafka)
if !ok {
return nil, fmt.Errorf("invalid managed resource type %T for kafka connector", mg)
}

exo, err := pipelineutil.OpenExoscaleClient(ctx, c.Kube, kafkaInstance.GetProviderConfigName(), exoscalesdk.ClientOptWithEndpoint(common.ZoneTranslation[kafkaInstance.Spec.ForProvider.Zone]))
if err != nil {
return nil, err
}
return newPipeline(c.Kube, c.Recorder, exo.Exoscale), nil

}
42 changes: 18 additions & 24 deletions operator/kafkacontroller/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,23 @@ package kafkacontroller

import (
"context"
"encoding/json"
"errors"
"fmt"
"strings"

exoscalesdk "github.com/exoscale/egoscale/v3"
exoscalev1 "github.com/vshn/provider-exoscale/apis/exoscale/v1"
"github.com/vshn/provider-exoscale/operator/mapper"

"github.com/crossplane/crossplane-runtime/pkg/reconciler/managed"
"github.com/crossplane/crossplane-runtime/pkg/resource"
exoscaleapi "github.com/exoscale/egoscale/v2/api"
"github.com/exoscale/egoscale/v2/oapi"
controllerruntime "sigs.k8s.io/controller-runtime"
)

// Create idempotently creates a Kafka instance.
// It will not return an "already exits" error.
func (c connection) Create(ctx context.Context, mg resource.Managed) (managed.ExternalCreation, error) {
func (p *pipeline) Create(ctx context.Context, mg resource.Managed) (managed.ExternalCreation, error) {
log := controllerruntime.LoggerFrom(ctx)
log.V(1).Info("creating resource")

Expand All @@ -28,39 +28,33 @@ func (c connection) Create(ctx context.Context, mg resource.Managed) (managed.Ex
}

spec := instance.Spec.ForProvider
ipFilter := []string(spec.IPFilter)
settings, err := mapper.ToMap(spec.KafkaSettings)
ipFilter := spec.IPFilter
settings := exoscalesdk.JSONSchemaKafka{}
err := json.Unmarshal(spec.KafkaSettings.Raw, &settings)
if err != nil {
return managed.ExternalCreation{}, fmt.Errorf("invalid kafka settings: %w", err)
return managed.ExternalCreation{}, fmt.Errorf("cannot map kafkaInstance settings: %w", err)
}

restSettings, err := mapper.ToMap(spec.KafkaRestSettings)
restSettings := exoscalesdk.JSONSchemaKafkaRest{}
err = json.Unmarshal(spec.KafkaRestSettings.Raw, &restSettings)
if err != nil {
return managed.ExternalCreation{}, fmt.Errorf("invalid kafka rest settings: %w", err)
}
var version *string
if spec.Version != "" {
version = &spec.Version
}

body := oapi.CreateDbaasServiceKafkaJSONRequestBody{
IpFilter: &ipFilter,
KafkaSettings: &settings,
Maintenance: &struct {
Dow oapi.CreateDbaasServiceKafkaJSONBodyMaintenanceDow "json:\"dow\""
Time string "json:\"time\""
}{
Dow: oapi.CreateDbaasServiceKafkaJSONBodyMaintenanceDow(spec.Maintenance.DayOfWeek),
body := exoscalesdk.CreateDBAASServiceKafkaRequest{
IPFilter: ipFilter,
KafkaSettings: settings,
Maintenance: &exoscalesdk.CreateDBAASServiceKafkaRequestMaintenance{
Dow: exoscalesdk.CreateDBAASServiceKafkaRequestMaintenanceDow(spec.Maintenance.DayOfWeek),
Time: spec.Maintenance.TimeOfDay.String(),
},
Plan: spec.Size.Plan,
Version: version,
Version: spec.Version,
TerminationProtection: &spec.TerminationProtection,
KafkaRestEnabled: &spec.KafkaRestEnabled,
KafkaRestSettings: &restSettings,
KafkaRestSettings: restSettings,
}

resp, err := c.exo.CreateDbaasServiceKafkaWithResponse(ctx, oapi.DbaasServiceName(instance.GetInstanceName()), body)
resp, err := p.exo.CreateDBAASServiceKafka(ctx, instance.GetInstanceName(), body)
if err != nil {
if errors.Is(err, exoscaleapi.ErrInvalidRequest) && strings.Contains(err.Error(), "Service name is already taken") {
// According to the ExternalClient Interface, create needs to be idempotent.
Expand All @@ -69,6 +63,6 @@ func (c connection) Create(ctx context.Context, mg resource.Managed) (managed.Ex
}
return managed.ExternalCreation{}, fmt.Errorf("unable to create instance: %w", err)
}
log.V(2).Info("response", "body", string(resp.Body))
log.V(2).Info("response", "message", string(resp.Message))
return managed.ExternalCreation{}, nil
}
6 changes: 3 additions & 3 deletions operator/kafkacontroller/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,21 @@ import (

// Delete idempotently deletes a kafka instance.
// It will not return a "not found" error.
func (c connection) Delete(ctx context.Context, mg resource.Managed) error {
func (p *pipeline) Delete(ctx context.Context, mg resource.Managed) error {
log := controllerruntime.LoggerFrom(ctx)
log.V(1).Info("deleting resource")

instance, ok := mg.(*exoscalev1.Kafka)
if !ok {
return fmt.Errorf("invalid managed resource type %T for kafka connection", mg)
}
resp, err := c.exo.DeleteDbaasServiceWithResponse(ctx, instance.GetInstanceName())
resp, err := p.exo.DeleteDBAASServiceKafka(ctx, instance.GetInstanceName())
if err != nil {
if errors.Is(err, exoscaleapi.ErrNotFound) {
return nil
}
return fmt.Errorf("cannot delete kafka instance: %w", err)
}
log.V(2).Info("response", "body", string(resp.Body))
log.V(2).Info("response", "message", string(resp.Message))
return nil
}
Loading

0 comments on commit 3d79f03

Please sign in to comment.