diff --git a/cloud/azure/actuators/cluster/clusteractuator.go b/cloud/azure/actuators/cluster/clusteractuator.go index 36c0e85643c1..15ef6075f269 100644 --- a/cloud/azure/actuators/cluster/clusteractuator.go +++ b/cloud/azure/actuators/cluster/clusteractuator.go @@ -25,6 +25,7 @@ import ( azureconfigv1 "github.com/platform9/azure-provider/cloud/azure/providerconfig/v1alpha1" "github.com/platform9/azure-provider/cloud/azure/services" "github.com/platform9/azure-provider/cloud/azure/services/network" + "github.com/platform9/azure-provider/cloud/azure/services/resourcemanagement" clusterv1 "sigs.k8s.io/cluster-api/pkg/apis/cluster/v1alpha1" client "sigs.k8s.io/cluster-api/pkg/client/clientset_generated/clientset/typed/cluster/v1alpha1" ) @@ -64,6 +65,12 @@ func (azure *AzureClusterClient) Reconcile(cluster *clusterv1.Cluster) error { if err != nil { return fmt.Errorf("error loading cluster provider config: %v", err) } + + _, err = azure.resourcemanagement().CreateOrUpdateGroup(clusterConfig.ResourceGroup, clusterConfig.Location) + if err != nil { + return fmt.Errorf("failed to create or update resource group: %v", err) + } + networkSGFuture, err := azure.network().CreateOrUpdateNetworkSecurityGroup(clusterConfig.ResourceGroup, "ClusterAPINSG", clusterConfig.Location) if err != nil { return fmt.Errorf("error creating or updating network security group: %v", err) @@ -107,11 +114,18 @@ func azureServicesClientOrDefault(params ClusterActuatorParams) (*services.Azure } azureNetworkClient := network.NewService(subscriptionID) azureNetworkClient.SetAuthorizer(authorizer) + azureResourceManagementClient := resourcemanagement.NewService(subscriptionID) + azureResourceManagementClient.SetAuthorizer(authorizer) return &services.AzureClients{ - Network: azureNetworkClient, + Network: azureNetworkClient, + Resourcemanagement: azureResourceManagementClient, }, nil } func (azure *AzureClusterClient) network() services.AzureNetworkClient { return azure.services.Network } + +func (azure *AzureClusterClient) resourcemanagement() services.AzureResourceManagementClient { + return azure.services.Resourcemanagement +} diff --git a/cloud/azure/actuators/cluster/clusteractuator_test.go b/cloud/azure/actuators/cluster/clusteractuator_test.go index 6de27b06c18f..1c26e91ebf15 100644 --- a/cloud/azure/actuators/cluster/clusteractuator_test.go +++ b/cloud/azure/actuators/cluster/clusteractuator_test.go @@ -37,7 +37,7 @@ func TestActuatorCreateSuccess(t *testing.T) { } func TestReconcileSuccess(t *testing.T) { - azureServicesClient := mockSGCreateSuccess() + azureServicesClient := mockReconcileSuccess() params := ClusterActuatorParams{Services: &azureServicesClient} cluster := newCluster(t) @@ -51,7 +51,7 @@ func TestReconcileSuccess(t *testing.T) { } } func TestReconcileFailure(t *testing.T) { - azureServicesClient := mockSGCreateFailure() + azureServicesClient := mockReconcileFailure() params := ClusterActuatorParams{Services: &azureServicesClient} cluster := newCluster(t) @@ -65,28 +65,28 @@ func TestReconcileFailure(t *testing.T) { } } -func mockSGCreateSuccess() services.AzureClients { +func mockReconcileSuccess() services.AzureClients { networkMock := services.MockAzureNetworkClient{ MockCreateOrUpdateNetworkSecurityGroup: func(resourceGroupName string, networkSecurityGroupName string, location string) (*network.SecurityGroupsCreateOrUpdateFuture, error) { return &network.SecurityGroupsCreateOrUpdateFuture{}, nil }, } - return services.AzureClients{Network: &networkMock} + return services.AzureClients{Resourcemanagement: &services.MockAzureResourceManagementClient{}, Network: &networkMock} } -func mockSGCreateFailure() services.AzureClients { +func mockReconcileFailure() services.AzureClients { networkMock := services.MockAzureNetworkClient{ MockCreateOrUpdateNetworkSecurityGroup: func(resourceGroupName string, networkSecurityGroupName string, location string) (*network.SecurityGroupsCreateOrUpdateFuture, error) { return nil, errors.New("failed to create resource") }, } - return services.AzureClients{Network: &networkMock} + return services.AzureClients{Resourcemanagement: &services.MockAzureResourceManagementClient{}, Network: &networkMock} } func newClusterProviderConfig() azureconfigv1.AzureClusterProviderConfig { return azureconfigv1.AzureClusterProviderConfig{ ResourceGroup: "resource-group-test", - Location: "southcentralus", + Location: "westus2", } } diff --git a/cloud/azure/actuators/machine/machineactuator.go b/cloud/azure/actuators/machine/machineactuator.go index a8528a37e066..f62b2740b7e6 100644 --- a/cloud/azure/actuators/machine/machineactuator.go +++ b/cloud/azure/actuators/machine/machineactuator.go @@ -121,10 +121,6 @@ func (azure *AzureClient) Create(cluster *clusterv1.Cluster, machine *clusterv1. if err != nil { return err } - _, err = azure.createOrUpdateGroup(cluster) - if err != nil { - return err - } _, err = azure.createOrUpdateDeployment(cluster, machine) if err != nil { return err diff --git a/cloud/azure/services/interfaces.go b/cloud/azure/services/interfaces.go index 2696d8a8115a..2dabf97a4389 100644 --- a/cloud/azure/services/interfaces.go +++ b/cloud/azure/services/interfaces.go @@ -14,11 +14,14 @@ package services import ( "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network" + "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources" + "github.com/Azure/go-autorest/autorest" ) // interface for all azure services clients type AzureClients struct { - Network AzureNetworkClient + Network AzureNetworkClient + Resourcemanagement AzureResourceManagementClient } type AzureNetworkClient interface { @@ -27,3 +30,11 @@ type AzureNetworkClient interface { NetworkSGIfExists(resourceGroupName string, networkSecurityGroupName string) (*network.SecurityGroup, error) WaitForNetworkSGsCreateOrUpdateFuture(future network.SecurityGroupsCreateOrUpdateFuture) error } + +type AzureResourceManagementClient interface { + // Resource Groups Operations + CreateOrUpdateGroup(resourceGroupName string, location string) (resources.Group, error) + DeleteGroup(resourceGroupName string) (resources.GroupsDeleteFuture, error) + CheckGroupExistence(rgName string) (autorest.Response, error) + WaitForGroupsFuture(future resources.GroupsDeleteFuture) error +} diff --git a/cloud/azure/services/mock_interfaces.go b/cloud/azure/services/mock_interfaces.go index 8761d3eec549..21fe3bbe699b 100644 --- a/cloud/azure/services/mock_interfaces.go +++ b/cloud/azure/services/mock_interfaces.go @@ -12,13 +12,23 @@ limitations under the License. */ package services -import "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network" +import ( + "github.com/Azure/azure-sdk-for-go/services/network/mgmt/2018-01-01/network" + "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources" + "github.com/Azure/go-autorest/autorest" +) type MockAzureNetworkClient struct { MockCreateOrUpdateNetworkSecurityGroup func(resourceGroupName string, networkSecurityGroupName string, location string) (*network.SecurityGroupsCreateOrUpdateFuture, error) MockNetworkSGIfExists func(resourceGroupName string, networkSecurityGroupName string) (*network.SecurityGroup, error) MockWaitForNetworkSGsCreateOrUpdateFuture func(future network.SecurityGroupsCreateOrUpdateFuture) error } +type MockAzureResourceManagementClient struct { + MockCreateOrUpdateGroup func(resourceGroupName string, location string) (resources.Group, error) + MockDeleteGroup func(resourceGroupName string) (resources.GroupsDeleteFuture, error) + MockCheckGroupExistence func(rgName string) (autorest.Response, error) + MockWaitForGroupsFuture func(future resources.GroupsDeleteFuture) error +} func (m *MockAzureNetworkClient) CreateOrUpdateNetworkSecurityGroup(resourceGroupName string, networkSecurityGroupName string, location string) (*network.SecurityGroupsCreateOrUpdateFuture, error) { if m.MockCreateOrUpdateNetworkSecurityGroup == nil { @@ -40,3 +50,31 @@ func (m *MockAzureNetworkClient) WaitForNetworkSGsCreateOrUpdateFuture(future ne } return m.MockWaitForNetworkSGsCreateOrUpdateFuture(future) } + +func (m *MockAzureResourceManagementClient) CreateOrUpdateGroup(resourceGroupName string, location string) (resources.Group, error) { + if m.MockCreateOrUpdateGroup == nil { + return resources.Group{}, nil + } + return m.MockCreateOrUpdateGroup(resourceGroupName, location) +} + +func (m *MockAzureResourceManagementClient) DeleteGroup(resourceGroupName string) (resources.GroupsDeleteFuture, error) { + if m.MockDeleteGroup == nil { + return resources.GroupsDeleteFuture{}, nil + } + return m.MockDeleteGroup(resourceGroupName) +} + +func (m *MockAzureResourceManagementClient) CheckGroupExistence(rgName string) (autorest.Response, error) { + if m.MockCheckGroupExistence == nil { + return autorest.Response{}, nil + } + return m.MockCheckGroupExistence(rgName) +} + +func (m *MockAzureResourceManagementClient) WaitForGroupsFuture(future resources.GroupsDeleteFuture) error { + if m.MockWaitForGroupsFuture == nil { + return nil + } + return m.MockWaitForGroupsFuture(future) +} diff --git a/cloud/azure/services/resourcemanagement/groups.go b/cloud/azure/services/resourcemanagement/groups.go new file mode 100644 index 000000000000..a0cb33674910 --- /dev/null +++ b/cloud/azure/services/resourcemanagement/groups.go @@ -0,0 +1,23 @@ +package resourcemanagement + +import ( + "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/to" +) + +func (s *Service) CreateOrUpdateGroup(resourceGroupName string, location string) (resources.Group, error) { + return s.GroupsClient.CreateOrUpdate(s.ctx, resourceGroupName, resources.Group{Location: to.StringPtr(location)}) +} + +func (s *Service) DeleteGroup(resourceGroupName string) (resources.GroupsDeleteFuture, error) { + return s.GroupsClient.Delete(s.ctx, resourceGroupName) +} + +func (s *Service) CheckGroupExistence(resourceGroupName string) (autorest.Response, error) { + return s.GroupsClient.CheckExistence(s.ctx, resourceGroupName) +} + +func (s *Service) WaitForGroupsFuture(future resources.GroupsDeleteFuture) error { + return future.WaitForCompletionRef(s.ctx, s.GroupsClient.Client) +} diff --git a/cloud/azure/services/resourcemanagement/service.go b/cloud/azure/services/resourcemanagement/service.go new file mode 100644 index 000000000000..f895cbd3b33f --- /dev/null +++ b/cloud/azure/services/resourcemanagement/service.go @@ -0,0 +1,24 @@ +package resourcemanagement + +import ( + "context" + + "github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2018-02-01/resources" + "github.com/Azure/go-autorest/autorest" +) + +type Service struct { + GroupsClient resources.GroupsClient + ctx context.Context +} + +func NewService(subscriptionId string) *Service { + return &Service{ + GroupsClient: resources.NewGroupsClient(subscriptionId), + ctx: context.Background(), + } +} + +func (s *Service) SetAuthorizer(authorizer autorest.Authorizer) { + s.GroupsClient.BaseClient.Client.Authorizer = authorizer +}