From 4871d49b110ce6d6a4405e19f0e005f594849c8f Mon Sep 17 00:00:00 2001 From: Yuwen Ma Date: Thu, 4 Jul 2024 08:44:57 +0000 Subject: [PATCH 1/2] feat: enable pure direct resource on dynamic test --- .../cloudbuild/workerpool_controller.go | 23 ++- .../dynamic_controller_integration_test.go | 2 + pkg/krmtotf/resource.go | 9 ++ pkg/test/resourcefixture/contexts/register.go | 148 ++++++++++-------- 4 files changed, 116 insertions(+), 66 deletions(-) diff --git a/pkg/controller/direct/cloudbuild/workerpool_controller.go b/pkg/controller/direct/cloudbuild/workerpool_controller.go index 5a23ce3482..f887d81bef 100644 --- a/pkg/controller/direct/cloudbuild/workerpool_controller.go +++ b/pkg/controller/direct/cloudbuild/workerpool_controller.go @@ -302,7 +302,28 @@ func (a *Adapter) Update(ctx context.Context, u *unstructured.Unstructured) erro } func (a *Adapter) Export(ctx context.Context) (*unstructured.Unstructured, error) { - return nil, nil + u := &unstructured.Unstructured{} + + apiVersion, kind := krm.GroupVersionKind.ToAPIVersionAndKind() + u.SetAPIVersion(apiVersion) + u.SetKind(kind) + + wp := &krm.CloudBuildWorkerPool{} + wp.Spec.DisplayName = a.actual.DisplayName + wp.Spec.ResourceID = &a.actual.Name + + mapCtx := &MapContext{} + wp.Spec.PrivatePoolConfig = PrivatePoolV1Config_FromProto(mapCtx, a.actual.GetPrivatePoolV1Config()) + if mapCtx.Err() != nil { + return nil, mapCtx.Err() + } + + obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(wp) + if err != nil { + return nil, err + } + u.Object = obj + return u, nil } // Delete implements the Adapter interface. diff --git a/pkg/controller/dynamic/dynamic_controller_integration_test.go b/pkg/controller/dynamic/dynamic_controller_integration_test.go index ec5f18e3c5..4b1552f22c 100644 --- a/pkg/controller/dynamic/dynamic_controller_integration_test.go +++ b/pkg/controller/dynamic/dynamic_controller_integration_test.go @@ -59,6 +59,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/manager" + + _ "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct/register" ) type httpRoundTripperKeyType int diff --git a/pkg/krmtotf/resource.go b/pkg/krmtotf/resource.go index c431a39974..d41fa040d1 100644 --- a/pkg/krmtotf/resource.go +++ b/pkg/krmtotf/resource.go @@ -79,6 +79,15 @@ func NewResource(u *unstructured.Unstructured, sm *corekccv1alpha1.ServiceMappin func NewResourceFromResourceConfig(rc *corekccv1alpha1.ResourceConfig, p *tfschema.Provider) (*Resource, error) { tfResource, ok := p.ResourcesMap[rc.Name] + // Pure Direct Resource does not have ResourceMap. + if rc.Direct { + return &Resource{ + TFInfo: &terraform.InstanceInfo{ + Type: rc.Name, + }, + ResourceConfig: *rc, + }, nil + } if !ok { return nil, fmt.Errorf("error getting TF resource: unknown resource %v", rc.Name) } diff --git a/pkg/test/resourcefixture/contexts/register.go b/pkg/test/resourcefixture/contexts/register.go index 61eb72a79c..f22f0d9421 100644 --- a/pkg/test/resourcefixture/contexts/register.go +++ b/pkg/test/resourcefixture/contexts/register.go @@ -22,10 +22,10 @@ import ( "testing" "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/apis/core/v1alpha1" - "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/config" dclcontroller "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/dcl" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct/directbase" + "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct/registry" - "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/controller/direct/logging" "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/dcl" dclconversion "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/dcl/conversion" dclextension "github.com/GoogleCloudPlatform/k8s-config-connector/pkg/dcl/extension" @@ -112,14 +112,6 @@ func (rc ResourceContext) getResourceConfig(smLoader *servicemappingloader.Servi panic(fmt.Errorf("no resource config found for kind: %v", rc.ResourceKind)) } -func (rc ResourceContext) IsDirectResource() bool { - switch rc.ResourceGVK.GroupKind() { - case schema.GroupKind{Group: "logging.cnrm.cloud.google.com", Kind: "LoggingLogMetric"}: - return true - } - return false -} - func (rc ResourceContext) IsAutoGenerated(smLoader *servicemappingloader.ServiceMappingLoader) bool { if rc.DCLBased { return false @@ -129,6 +121,9 @@ func (rc ResourceContext) IsAutoGenerated(smLoader *servicemappingloader.Service } func (rc ResourceContext) Create(ctx context.Context, _ *testing.T, u *unstructured.Unstructured, provider *tfschema.Provider, c client.Client, smLoader *servicemappingloader.ServiceMappingLoader, config *mmdcl.Config, dclConverter *dclconversion.Converter) (*unstructured.Unstructured, error) { + if rc.IsDirectResource() { + return directCreate(ctx, u, c) + } if rc.DCLBased { return dclCreate(ctx, u, config, c, dclConverter, smLoader) } @@ -136,33 +131,8 @@ func (rc ResourceContext) Create(ctx context.Context, _ *testing.T, u *unstructu } func (rc ResourceContext) Get(ctx context.Context, _ *testing.T, u *unstructured.Unstructured, provider *tfschema.Provider, c client.Client, smLoader *servicemappingloader.ServiceMappingLoader, cfg *mmdcl.Config, dclConverter *dclconversion.Converter, httpClient *http.Client) (*unstructured.Unstructured, error) { - // direct controllers - switch u.GroupVersionKind().GroupKind() { - case schema.GroupKind{Group: "logging.cnrm.cloud.google.com", Kind: "LoggingLogMetric"}: - m, err := logging.NewLogMetricModel(ctx, &config.ControllerConfig{ - HTTPClient: httpClient, - }) - if err != nil { - return nil, err - } - a, err := m.AdapterForObject(ctx, c, u) - if err != nil { - return nil, err - } - found, err := a.Find(ctx) - if err != nil { - return nil, err - } - if !found { - return nil, fmt.Errorf("logging.cnrm.cloud.google.com/LoggingLogMetric '%v' is not found", u.GetName()) - } - - unst, err := a.Export(ctx) - if err != nil { - return nil, err - } - - return unst, nil + if rc.IsDirectResource() { + return directExport(ctx, u, c) } if rc.DCLBased { @@ -172,34 +142,8 @@ func (rc ResourceContext) Get(ctx context.Context, _ *testing.T, u *unstructured } func (rc ResourceContext) Delete(ctx context.Context, _ *testing.T, u *unstructured.Unstructured, provider *tfschema.Provider, c client.Client, smLoader *servicemappingloader.ServiceMappingLoader, cfg *mmdcl.Config, dclConverter *dclconversion.Converter, httpClient *http.Client) error { - // direct controllers - switch u.GroupVersionKind().GroupKind() { - case schema.GroupKind{Group: "logging.cnrm.cloud.google.com", Kind: "LoggingLogMetric"}: - m, err := logging.NewLogMetricModel(ctx, &config.ControllerConfig{ - HTTPClient: httpClient, - }) - if err != nil { - return err - } - a, err := m.AdapterForObject(ctx, c, u) - if err != nil { - return err - } - found, err := a.Find(ctx) - if err != nil { - return err - } - if !found { - return fmt.Errorf("logging.cnrm.cloud.google.com/LoggingLogMetric '%v' not found", u.GetName()) - } - - deleted, err := a.Delete(ctx) - if err != nil { - return err - } - if !deleted { - return fmt.Errorf("did not delete logging.cnrm.cloud.google.com/LoggingLogMetric '%v'", u.GetName()) - } + if rc.IsDirectResource() { + return directDelete(ctx, u, c) } if rc.DCLBased { return dclDelete(ctx, u, cfg, c, dclConverter, smLoader) @@ -390,3 +334,77 @@ func IsNotFoundError(err error) bool { } return strings.Contains(err.Error(), "is not found") } + +func (rc ResourceContext) IsDirectResource() bool { + gk := rc.ResourceGVK.GroupKind() + return registry.IsDirectByGK(gk) +} + +func getAdapter(ctx context.Context, u *unstructured.Unstructured, c client.Client) (directbase.Adapter, error) { + gvk := u.GroupVersionKind() + model, err := registry.GetModel(gvk.GroupKind()) + if err != nil { + return nil, err + } + return model.AdapterForObject(ctx, c, u) +} + +func directExport(ctx context.Context, u *unstructured.Unstructured, c client.Client) (*unstructured.Unstructured, error) { + a, err := getAdapter(ctx, u, c) + if err != nil { + return nil, err + } + + found, err := a.Find(ctx) + if err != nil { + return nil, err + } + if !found { + return nil, fmt.Errorf("GVK %s '%v' is not found", u.GroupVersionKind(), u.GetName()) + } + + unst, err := a.Export(ctx) + if err != nil { + return nil, err + } + return unst, nil +} + +func directCreate(ctx context.Context, u *unstructured.Unstructured, c client.Client) (*unstructured.Unstructured, error) { + a, err := getAdapter(ctx, u, c) + if err != nil { + return nil, err + } + + found, err := a.Find(ctx) + if err != nil { + return nil, err + } + if found { + return nil, fmt.Errorf("GVK %s '%v' already exist", u.GroupVersionKind(), u.GetName()) + } + + err = a.Create(ctx, u) + if err != nil { + return nil, err + } + return directExport(ctx, u, c) +} + +func directDelete(ctx context.Context, u *unstructured.Unstructured, c client.Client) error { + a, err := getAdapter(ctx, u, c) + if err != nil { + return err + } + + found, err := a.Find(ctx) + if err != nil { + return err + } + if !found { + return fmt.Errorf("GVK %s '%v' is not found", u.GroupVersionKind(), u.GetName()) + } + + _, err = a.Delete(ctx) + return err +} From eb9f53d816eb3af1d26aa2b982e85d77a8c7b370 Mon Sep 17 00:00:00 2001 From: Yuwen Ma Date: Tue, 9 Jul 2024 08:32:12 +0000 Subject: [PATCH 2/2] revert cbwp export --- .../cloudbuild/workerpool_controller.go | 23 +------------------ 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/pkg/controller/direct/cloudbuild/workerpool_controller.go b/pkg/controller/direct/cloudbuild/workerpool_controller.go index f887d81bef..5a23ce3482 100644 --- a/pkg/controller/direct/cloudbuild/workerpool_controller.go +++ b/pkg/controller/direct/cloudbuild/workerpool_controller.go @@ -302,28 +302,7 @@ func (a *Adapter) Update(ctx context.Context, u *unstructured.Unstructured) erro } func (a *Adapter) Export(ctx context.Context) (*unstructured.Unstructured, error) { - u := &unstructured.Unstructured{} - - apiVersion, kind := krm.GroupVersionKind.ToAPIVersionAndKind() - u.SetAPIVersion(apiVersion) - u.SetKind(kind) - - wp := &krm.CloudBuildWorkerPool{} - wp.Spec.DisplayName = a.actual.DisplayName - wp.Spec.ResourceID = &a.actual.Name - - mapCtx := &MapContext{} - wp.Spec.PrivatePoolConfig = PrivatePoolV1Config_FromProto(mapCtx, a.actual.GetPrivatePoolV1Config()) - if mapCtx.Err() != nil { - return nil, mapCtx.Err() - } - - obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(wp) - if err != nil { - return nil, err - } - u.Object = obj - return u, nil + return nil, nil } // Delete implements the Adapter interface.