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 +}