diff --git a/v2/internal/reconcilers/arm/azure_generic_arm_reconciler_instance.go b/v2/internal/reconcilers/arm/azure_generic_arm_reconciler_instance.go index 79e9480a15b..4d2ff790b0c 100644 --- a/v2/internal/reconcilers/arm/azure_generic_arm_reconciler_instance.go +++ b/v2/internal/reconcilers/arm/azure_generic_arm_reconciler_instance.go @@ -559,18 +559,35 @@ func (r *azureDeploymentReconcilerInstance) getStatus(ctx context.Context, id st } // Get the resource - retryAfter, err := r.ARMConnection.Client().GetByID(ctx, id, apiVersion, armStatus) - if err != nil { - return nil, retryAfter, errors.Wrapf(err, "getting resource with ID: %q", id) - } + if genruntime.ResourceOperationGet.IsSupportedBy(r.Obj) { + var retryAfter time.Duration + retryAfter, err = r.ARMConnection.Client().GetByID(ctx, id, apiVersion, armStatus) + if err != nil { + return nil, retryAfter, errors.Wrapf(err, "getting resource with ID: %q", id) + } + + if r.Log.V(Debug).Enabled() { + statusBytes, marshalErr := json.Marshal(armStatus) + if marshalErr != nil { + return nil, zeroDuration, errors.Wrapf(marshalErr, "serializing ARM status to JSON for debugging") + } - if r.Log.V(Debug).Enabled() { - statusBytes, marshalErr := json.Marshal(armStatus) - if marshalErr != nil { - return nil, zeroDuration, errors.Wrapf(marshalErr, "serializing ARM status to JSON for debugging") + r.Log.V(Debug).Info("Got ARM status", "status", string(statusBytes)) + } + } else if genruntime.ResourceOperationHead.IsSupportedBy(r.Obj) { + var retryAfter time.Duration + var exists bool + exists, retryAfter, err = r.ARMConnection.Client().CheckExistenceByID(ctx, id, apiVersion) + if err != nil { + return nil, retryAfter, errors.Wrapf(err, "getting resource with ID: %q", id) } - r.Log.V(Debug).Info("Got ARM status", "status", string(statusBytes)) + // We expect the resource to exist + if !exists { + return nil, retryAfter, errors.Wrapf(err, "getting resource with ID: %q", id) + } + } else { + return nil, zeroDuration, errors.Errorf("resource must support one of GET or HEAD, but it supports neither") } // Convert the ARM shape to the Kube shape diff --git a/v2/pkg/genruntime/base_types.go b/v2/pkg/genruntime/base_types.go index 2ef6bb87a3f..eadc7a2a35e 100644 --- a/v2/pkg/genruntime/base_types.go +++ b/v2/pkg/genruntime/base_types.go @@ -34,6 +34,16 @@ const ( ResourceOperationDelete = ResourceOperation("DELETE") ) +func (o ResourceOperation) IsSupportedBy(obj SupportedResourceOperations) bool { + for _, op := range obj.GetSupportedOperations() { + if op == o { + return true + } + } + + return false +} + // TODO: It's weird that this is isn't with the other annotations // TODO: Should we move them all here (so they're exported?) Or shold we move them // TODO: to serviceoperator-internal.azure.com to signify they are internal? diff --git a/v2/pkg/genruntime/kubernetes_resource.go b/v2/pkg/genruntime/kubernetes_resource.go index 0d51e717f7e..782a01f396a 100644 --- a/v2/pkg/genruntime/kubernetes_resource.go +++ b/v2/pkg/genruntime/kubernetes_resource.go @@ -18,10 +18,17 @@ type ARMOwned interface { Owner() *ResourceReference } +type SupportedResourceOperations interface { + + // GetSupportedOperations gets the set of supported resource operations + GetSupportedOperations() []ResourceOperation +} + // KubernetesResource is an Azure resource. This interface contains the common set of // methods that apply to all ASO ARM resources. type KubernetesResource interface { ARMOwned + SupportedResourceOperations // TODO: I think we need this? // KnownOwner() *KnownResourceReference @@ -36,9 +43,6 @@ type KubernetesResource interface { // GetResourceScope returns the ResourceScope of the resource. GetResourceScope() ResourceScope - // GetSupportedOperations gets the set of supported resource operations - GetSupportedOperations() []ResourceOperation - // Some types, but not all, have a corresponding: // SetAzureName(name string) // They do not if the name must be a fixed value (like 'default').