diff --git a/README.md b/README.md index 7ad78dded27..af2ff6ce068 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,69 @@ For more details on the control flow of the Azure Service operator, refer to the - [Virtual Machine](/docs/services/virtualmachine/virtualmachine.md) - [Virtual Machine Scale Set](/docs/services/vmscaleset/vmscaleset.md) +## Quick start + +![Deploying ASO](/docs/images/asodeploy.gif) + +Do you want to quickly deploy the latest version of Azure Service Operator on your Kubernetes cluster and get exploring? Follow these steps. + +1. Make sure `kubectl` is configured to connect to the Kubernetes cluster you want to deploy Azure Service Operators to. +For an AKS cluster, you can use the below command: + +``` +az aks get-credentials -g -n +``` + +2. Install cert-manager on the cluster using the following commands. + +``` +kubectl create namespace cert-manager +kubectl label namespace cert-manager cert-manager.io/disable-validation=true +kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.12.0/cert-manager.yaml +``` + +Wait for the cert-manager deployment to be complete. Use the below command to check for this. + +``` +kubectl rollout status -n cert-manager deploy/cert-manager-webhook +``` + +3. Download the latest Helm chart for Azure Service Operators locally to your machine. Run the following commands. + +``` +mkdir install-aso +cd install-aso +export HELM_EXPERIMENTAL_OCI=1 +``` + +Pull and export the helm chart. + +``` +helm chart pull mcr.microsoft.com/k8s/asohelmchart:latest +``` + +``` +helm chart export mcr.microsoft.com/k8s/asohelmchart:latest --destination . +``` + +4. Install the Azure Service Operator on your cluster using the following helm install command. + +The ServicePrincipal you pass to the command below should have access to create resources in your subscription. + +``` +helm install aso ./azure-service-operator \ + --set azureSubscriptionID= \ + --set azureTenantID= \ + --set azureClientID= \ + --set azureClientSecret= \ + --set createNamespace=true \ + --set image.repository="mcr.microsoft.com/k8s/azure-service-operator:latest" +``` + +Now you can see the Azure service operator pods running in your cluster. + +`kubectl get pods -n azureoperator-system` + ## Getting started This project maintains [releases of the Azure Service Operator](https://github.com/Azure/azure-service-operator/releases) that you can deploy via a [configurable Helm chart](/charts/azure-service-operator). diff --git a/docs/images/asodeploy.gif b/docs/images/asodeploy.gif new file mode 100644 index 00000000000..6a523943836 Binary files /dev/null and b/docs/images/asodeploy.gif differ diff --git a/pkg/errhelp/errhelp.go b/pkg/errhelp/errhelp.go index d2614f2e823..ab377ae596f 100644 --- a/pkg/errhelp/errhelp.go +++ b/pkg/errhelp/errhelp.go @@ -9,41 +9,6 @@ import ( "strings" ) -// IsParentNotFound checks if the error is about a parent resrouce not existing -func IsParentNotFound(err error) bool { - return strings.Contains(err.Error(), "ParentResourceNotFound") -} - -// IsGroupNotFound checks if error is about resource group not existing -func IsGroupNotFound(err error) bool { - return strings.Contains(err.Error(), "ResourceGroupNotFound") -} - -// IsNotActive checks if error is mentioning a non active resource -func IsNotActive(err error) bool { - return strings.Contains(err.Error(), "not active") -} - -// IsAsynchronousOperationNotComplete checks if error reports an asynchronous operation not completed -func IsAsynchronousOperationNotComplete(err error) bool { - return strings.Contains(err.Error(), "asynchronous operation has not completed") -} - -// IsStatusCode204 checks if the error reports a status code 204 failure to respond to request -func IsStatusCode204(err error) bool { - return strings.Contains(err.Error(), "StatusCode=204") -} - -// IsStatusCode404 checks if the error reports a status code 404 resource not found -func IsStatusCode404(err error) bool { - return strings.Contains(err.Error(), "StatusCode=404") -} - -// IsResourceNotFound checks if error reports that a referenced resource is not found -func IsResourceNotFound(err error) bool { - return strings.Contains(err.Error(), "ResourceNotFound") -} - // StripErrorIDs takes an error and returns its string representation after filtering some common ID patterns func StripErrorIDs(err error) string { patterns := []string{ diff --git a/pkg/resourcemanager/apim/apimgmt/apimgmt_test.go b/pkg/resourcemanager/apim/apimgmt/apimgmt_test.go index dab131d2512..effd7c47b8c 100644 --- a/pkg/resourcemanager/apim/apimgmt/apimgmt_test.go +++ b/pkg/resourcemanager/apim/apimgmt/apimgmt_test.go @@ -10,6 +10,7 @@ import ( "github.com/Azure/azure-sdk-for-go/services/apimanagement/mgmt/2019-01-01/apimanagement" "github.com/Azure/azure-service-operator/api/v1alpha1" "github.com/Azure/azure-service-operator/pkg/errhelp" + "github.com/Azure/azure-service-operator/pkg/helpers" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) @@ -69,7 +70,11 @@ var _ = Describe("API Management", func() { APIETag) if err != nil { fmt.Println(err.Error()) - if !errhelp.IsAsynchronousOperationNotComplete(err) { + ignore := []string{ + errhelp.AsyncOpIncompleteError, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if !helpers.ContainsString(ignore, azerr.Type) { fmt.Println("error occured") return false } @@ -90,7 +95,11 @@ var _ = Describe("API Management", func() { _, err = APIManager.DeleteAPI(ctx, tc.ResourceGroupName, APIServiceName, *contract.ID, *contract.APIRevision, true) if err != nil { fmt.Println(err.Error()) - if !errhelp.IsAsynchronousOperationNotComplete(err) { + ignore := []string{ + errhelp.AsyncOpIncompleteError, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if !helpers.ContainsString(ignore, azerr.Type) { fmt.Println("error occured") return false } diff --git a/pkg/resourcemanager/appinsights/appinsights.go b/pkg/resourcemanager/appinsights/appinsights.go index d03efed3f50..3cbbaa75064 100644 --- a/pkg/resourcemanager/appinsights/appinsights.go +++ b/pkg/resourcemanager/appinsights/appinsights.go @@ -188,9 +188,22 @@ func (m *Manager) Delete(ctx context.Context, obj runtime.Object, opts ...resour response, err := m.DeleteAppInsights(ctx, i.Spec.ResourceGroup, i.Name) if err != nil { - if !errhelp.IsAsynchronousOperationNotComplete(err) { - return true, err + catch := []string{ + errhelp.AsyncOpIncompleteError, + } + gone := []string{ + errhelp.ResourceGroupNotFoundErrorCode, + errhelp.ParentNotFoundErrorCode, + errhelp.NotFoundErrorCode, + errhelp.ResourceNotFound, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if helpers.ContainsString(catch, azerr.Type) { + return true, nil + } else if helpers.ContainsString(gone, azerr.Type) { + return false, nil } + return true, err } i.Status.State = response.Status diff --git a/pkg/resourcemanager/appinsights/appinsights_test.go b/pkg/resourcemanager/appinsights/appinsights_test.go index 5b239f9fe3e..b860af21396 100644 --- a/pkg/resourcemanager/appinsights/appinsights_test.go +++ b/pkg/resourcemanager/appinsights/appinsights_test.go @@ -43,7 +43,11 @@ var _ = Describe("App Insights", func() { _, err = AppInsightsManager.CreateAppInsights(ctx, rgName, "web", "other", location, appinsightsInstance) if err != nil { fmt.Println(err.Error()) - if !errhelp.IsAsynchronousOperationNotComplete(err) { + ignore := []string{ + errhelp.AsyncOpIncompleteError, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if !helpers.ContainsString(ignore, azerr.Type) { fmt.Println("error occured") return false } @@ -64,7 +68,11 @@ var _ = Describe("App Insights", func() { _, err = AppInsightsManager.DeleteAppInsights(ctx, psqlServer, appinsightsInstance) if err != nil { fmt.Println(err.Error()) - if !errhelp.IsAsynchronousOperationNotComplete(err) { + ignore := []string{ + errhelp.AsyncOpIncompleteError, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if !helpers.ContainsString(ignore, azerr.Type) { fmt.Println("error occured") return false } diff --git a/pkg/resourcemanager/appinsights/suite_test.go b/pkg/resourcemanager/appinsights/suite_test.go index 98083a94ff3..6d06a93fd21 100644 --- a/pkg/resourcemanager/appinsights/suite_test.go +++ b/pkg/resourcemanager/appinsights/suite_test.go @@ -77,7 +77,11 @@ var _ = BeforeSuite(func() { var _ = AfterSuite(func() { By("tearing down the test environment") _, err := tc.ResourceGroupManager.DeleteGroup(ctx, tc.ResourceGroupName) - if !errhelp.IsAsynchronousOperationNotComplete(err) { + ignore := []string{ + errhelp.AsyncOpIncompleteError, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if !helpers.ContainsString(ignore, azerr.Type) { log.Println("Delete RG failed") return } @@ -88,9 +92,13 @@ var _ = AfterSuite(func() { if err == nil { log.Println("waiting for resource group to be deleted") } else { - if errhelp.IsGroupNotFound(err) { - log.Println("resource group deleted") - break + catch := []string{ + errhelp.ResourceGroupNotFoundErrorCode, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if helpers.ContainsString(catch, azerr.Type) { + log.Println("Delete RG failed") + return } else { log.Println(fmt.Sprintf("cannot delete resource group: %v", err)) return diff --git a/pkg/resourcemanager/azuresql/azuresqldb/azuresqldb_reconcile.go b/pkg/resourcemanager/azuresql/azuresqldb/azuresqldb_reconcile.go index 50f2a48c15e..6e0cfb64fe6 100644 --- a/pkg/resourcemanager/azuresql/azuresqldb/azuresqldb_reconcile.go +++ b/pkg/resourcemanager/azuresql/azuresqldb/azuresqldb_reconcile.go @@ -134,11 +134,21 @@ func (db *AzureSqlDbManager) Delete(ctx context.Context, obj runtime.Object, opt _, err = db.DeleteDB(ctx, groupName, server, dbName) if err != nil { - if errhelp.IsStatusCode204(err) { - // Database does not exist + catch := []string{ + errhelp.AsyncOpIncompleteError, + } + gone := []string{ + errhelp.ResourceGroupNotFoundErrorCode, + errhelp.ParentNotFoundErrorCode, + errhelp.NotFoundErrorCode, + errhelp.ResourceNotFound, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if helpers.ContainsString(catch, azerr.Type) { + return true, nil + } else if helpers.ContainsString(gone, azerr.Type) { return false, nil } - return true, fmt.Errorf("AzureSqlDb delete error %v", err) } diff --git a/pkg/resourcemanager/azuresql/azuresqlfirewallrule/azuresqlfirewallrule_reconcile.go b/pkg/resourcemanager/azuresql/azuresqlfirewallrule/azuresqlfirewallrule_reconcile.go index bac1577a9a7..268a6eb3af9 100644 --- a/pkg/resourcemanager/azuresql/azuresqlfirewallrule/azuresqlfirewallrule_reconcile.go +++ b/pkg/resourcemanager/azuresql/azuresqlfirewallrule/azuresqlfirewallrule_reconcile.go @@ -80,15 +80,23 @@ func (fw *AzureSqlFirewallRuleManager) Delete(ctx context.Context, obj runtime.O err = fw.DeleteSQLFirewallRule(ctx, groupName, server, ruleName) if err != nil { - if errhelp.IsStatusCode204(err) { - // firewall does not exist - return true, nil + catch := []string{ + errhelp.AsyncOpIncompleteError, } - if errhelp.IsStatusCode404(err) { + gone := []string{ + errhelp.ResourceGroupNotFoundErrorCode, + errhelp.ParentNotFoundErrorCode, + errhelp.NotFoundErrorCode, + errhelp.ResourceNotFound, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if helpers.ContainsString(catch, azerr.Type) { + return true, nil + } else if helpers.ContainsString(gone, azerr.Type) { return false, nil } instance.Status.Message = fmt.Sprintf("AzureSqlFirewallRule Delete failed with %s", err.Error()) - return false, err + return true, err } instance.Status.Message = fmt.Sprintf("Delete AzureSqlFirewallRule succeeded") return false, nil diff --git a/pkg/resourcemanager/keyvaults/keyvault.go b/pkg/resourcemanager/keyvaults/keyvault.go index 17fc2e07edd..a98e9bb586d 100644 --- a/pkg/resourcemanager/keyvaults/keyvault.go +++ b/pkg/resourcemanager/keyvaults/keyvault.go @@ -486,9 +486,22 @@ func (k *azureKeyVaultManager) Delete(ctx context.Context, obj runtime.Object, o if err == nil { _, err := k.DeleteVault(ctx, instance.Spec.ResourceGroup, instance.Name) if err != nil { - if !errhelp.IsAsynchronousOperationNotComplete(err) { - return true, err + catch := []string{ + errhelp.AsyncOpIncompleteError, } + gone := []string{ + errhelp.ResourceGroupNotFoundErrorCode, + errhelp.ParentNotFoundErrorCode, + errhelp.NotFoundErrorCode, + errhelp.ResourceNotFound, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if helpers.ContainsString(catch, azerr.Type) { + return true, nil + } else if helpers.ContainsString(gone, azerr.Type) { + return false, nil + } + return true, err } return true, nil } diff --git a/pkg/resourcemanager/keyvaults/keyvault_test.go b/pkg/resourcemanager/keyvaults/keyvault_test.go index 56b7be06ac1..1140979d38a 100644 --- a/pkg/resourcemanager/keyvaults/keyvault_test.go +++ b/pkg/resourcemanager/keyvaults/keyvault_test.go @@ -74,7 +74,11 @@ var _ = Describe("KeyVault Resource Manager test", func() { ) if err != nil { fmt.Println(err.Error()) - if !errhelp.IsAsynchronousOperationNotComplete(err) { + ignore := []string{ + errhelp.AsyncOpIncompleteError, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if !helpers.ContainsString(ignore, azerr.Type) { fmt.Println("error occured") return false } @@ -97,7 +101,11 @@ var _ = Describe("KeyVault Resource Manager test", func() { _, err := keyVaultManager.DeleteVault(ctx, rgName, keyvaultName) if err != nil { fmt.Println(err.Error()) - if !errhelp.IsAsynchronousOperationNotComplete(err) { + ignore := []string{ + errhelp.AsyncOpIncompleteError, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if !helpers.ContainsString(ignore, azerr.Type) { fmt.Println("error occured") return false } diff --git a/pkg/resourcemanager/keyvaults/suite_test.go b/pkg/resourcemanager/keyvaults/suite_test.go index dbad40675b0..359d55226c4 100644 --- a/pkg/resourcemanager/keyvaults/suite_test.go +++ b/pkg/resourcemanager/keyvaults/suite_test.go @@ -81,10 +81,15 @@ var _ = AfterSuite(func() { By("tearing down the test environment") // delete the resource group and contained resources _, err := tc.ResourceGroupManager.DeleteGroup(ctx, tc.ResourceGroupName) - if !errhelp.IsAsynchronousOperationNotComplete(err) { + ignore := []string{ + errhelp.AsyncOpIncompleteError, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if !helpers.ContainsString(ignore, azerr.Type) { log.Println("Delete RG failed") return } + polling := time.Second * 10 Eventually(func() bool { _, err := resourcegroupsresourcemanager.GetGroup(ctx, tc.ResourceGroupName) @@ -93,7 +98,11 @@ var _ = AfterSuite(func() { return false } - if errhelp.IsGroupNotFound(err) { + catch := []string{ + errhelp.ResourceGroupNotFoundErrorCode, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if helpers.ContainsString(catch, azerr.Type) { log.Println("resource group deleted") return true } else { diff --git a/pkg/resourcemanager/loadbalancer/reconcile.go b/pkg/resourcemanager/loadbalancer/reconcile.go index 04468d8b641..319970a3c65 100644 --- a/pkg/resourcemanager/loadbalancer/reconcile.go +++ b/pkg/resourcemanager/loadbalancer/reconcile.go @@ -141,9 +141,22 @@ func (g *AzureLoadBalancerClient) Delete(ctx context.Context, obj runtime.Object resourceGroup, ) if err != nil { - if !errhelp.IsAsynchronousOperationNotComplete(err) { - return true, err + catch := []string{ + errhelp.AsyncOpIncompleteError, + } + gone := []string{ + errhelp.ResourceGroupNotFoundErrorCode, + errhelp.ParentNotFoundErrorCode, + errhelp.NotFoundErrorCode, + errhelp.ResourceNotFound, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if helpers.ContainsString(catch, azerr.Type) { + return true, nil + } else if helpers.ContainsString(gone, azerr.Type) { + return false, nil } + return true, err } if err == nil { diff --git a/pkg/resourcemanager/mysql/database/reconcile.go b/pkg/resourcemanager/mysql/database/reconcile.go index e8f78b3da7c..8a096c9e3d8 100644 --- a/pkg/resourcemanager/mysql/database/reconcile.go +++ b/pkg/resourcemanager/mysql/database/reconcile.go @@ -122,15 +122,26 @@ func (m *MySQLDatabaseClient) Delete(ctx context.Context, obj runtime.Object, op status, err := m.DeleteDatabase(ctx, instance.Name, instance.Spec.Server, instance.Spec.ResourceGroup) if err != nil { - if !errhelp.IsAsynchronousOperationNotComplete(err) { - return true, err + catch := []string{ + errhelp.AsyncOpIncompleteError, } - } - - if err == nil { - if status != "InProgress" { + gone := []string{ + errhelp.ResourceGroupNotFoundErrorCode, + errhelp.ParentNotFoundErrorCode, + errhelp.NotFoundErrorCode, + errhelp.ResourceNotFound, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if helpers.ContainsString(catch, azerr.Type) { + return true, nil + } else if helpers.ContainsString(gone, azerr.Type) { return false, nil } + return true, err + } + + if status != "InProgress" { + return false, nil } return true, nil diff --git a/pkg/resourcemanager/mysql/firewallrule/reconcile.go b/pkg/resourcemanager/mysql/firewallrule/reconcile.go index a1187a9f8e0..89d102ab106 100644 --- a/pkg/resourcemanager/mysql/firewallrule/reconcile.go +++ b/pkg/resourcemanager/mysql/firewallrule/reconcile.go @@ -123,9 +123,22 @@ func (m *MySQLFirewallRuleClient) Delete(ctx context.Context, obj runtime.Object status, err := m.DeleteFirewallRule(ctx, instance.Spec.ResourceGroup, instance.Spec.Server, instance.Name) if err != nil { - if !errhelp.IsAsynchronousOperationNotComplete(err) { - return true, err + catch := []string{ + errhelp.AsyncOpIncompleteError, + } + gone := []string{ + errhelp.ResourceGroupNotFoundErrorCode, + errhelp.ParentNotFoundErrorCode, + errhelp.NotFoundErrorCode, + errhelp.ResourceNotFound, } + azerr := errhelp.NewAzureErrorAzureError(err) + if helpers.ContainsString(catch, azerr.Type) { + return true, nil + } else if helpers.ContainsString(gone, azerr.Type) { + return false, nil + } + return true, err } instance.Status.State = status diff --git a/pkg/resourcemanager/mysql/server/reconcile.go b/pkg/resourcemanager/mysql/server/reconcile.go index b3650b375ca..a3a7adb6705 100644 --- a/pkg/resourcemanager/mysql/server/reconcile.go +++ b/pkg/resourcemanager/mysql/server/reconcile.go @@ -204,9 +204,22 @@ func (m *MySQLServerClient) Delete(ctx context.Context, obj runtime.Object, opts status, err := m.DeleteServer(ctx, instance.Spec.ResourceGroup, instance.Name) if err != nil { - if !errhelp.IsAsynchronousOperationNotComplete(err) { - return true, err + catch := []string{ + errhelp.AsyncOpIncompleteError, } + gone := []string{ + errhelp.ResourceGroupNotFoundErrorCode, + errhelp.ParentNotFoundErrorCode, + errhelp.NotFoundErrorCode, + errhelp.ResourceNotFound, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if helpers.ContainsString(catch, azerr.Type) { + return true, nil + } else if helpers.ContainsString(gone, azerr.Type) { + return false, nil + } + return true, err } instance.Status.State = status diff --git a/pkg/resourcemanager/nic/reconcile.go b/pkg/resourcemanager/nic/reconcile.go index ce5ccbbae0a..0e5b61226b8 100644 --- a/pkg/resourcemanager/nic/reconcile.go +++ b/pkg/resourcemanager/nic/reconcile.go @@ -135,9 +135,22 @@ func (g *AzureNetworkInterfaceClient) Delete(ctx context.Context, obj runtime.Ob resourceGroup, ) if err != nil { - if !errhelp.IsAsynchronousOperationNotComplete(err) { - return true, err + catch := []string{ + errhelp.AsyncOpIncompleteError, + } + gone := []string{ + errhelp.ResourceGroupNotFoundErrorCode, + errhelp.ParentNotFoundErrorCode, + errhelp.NotFoundErrorCode, + errhelp.ResourceNotFound, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if helpers.ContainsString(catch, azerr.Type) { + return true, nil + } else if helpers.ContainsString(gone, azerr.Type) { + return false, nil } + return true, err } if err == nil { diff --git a/pkg/resourcemanager/pip/reconcile.go b/pkg/resourcemanager/pip/reconcile.go index ce549b88029..9f67f59f85c 100644 --- a/pkg/resourcemanager/pip/reconcile.go +++ b/pkg/resourcemanager/pip/reconcile.go @@ -140,9 +140,22 @@ func (g *AzurePublicIPAddressClient) Delete(ctx context.Context, obj runtime.Obj resourceGroup, ) if err != nil { - if !errhelp.IsAsynchronousOperationNotComplete(err) { - return true, err + catch := []string{ + errhelp.AsyncOpIncompleteError, + } + gone := []string{ + errhelp.ResourceGroupNotFoundErrorCode, + errhelp.ParentNotFoundErrorCode, + errhelp.NotFoundErrorCode, + errhelp.ResourceNotFound, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if helpers.ContainsString(catch, azerr.Type) { + return true, nil + } else if helpers.ContainsString(gone, azerr.Type) { + return false, nil } + return true, err } if err == nil { diff --git a/pkg/resourcemanager/psql/database/database_reconcile.go b/pkg/resourcemanager/psql/database/database_reconcile.go index 70e2665dc99..2a94fdb30d0 100644 --- a/pkg/resourcemanager/psql/database/database_reconcile.go +++ b/pkg/resourcemanager/psql/database/database_reconcile.go @@ -98,15 +98,27 @@ func (p *PSQLDatabaseClient) Delete(ctx context.Context, obj runtime.Object, opt status, err := p.DeleteDatabase(ctx, instance.Name, instance.Spec.Server, instance.Spec.ResourceGroup) if err != nil { - if !errhelp.IsAsynchronousOperationNotComplete(err) { - return true, err + catch := []string{ + errhelp.AsyncOpIncompleteError, } - } - - if err == nil { - if status != "InProgress" { + gone := []string{ + errhelp.ResourceGroupNotFoundErrorCode, + errhelp.ParentNotFoundErrorCode, + errhelp.NotFoundErrorCode, + errhelp.ResourceNotFound, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if helpers.ContainsString(catch, azerr.Type) { + return true, nil + } else if helpers.ContainsString(gone, azerr.Type) { return false, nil } + return true, err + } + instance.Status.State = status + + if status != "InProgress" { + return false, nil } return true, nil diff --git a/pkg/resourcemanager/psql/database/suite_test.go b/pkg/resourcemanager/psql/database/suite_test.go deleted file mode 100644 index 362c3258e8b..00000000000 --- a/pkg/resourcemanager/psql/database/suite_test.go +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -package database - -import ( - "testing" - "time" - - "github.com/Azure/azure-service-operator/pkg/errhelp" - resourcemanagerconfig "github.com/Azure/azure-service-operator/pkg/resourcemanager/config" - server "github.com/Azure/azure-service-operator/pkg/resourcemanager/psql/server" - - resourcegroupsresourcemanager "github.com/Azure/azure-service-operator/pkg/resourcemanager/resourcegroups" - . "github.com/onsi/ginkgo" - . "github.com/onsi/gomega" - - "context" - - "github.com/Azure/azure-service-operator/pkg/helpers" - // +kubebuilder:scaffold:imports -) - -// These tests use Ginkgo (BDD-style Go testing framework). Refer to -// http://onsi.github.io/ginkgo/ to learn more about Ginkgo. - -type TestContext struct { - ResourceGroupName string - ResourceGroupLocation string - postgreSQLServerManager server.PostgreSQLServerManager - postgreSQLDatabaseManager PostgreSQLDatabaseManager - ResourceGroupManager resourcegroupsresourcemanager.ResourceGroupManager - timeout time.Duration - retryInterval time.Duration -} - -var tc TestContext -var ctx context.Context - -func TestAPIs(t *testing.T) { - t.Parallel() - RegisterFailHandler(Fail) - RunSpecs(t, "PSQL database Suite") -} - -var _ = BeforeSuite(func() { - - By("bootstrapping test environment") - - ctx = context.Background() - err := resourcemanagerconfig.ParseEnvironment() - Expect(err).ToNot(HaveOccurred()) - - resourceGroupName := "t-rg-dev-psql-" + helpers.RandomString(10) - resourceGroupLocation := resourcemanagerconfig.DefaultLocation() - resourceGroupManager := resourcegroupsresourcemanager.NewAzureResourceGroupManager() - - //create resourcegroup for this suite - _, err = resourceGroupManager.CreateGroup(ctx, resourceGroupName, resourceGroupLocation) - Expect(err).ToNot(HaveOccurred()) - - tc = TestContext{ - ResourceGroupName: resourceGroupName, - ResourceGroupLocation: resourceGroupLocation, - postgreSQLServerManager: &server.PSQLServerClient{}, - postgreSQLDatabaseManager: &PSQLDatabaseClient{}, - ResourceGroupManager: resourceGroupManager, - timeout: 20 * time.Minute, - retryInterval: 3 * time.Second, - } -}) - -var _ = AfterSuite(func() { - By("tearing down the test environment") - // delete the resource group and contained resources - _, err := tc.ResourceGroupManager.DeleteGroup(ctx, tc.ResourceGroupName) - if !errhelp.IsAsynchronousOperationNotComplete(err) { - - return - } - - for { - time.Sleep(time.Second * 10) - _, err := resourcegroupsresourcemanager.GetGroup(ctx, tc.ResourceGroupName) - if err == nil { - - } else { - if errhelp.IsGroupNotFound(err) { - break - } else { - return - } - } - } -}) diff --git a/pkg/resourcemanager/psql/firewallrule/firewallrule_reconcile.go b/pkg/resourcemanager/psql/firewallrule/firewallrule_reconcile.go index 75cde160be4..bba437cb837 100644 --- a/pkg/resourcemanager/psql/firewallrule/firewallrule_reconcile.go +++ b/pkg/resourcemanager/psql/firewallrule/firewallrule_reconcile.go @@ -96,9 +96,22 @@ func (p *PSQLFirewallRuleClient) Delete(ctx context.Context, obj runtime.Object, status, err := p.DeleteFirewallRule(ctx, instance.Spec.ResourceGroup, instance.Spec.Server, instance.Name) if err != nil { - if !errhelp.IsAsynchronousOperationNotComplete(err) { - return true, err + catch := []string{ + errhelp.AsyncOpIncompleteError, + } + gone := []string{ + errhelp.ResourceGroupNotFoundErrorCode, + errhelp.ParentNotFoundErrorCode, + errhelp.NotFoundErrorCode, + errhelp.ResourceNotFound, } + azerr := errhelp.NewAzureErrorAzureError(err) + if helpers.ContainsString(catch, azerr.Type) { + return true, nil + } else if helpers.ContainsString(gone, azerr.Type) { + return false, nil + } + return true, err } instance.Status.State = status diff --git a/pkg/resourcemanager/psql/server/server_reconcile.go b/pkg/resourcemanager/psql/server/server_reconcile.go index 7b8b7130282..33aeb3d2707 100644 --- a/pkg/resourcemanager/psql/server/server_reconcile.go +++ b/pkg/resourcemanager/psql/server/server_reconcile.go @@ -203,9 +203,22 @@ func (p *PSQLServerClient) Delete(ctx context.Context, obj runtime.Object, opts status, err := p.DeleteServer(ctx, instance.Spec.ResourceGroup, instance.Name) if err != nil { - if !errhelp.IsAsynchronousOperationNotComplete(err) { - return true, err + catch := []string{ + errhelp.AsyncOpIncompleteError, + } + gone := []string{ + errhelp.ResourceGroupNotFoundErrorCode, + errhelp.ParentNotFoundErrorCode, + errhelp.NotFoundErrorCode, + errhelp.ResourceNotFound, } + azerr := errhelp.NewAzureErrorAzureError(err) + if helpers.ContainsString(catch, azerr.Type) { + return true, nil + } else if helpers.ContainsString(gone, azerr.Type) { + return false, nil + } + return true, err } instance.Status.State = status diff --git a/pkg/resourcemanager/storages/storageaccount/storageaccount_reconcile.go b/pkg/resourcemanager/storages/storageaccount/storageaccount_reconcile.go index 1cc88544b34..ca49ebaca28 100644 --- a/pkg/resourcemanager/storages/storageaccount/storageaccount_reconcile.go +++ b/pkg/resourcemanager/storages/storageaccount/storageaccount_reconcile.go @@ -201,11 +201,22 @@ func (sa *azureStorageManager) Delete(ctx context.Context, obj runtime.Object, o _, err = sa.GetStorage(ctx, groupName, name) if err != nil { - if errhelp.IsStatusCode404(err) { - // Best case deletion of secrets - sa.SecretClient.Delete(ctx, key) + catch := []string{ + errhelp.AsyncOpIncompleteError, + } + gone := []string{ + errhelp.ResourceGroupNotFoundErrorCode, + errhelp.ParentNotFoundErrorCode, + errhelp.NotFoundErrorCode, + errhelp.ResourceNotFound, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if helpers.ContainsString(catch, azerr.Type) { + return true, nil + } else if helpers.ContainsString(gone, azerr.Type) { return false, nil } + return true, err } return true, nil } diff --git a/pkg/resourcemanager/vm/reconcile.go b/pkg/resourcemanager/vm/reconcile.go index ec9e5153e76..b5bec8374b0 100644 --- a/pkg/resourcemanager/vm/reconcile.go +++ b/pkg/resourcemanager/vm/reconcile.go @@ -154,9 +154,22 @@ func (g *AzureVirtualMachineClient) Delete(ctx context.Context, obj runtime.Obje resourceGroup, ) if err != nil { - if !errhelp.IsAsynchronousOperationNotComplete(err) { - return true, err + catch := []string{ + errhelp.AsyncOpIncompleteError, + } + gone := []string{ + errhelp.ResourceGroupNotFoundErrorCode, + errhelp.ParentNotFoundErrorCode, + errhelp.NotFoundErrorCode, + errhelp.ResourceNotFound, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if helpers.ContainsString(catch, azerr.Type) { + return true, nil + } else if helpers.ContainsString(gone, azerr.Type) { + return false, nil } + return true, err } if err == nil { diff --git a/pkg/resourcemanager/vmss/reconcile.go b/pkg/resourcemanager/vmss/reconcile.go index 1a44a55eb5c..eb58880f6cf 100644 --- a/pkg/resourcemanager/vmss/reconcile.go +++ b/pkg/resourcemanager/vmss/reconcile.go @@ -165,9 +165,22 @@ func (g *AzureVMScaleSetClient) Delete(ctx context.Context, obj runtime.Object, resourceGroup, ) if err != nil { - if !errhelp.IsAsynchronousOperationNotComplete(err) { - return true, err + catch := []string{ + errhelp.AsyncOpIncompleteError, + } + gone := []string{ + errhelp.ResourceGroupNotFoundErrorCode, + errhelp.ParentNotFoundErrorCode, + errhelp.NotFoundErrorCode, + errhelp.ResourceNotFound, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if helpers.ContainsString(catch, azerr.Type) { + return true, nil + } else if helpers.ContainsString(gone, azerr.Type) { + return false, nil } + return true, err } if err == nil { diff --git a/pkg/resourcemanager/vnet/suite_test.go b/pkg/resourcemanager/vnet/suite_test.go index 1097eae9eb7..2c64216af1e 100644 --- a/pkg/resourcemanager/vnet/suite_test.go +++ b/pkg/resourcemanager/vnet/suite_test.go @@ -83,7 +83,11 @@ var _ = BeforeSuite(func() { var _ = AfterSuite(func() { By("tearing down the test environment") _, err := tc.ResourceGroupManager.DeleteGroup(ctx, tc.ResourceGroupName) - if !errhelp.IsAsynchronousOperationNotComplete(err) { + ignore := []string{ + errhelp.AsyncOpIncompleteError, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if !helpers.ContainsString(ignore, azerr.Type) { log.Println("Delete RG failed") return } @@ -94,7 +98,11 @@ var _ = AfterSuite(func() { if err == nil { log.Println("waiting for resource group to be deleted") } else { - if errhelp.IsGroupNotFound(err) { + catch := []string{ + errhelp.ResourceGroupNotFoundErrorCode, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if helpers.ContainsString(catch, azerr.Type) { log.Println("resource group deleted") break } else { diff --git a/pkg/resourcemanager/vnet/vnet_test.go b/pkg/resourcemanager/vnet/vnet_test.go index 320cff05984..3ec50cc597e 100644 --- a/pkg/resourcemanager/vnet/vnet_test.go +++ b/pkg/resourcemanager/vnet/vnet_test.go @@ -54,7 +54,11 @@ var _ = Describe("VNet", func() { }) if err != nil { fmt.Println(err.Error()) - if !errhelp.IsAsynchronousOperationNotComplete(err) { + ignore := []string{ + errhelp.AsyncOpIncompleteError, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if !helpers.ContainsString(ignore, azerr.Type) { fmt.Println("error occured") return false } @@ -75,7 +79,11 @@ var _ = Describe("VNet", func() { _, err = vnetManager.DeleteVNet(ctx, rgName, vnetName) if err != nil { fmt.Println(err.Error()) - if !errhelp.IsAsynchronousOperationNotComplete(err) { + ignore := []string{ + errhelp.AsyncOpIncompleteError, + } + azerr := errhelp.NewAzureErrorAzureError(err) + if !helpers.ContainsString(ignore, azerr.Type) { fmt.Println("error occured") return false }