From a46aec97166fe4e11c6dcc182a3d96bdf37b173b Mon Sep 17 00:00:00 2001 From: Date: Thu, 31 Aug 2017 04:06:21 +0530 Subject: [PATCH 01/20] Added outline for container group resource. --- azurerm/config.go | 8 + azurerm/provider.go | 2 + azurerm/resource_arm_container_group.go | 44 ++ .../arm/containerinstance/client.go | 51 ++ .../arm/containerinstance/containergroups.go | 512 ++++++++++++++++++ .../arm/containerinstance/containerlogs.go | 109 ++++ .../arm/containerinstance/models.go | 223 ++++++++ .../arm/containerinstance/version.go | 28 + vendor/vendor.json | 8 + 9 files changed, 985 insertions(+) create mode 100644 azurerm/resource_arm_container_group.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/arm/containerinstance/client.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/arm/containerinstance/containergroups.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/arm/containerinstance/containerlogs.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/arm/containerinstance/models.go create mode 100644 vendor/github.com/Azure/azure-sdk-for-go/arm/containerinstance/version.go diff --git a/azurerm/config.go b/azurerm/config.go index 97da789255df..27a13a4fc491 100644 --- a/azurerm/config.go +++ b/azurerm/config.go @@ -10,6 +10,7 @@ import ( "github.com/Azure/azure-sdk-for-go/arm/appinsights" "github.com/Azure/azure-sdk-for-go/arm/cdn" "github.com/Azure/azure-sdk-for-go/arm/compute" + "github.com/Azure/azure-sdk-for-go/arm/containerinstance" "github.com/Azure/azure-sdk-for-go/arm/containerregistry" "github.com/Azure/azure-sdk-for-go/arm/containerservice" "github.com/Azure/azure-sdk-for-go/arm/cosmos-db" @@ -83,6 +84,7 @@ type ArmClient struct { containerRegistryClient containerregistry.RegistriesClient containerServicesClient containerservice.ContainerServicesClient + containerGroupsClient containerinstance.ContainerGroupsClient eventGridTopicsClient eventgrid.TopicsClient eventHubClient eventhub.EventHubsClient @@ -277,6 +279,12 @@ func (c *Config) getArmClient() (*ArmClient, error) { csc.Sender = autorest.CreateSender(withRequestLogging()) client.containerServicesClient = csc + cgc := containerinstance.NewContainerGroupsClientWithBaseURI(endpoint, c.SubscriptionID) + setUserAgent(&cgc.Client) + cgc.Authorizer = auth + cgc.Sender = autorest.CreateSender(withRequestLogging()) + client.containerGroupsClient = cgc + cdb := cosmosdb.NewDatabaseAccountsClientWithBaseURI(endpoint, c.SubscriptionID) setUserAgent(&cdb.Client) cdb.Authorizer = auth diff --git a/azurerm/provider.go b/azurerm/provider.go index a7a0acb69aab..98a8080a8dd9 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -76,6 +76,7 @@ func Provider() terraform.ResourceProvider { "azurerm_cdn_profile": resourceArmCdnProfile(), "azurerm_container_registry": resourceArmContainerRegistry(), "azurerm_container_service": resourceArmContainerService(), + "azurerm_container_group": resourceArmContainerGroup(), "azurerm_cosmosdb_account": resourceArmCosmosDBAccount(), "azurerm_dns_a_record": resourceArmDnsARecord(), @@ -261,6 +262,7 @@ func registerAzureResourceProvidersWithSubscription(providerList []resources.Pro "Microsoft.Compute": struct{}{}, "Microsoft.ContainerRegistry": struct{}{}, "Microsoft.ContainerService": struct{}{}, + "Microsoft.ContainerInstance": struct{}{}, "Microsoft.DocumentDB": struct{}{}, "Microsoft.EventGrid": struct{}{}, "Microsoft.EventHub": struct{}{}, diff --git a/azurerm/resource_arm_container_group.go b/azurerm/resource_arm_container_group.go new file mode 100644 index 000000000000..f124f54787a7 --- /dev/null +++ b/azurerm/resource_arm_container_group.go @@ -0,0 +1,44 @@ +package azurerm + +import "github.com/hashicorp/terraform/helper/schema" + +func resourceArmContainerGroup() *schema.Resource { + return &schema.Resource{ + Create: resourceArmContainerGroupCreate, + Read: resourceArmContainerGroupRead, + Update: resourceArmContainerGroupCreate, + Delete: resourceArmContainerGroupDelete, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "location": locationSchema(), + + "resource_group_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "tags": tagsSchema(), + }, + } +} + +func resourceArmContainerGroupCreate(d *schema.ResourceData, meta interface{}) error { + //client := meta.(*ArmClient) + //containterGroupsClient := client.containerGroupsClient + + //containterGroupsClient.CreateOrUpdate() + return nil +} +func resourceArmContainerGroupRead(d *schema.ResourceData, meta interface{}) error { + return nil +} +func resourceArmContainerGroupDelete(d *schema.ResourceData, meta interface{}) error { + return nil +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/containerinstance/client.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/containerinstance/client.go new file mode 100644 index 000000000000..8428722c57b1 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/containerinstance/client.go @@ -0,0 +1,51 @@ +// Package containerinstance implements the Azure ARM Containerinstance service API version 2017-08-01-preview. +// +// +package containerinstance + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 1.2.2.0 +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" +) + +const ( + // DefaultBaseURI is the default URI used for the service Containerinstance + DefaultBaseURI = "https://management.azure.com" +) + +// ManagementClient is the base client for Containerinstance. +type ManagementClient struct { + autorest.Client + BaseURI string + SubscriptionID string +} + +// New creates an instance of the ManagementClient client. +func New(subscriptionID string) ManagementClient { + return NewWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewWithBaseURI creates an instance of the ManagementClient client. +func NewWithBaseURI(baseURI string, subscriptionID string) ManagementClient { + return ManagementClient{ + Client: autorest.NewClientWithUserAgent(UserAgent()), + BaseURI: baseURI, + SubscriptionID: subscriptionID, + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/containerinstance/containergroups.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/containerinstance/containergroups.go new file mode 100644 index 000000000000..0396dac00950 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/containerinstance/containergroups.go @@ -0,0 +1,512 @@ +package containerinstance + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 1.2.2.0 +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "net/http" +) + +// ContainerGroupsClient is the client for the ContainerGroups methods of the Containerinstance service. +type ContainerGroupsClient struct { + ManagementClient +} + +// NewContainerGroupsClient creates an instance of the ContainerGroupsClient client. +func NewContainerGroupsClient(subscriptionID string) ContainerGroupsClient { + return NewContainerGroupsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewContainerGroupsClientWithBaseURI creates an instance of the ContainerGroupsClient client. +func NewContainerGroupsClientWithBaseURI(baseURI string, subscriptionID string) ContainerGroupsClient { + return ContainerGroupsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// CreateOrUpdate create or update container groups. +// +// resourceGroupName is azure resource group name containerGroupName is container group name containerGroup is +// definition of the container to be created. +func (client ContainerGroupsClient) CreateOrUpdate(resourceGroupName string, containerGroupName string, containerGroup ContainerGroup) (result ContainerGroup, err error) { + if err := validation.Validate([]validation.Validation{ + {TargetValue: containerGroup, + Constraints: []validation.Constraint{{Target: "containerGroup.ContainerGroupProperties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "containerGroup.ContainerGroupProperties.IPAddress", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "containerGroup.ContainerGroupProperties.IPAddress.Ports", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "containerGroup.ContainerGroupProperties.IPAddress.Type", Name: validation.Null, Rule: true, Chain: nil}, + }}, + }}}}}); err != nil { + return result, validation.NewErrorWithValidationError(err, "containerinstance.ContainerGroupsClient", "CreateOrUpdate") + } + + req, err := client.CreateOrUpdatePreparer(resourceGroupName, containerGroupName, containerGroup) + if err != nil { + err = autorest.NewErrorWithError(err, "containerinstance.ContainerGroupsClient", "CreateOrUpdate", nil, "Failure preparing request") + return + } + + resp, err := client.CreateOrUpdateSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "containerinstance.ContainerGroupsClient", "CreateOrUpdate", resp, "Failure sending request") + return + } + + result, err = client.CreateOrUpdateResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "containerinstance.ContainerGroupsClient", "CreateOrUpdate", resp, "Failure responding to request") + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client ContainerGroupsClient) CreateOrUpdatePreparer(resourceGroupName string, containerGroupName string, containerGroup ContainerGroup) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "containerGroupName": autorest.Encode("path", containerGroupName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsJSON(), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ContainerInstance/containerGroups/{containerGroupName}", pathParameters), + autorest.WithJSON(containerGroup), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client ContainerGroupsClient) CreateOrUpdateSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client ContainerGroupsClient) CreateOrUpdateResponder(resp *http.Response) (result ContainerGroup, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete delete container groups. +// +// resourceGroupName is azure resource group name containerGroupName is name of the container group to be deleted +func (client ContainerGroupsClient) Delete(resourceGroupName string, containerGroupName string) (result ContainerGroup, err error) { + req, err := client.DeletePreparer(resourceGroupName, containerGroupName) + if err != nil { + err = autorest.NewErrorWithError(err, "containerinstance.ContainerGroupsClient", "Delete", nil, "Failure preparing request") + return + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "containerinstance.ContainerGroupsClient", "Delete", resp, "Failure sending request") + return + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "containerinstance.ContainerGroupsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client ContainerGroupsClient) DeletePreparer(resourceGroupName string, containerGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "containerGroupName": autorest.Encode("path", containerGroupName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ContainerInstance/containerGroups/{containerGroupName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client ContainerGroupsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client ContainerGroupsClient) DeleteResponder(resp *http.Response) (result ContainerGroup, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Get get details for this container group. +// +// resourceGroupName is azure resource group name containerGroupName is container group name +func (client ContainerGroupsClient) Get(resourceGroupName string, containerGroupName string) (result ContainerGroup, err error) { + req, err := client.GetPreparer(resourceGroupName, containerGroupName) + if err != nil { + err = autorest.NewErrorWithError(err, "containerinstance.ContainerGroupsClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "containerinstance.ContainerGroupsClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "containerinstance.ContainerGroupsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client ContainerGroupsClient) GetPreparer(resourceGroupName string, containerGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "containerGroupName": autorest.Encode("path", containerGroupName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ContainerInstance/containerGroups/{containerGroupName}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client ContainerGroupsClient) GetSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client ContainerGroupsClient) GetResponder(resp *http.Response) (result ContainerGroup, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List get the list of container groups in a given subscription. +func (client ContainerGroupsClient) List() (result ContainerGroupListResult, err error) { + req, err := client.ListPreparer() + if err != nil { + err = autorest.NewErrorWithError(err, "containerinstance.ContainerGroupsClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "containerinstance.ContainerGroupsClient", "List", resp, "Failure sending request") + return + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "containerinstance.ContainerGroupsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client ContainerGroupsClient) ListPreparer() (*http.Request, error) { + pathParameters := map[string]interface{}{ + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/providers/Microsoft.ContainerInstance/containerGroups", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client ContainerGroupsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client ContainerGroupsClient) ListResponder(resp *http.Response) (result ContainerGroupListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListNextResults retrieves the next set of results, if any. +func (client ContainerGroupsClient) ListNextResults(lastResults ContainerGroupListResult) (result ContainerGroupListResult, err error) { + req, err := lastResults.ContainerGroupListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "containerinstance.ContainerGroupsClient", "List", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "containerinstance.ContainerGroupsClient", "List", resp, "Failure sending next results request") + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "containerinstance.ContainerGroupsClient", "List", resp, "Failure responding to next results request") + } + + return +} + +// ListComplete gets all elements from the list without paging. +func (client ContainerGroupsClient) ListComplete(cancel <-chan struct{}) (<-chan ContainerGroup, <-chan error) { + resultChan := make(chan ContainerGroup) + errChan := make(chan error, 1) + go func() { + defer func() { + close(resultChan) + close(errChan) + }() + list, err := client.List() + if err != nil { + errChan <- err + return + } + if list.Value != nil { + for _, item := range *list.Value { + select { + case <-cancel: + return + case resultChan <- item: + // Intentionally left blank + } + } + } + for list.NextLink != nil { + list, err = client.ListNextResults(list) + if err != nil { + errChan <- err + return + } + if list.Value != nil { + for _, item := range *list.Value { + select { + case <-cancel: + return + case resultChan <- item: + // Intentionally left blank + } + } + } + } + }() + return resultChan, errChan +} + +// ListByResourceGroup get the list of container groups in a given resource group. +// +// resourceGroupName is azure resource group name +func (client ContainerGroupsClient) ListByResourceGroup(resourceGroupName string) (result ContainerGroupListResult, err error) { + req, err := client.ListByResourceGroupPreparer(resourceGroupName) + if err != nil { + err = autorest.NewErrorWithError(err, "containerinstance.ContainerGroupsClient", "ListByResourceGroup", nil, "Failure preparing request") + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "containerinstance.ContainerGroupsClient", "ListByResourceGroup", resp, "Failure sending request") + return + } + + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "containerinstance.ContainerGroupsClient", "ListByResourceGroup", resp, "Failure responding to request") + } + + return +} + +// ListByResourceGroupPreparer prepares the ListByResourceGroup request. +func (client ContainerGroupsClient) ListByResourceGroupPreparer(resourceGroupName string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ContainerInstance/containerGroups", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListByResourceGroupSender sends the ListByResourceGroup request. The method will close the +// http.Response Body if it receives an error. +func (client ContainerGroupsClient) ListByResourceGroupSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListByResourceGroupResponder handles the response to the ListByResourceGroup request. The method always +// closes the http.Response Body. +func (client ContainerGroupsClient) ListByResourceGroupResponder(resp *http.Response) (result ContainerGroupListResult, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// ListByResourceGroupNextResults retrieves the next set of results, if any. +func (client ContainerGroupsClient) ListByResourceGroupNextResults(lastResults ContainerGroupListResult) (result ContainerGroupListResult, err error) { + req, err := lastResults.ContainerGroupListResultPreparer() + if err != nil { + return result, autorest.NewErrorWithError(err, "containerinstance.ContainerGroupsClient", "ListByResourceGroup", nil, "Failure preparing next results request") + } + if req == nil { + return + } + + resp, err := client.ListByResourceGroupSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "containerinstance.ContainerGroupsClient", "ListByResourceGroup", resp, "Failure sending next results request") + } + + result, err = client.ListByResourceGroupResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "containerinstance.ContainerGroupsClient", "ListByResourceGroup", resp, "Failure responding to next results request") + } + + return +} + +// ListByResourceGroupComplete gets all elements from the list without paging. +func (client ContainerGroupsClient) ListByResourceGroupComplete(resourceGroupName string, cancel <-chan struct{}) (<-chan ContainerGroup, <-chan error) { + resultChan := make(chan ContainerGroup) + errChan := make(chan error, 1) + go func() { + defer func() { + close(resultChan) + close(errChan) + }() + list, err := client.ListByResourceGroup(resourceGroupName) + if err != nil { + errChan <- err + return + } + if list.Value != nil { + for _, item := range *list.Value { + select { + case <-cancel: + return + case resultChan <- item: + // Intentionally left blank + } + } + } + for list.NextLink != nil { + list, err = client.ListByResourceGroupNextResults(list) + if err != nil { + errChan <- err + return + } + if list.Value != nil { + for _, item := range *list.Value { + select { + case <-cancel: + return + case resultChan <- item: + // Intentionally left blank + } + } + } + } + }() + return resultChan, errChan +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/containerinstance/containerlogs.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/containerinstance/containerlogs.go new file mode 100644 index 000000000000..c11264b1800b --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/containerinstance/containerlogs.go @@ -0,0 +1,109 @@ +package containerinstance + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 1.2.2.0 +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "net/http" +) + +// ContainerLogsClient is the client for the ContainerLogs methods of the Containerinstance service. +type ContainerLogsClient struct { + ManagementClient +} + +// NewContainerLogsClient creates an instance of the ContainerLogsClient client. +func NewContainerLogsClient(subscriptionID string) ContainerLogsClient { + return NewContainerLogsClientWithBaseURI(DefaultBaseURI, subscriptionID) +} + +// NewContainerLogsClientWithBaseURI creates an instance of the ContainerLogsClient client. +func NewContainerLogsClientWithBaseURI(baseURI string, subscriptionID string) ContainerLogsClient { + return ContainerLogsClient{NewWithBaseURI(baseURI, subscriptionID)} +} + +// List get the logs for this container. +// +// resourceGroupName is azure resource group name containerName is container name containerGroupName is container group +// name tail is only show this number of log lines. If not provided, all available logs are shown. +func (client ContainerLogsClient) List(resourceGroupName string, containerName string, containerGroupName string, tail *int32) (result Logs, err error) { + req, err := client.ListPreparer(resourceGroupName, containerName, containerGroupName, tail) + if err != nil { + err = autorest.NewErrorWithError(err, "containerinstance.ContainerLogsClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "containerinstance.ContainerLogsClient", "List", resp, "Failure sending request") + return + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "containerinstance.ContainerLogsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client ContainerLogsClient) ListPreparer(resourceGroupName string, containerName string, containerGroupName string, tail *int32) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "containerGroupName": autorest.Encode("path", containerGroupName), + "containerName": autorest.Encode("path", containerName), + "resourceGroupName": autorest.Encode("path", resourceGroupName), + "subscriptionId": autorest.Encode("path", client.SubscriptionID), + } + + const APIVersion = "2017-08-01-preview" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if tail != nil { + queryParameters["tail"] = autorest.Encode("query", *tail) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.ContainerInstance/containerGroups/{containerGroupName}/containers/{containerName}/logs", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare(&http.Request{}) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client ContainerLogsClient) ListSender(req *http.Request) (*http.Response, error) { + return autorest.SendWithSender(client, req) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client ContainerLogsClient) ListResponder(resp *http.Response) (result Logs, err error) { + err = autorest.Respond( + resp, + client.ByInspecting(), + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/containerinstance/models.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/containerinstance/models.go new file mode 100644 index 000000000000..51aea50b0eb8 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/containerinstance/models.go @@ -0,0 +1,223 @@ +package containerinstance + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 1.2.2.0 +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/date" + "github.com/Azure/go-autorest/autorest/to" + "net/http" +) + +// ContainerGroupNetworkProtocol enumerates the values for container group network protocol. +type ContainerGroupNetworkProtocol string + +const ( + // TCP specifies the tcp state for container group network protocol. + TCP ContainerGroupNetworkProtocol = "TCP" + // UDP specifies the udp state for container group network protocol. + UDP ContainerGroupNetworkProtocol = "UDP" +) + +// ContainerRestartPolicy enumerates the values for container restart policy. +type ContainerRestartPolicy string + +const ( + // Always specifies the always state for container restart policy. + Always ContainerRestartPolicy = "always" +) + +// OperatingSystemTypes enumerates the values for operating system types. +type OperatingSystemTypes string + +const ( + // Linux specifies the linux state for operating system types. + Linux OperatingSystemTypes = "Linux" + // Windows specifies the windows state for operating system types. + Windows OperatingSystemTypes = "Windows" +) + +// AzureFileVolume is the Azure file volume. +type AzureFileVolume struct { + ShareName *string `json:"shareName,omitempty"` + ReadOnly *bool `json:"readOnly,omitempty"` + StorageAccountName *string `json:"storageAccountName,omitempty"` + StorageAccountKey *string `json:"storageAccountKey,omitempty"` +} + +// Container is a container instance. +type Container struct { + Name *string `json:"name,omitempty"` + *ContainerProperties `json:"properties,omitempty"` +} + +// ContainerEvent is a container event. +type ContainerEvent struct { + Count *int32 `json:"count,omitempty"` + FirstTimestamp *date.Time `json:"firstTimestamp,omitempty"` + LastTimestamp *date.Time `json:"lastTimestamp,omitempty"` + Message *string `json:"message,omitempty"` + Type *string `json:"type,omitempty"` +} + +// ContainerGroup is a container group. +type ContainerGroup struct { + autorest.Response `json:"-"` + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` + *ContainerGroupProperties `json:"properties,omitempty"` +} + +// ContainerGroupProperties is +type ContainerGroupProperties struct { + ProvisioningState *string `json:"provisioningState,omitempty"` + Containers *[]Container `json:"containers,omitempty"` + ImageRegistryCredentials *[]ImageRegistryCredential `json:"imageRegistryCredentials,omitempty"` + RestartPolicy ContainerRestartPolicy `json:"restartPolicy,omitempty"` + IPAddress *IPAddress `json:"ipAddress,omitempty"` + OsType OperatingSystemTypes `json:"osType,omitempty"` + State *string `json:"state,omitempty"` + Volumes *[]Volume `json:"volumes,omitempty"` +} + +// ContainerGroupListResult is the container group list response that contains the container group properties. +type ContainerGroupListResult struct { + autorest.Response `json:"-"` + Value *[]ContainerGroup `json:"value,omitempty"` + NextLink *string `json:"nextLink,omitempty"` +} + +// ContainerGroupListResultPreparer prepares a request to retrieve the next set of results. It returns +// nil if no more results exist. +func (client ContainerGroupListResult) ContainerGroupListResultPreparer() (*http.Request, error) { + if client.NextLink == nil || len(to.String(client.NextLink)) <= 0 { + return nil, nil + } + return autorest.Prepare(&http.Request{}, + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(client.NextLink))) +} + +// ContainerPort is the container port. +type ContainerPort struct { + Port *int32 `json:"port,omitempty"` +} + +// ContainerProperties is the container properties. +type ContainerProperties struct { + Image *string `json:"image,omitempty"` + Command *[]string `json:"command,omitempty"` + Ports *[]ContainerPort `json:"ports,omitempty"` + EnvironmentVariables *[]EnvironmentVariable `json:"environmentVariables,omitempty"` + InstanceView *ContainerPropertiesInstanceView `json:"instanceView,omitempty"` + Resources *ResourceRequirements `json:"resources,omitempty"` + VolumeMounts *[]VolumeMount `json:"volumeMounts,omitempty"` +} + +// ContainerPropertiesInstanceView is the instance view of the container. Only valid in response. +type ContainerPropertiesInstanceView struct { + RestartCount *int32 `json:"restartCount,omitempty"` + CurrentState *ContainerState `json:"currentState,omitempty"` + PreviousState *ContainerState `json:"previousState,omitempty"` + Events *[]ContainerEvent `json:"events,omitempty"` +} + +// ContainerState is the container state. +type ContainerState struct { + State *string `json:"state,omitempty"` + StartTime *date.Time `json:"startTime,omitempty"` + ExitCode *int32 `json:"exitCode,omitempty"` + FinishTime *date.Time `json:"finishTime,omitempty"` + DetailStatus *string `json:"detailStatus,omitempty"` +} + +// EnvironmentVariable is environment variable to set within the container. +type EnvironmentVariable struct { + Name *string `json:"name,omitempty"` + Value *string `json:"value,omitempty"` +} + +// ImageRegistryCredential is image registry credential. +type ImageRegistryCredential struct { + Server *string `json:"server,omitempty"` + Username *string `json:"username,omitempty"` + Password *string `json:"password,omitempty"` +} + +// IPAddress is IP address for the group. +type IPAddress struct { + Ports *[]Port `json:"ports,omitempty"` + Type *string `json:"type,omitempty"` + IP *string `json:"ip,omitempty"` +} + +// Logs is the logs. +type Logs struct { + autorest.Response `json:"-"` + Content *string `json:"content,omitempty"` +} + +// Port is the port. +type Port struct { + Protocol ContainerGroupNetworkProtocol `json:"protocol,omitempty"` + Port *int32 `json:"port,omitempty"` +} + +// Resource is the Resource model definition. +type Resource struct { + ID *string `json:"id,omitempty"` + Name *string `json:"name,omitempty"` + Type *string `json:"type,omitempty"` + Location *string `json:"location,omitempty"` + Tags *map[string]*string `json:"tags,omitempty"` +} + +// ResourceLimits is the resource limits. +type ResourceLimits struct { + MemoryInGB *float64 `json:"memoryInGB,omitempty"` + CPU *float64 `json:"cpu,omitempty"` +} + +// ResourceRequests is the resource requests. +type ResourceRequests struct { + MemoryInGB *float64 `json:"memoryInGB,omitempty"` + CPU *float64 `json:"cpu,omitempty"` +} + +// ResourceRequirements is the resource requirements. +type ResourceRequirements struct { + Requests *ResourceRequests `json:"requests,omitempty"` + Limits *ResourceLimits `json:"limits,omitempty"` +} + +// Volume is the volume. +type Volume struct { + Name *string `json:"name,omitempty"` + AzureFile *AzureFileVolume `json:"azureFile,omitempty"` +} + +// VolumeMount is the volume mount. +type VolumeMount struct { + Name *string `json:"name,omitempty"` + MountPath *string `json:"mountPath,omitempty"` + ReadOnly *bool `json:"readOnly,omitempty"` +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/arm/containerinstance/version.go b/vendor/github.com/Azure/azure-sdk-for-go/arm/containerinstance/version.go new file mode 100644 index 000000000000..227dd95f5945 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/arm/containerinstance/version.go @@ -0,0 +1,28 @@ +package containerinstance + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator 1.2.2.0 +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// UserAgent returns the UserAgent string to use when sending http.Requests. +func UserAgent() string { + return "Azure-SDK-For-Go/v10.3.0-beta arm-containerinstance/2017-08-01-preview" +} + +// Version returns the semantic version (see http://semver.org) of the client. +func Version() string { + return "v10.3.0-beta" +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 2400acf7adee..26a92ebfb882 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -26,6 +26,14 @@ "version": "=v10.3.0-beta", "versionExact": "v10.3.0-beta" }, + { + "checksumSHA1": "MqsrM6ecN0KvCc15+F0asFR34/I=", + "path": "github.com/Azure/azure-sdk-for-go/arm/containerinstance", + "revision": "57db66900881e9fd21fd041a9d013514700ecab3", + "revisionTime": "2017-08-18T20:19:01Z", + "version": "v10.3.0-beta", + "versionExact": "v10.3.0-beta" + }, { "checksumSHA1": "chn3haEbJWbCx0yBkusQ6SGiURg=", "path": "github.com/Azure/azure-sdk-for-go/arm/containerregistry", From 2226646aa87d115d07059c6f944d49633854bd01 Mon Sep 17 00:00:00 2001 From: Abhijeet Gaiha Date: Mon, 4 Sep 2017 02:07:16 +0530 Subject: [PATCH 02/20] WIP: Container group resource --- azurerm/resource_arm_container_group.go | 92 +++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 4 deletions(-) diff --git a/azurerm/resource_arm_container_group.go b/azurerm/resource_arm_container_group.go index f124f54787a7..3cd524eab901 100644 --- a/azurerm/resource_arm_container_group.go +++ b/azurerm/resource_arm_container_group.go @@ -1,6 +1,9 @@ package azurerm -import "github.com/hashicorp/terraform/helper/schema" +import ( + "github.com/Azure/azure-sdk-for-go/arm/containerinstance" + "github.com/hashicorp/terraform/helper/schema" +) func resourceArmContainerGroup() *schema.Resource { return &schema.Resource{ @@ -24,16 +27,97 @@ func resourceArmContainerGroup() *schema.Resource { ForceNew: true, }, + "image": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "cpu_cores": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + }, + + "command_line": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "env_vars": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "ip_address_type": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "memory": { + Type: schema.TypeFloat, + Optional: true, + ForceNew: true, + }, + + "os_type": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + + "port": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + }, + "tags": tagsSchema(), }, } } +// func containerSchema() *schema.Resource { +// return &schema.Resource{ +// Type:schema +// } +// } + func resourceArmContainerGroupCreate(d *schema.ResourceData, meta interface{}) error { - //client := meta.(*ArmClient) - //containterGroupsClient := client.containerGroupsClient + client := meta.(*ArmClient) + containterGroupsClient := client.containerGroupsClient + + // container group properties + resGroup := d.Get("resource_group_name").(string) + name := d.Get("name").(string) + location := d.Get("location").(string) + OSType := d.Get("os_type").(string) + tags := d.Get("tags").(map[string]interface{}) + + // per container properties + // image := d.Get("image").(string) + // cores := d.Get("cpu_cores").(int) + // cmdLine := d.Get("command_line").(string) + // envVars := d.Get("env_vars").(string) + // IPAddressType := d.Get("ip_address_type").(string) + // memory := d.Get("memory").(float32) + // port := d.Get("port").(int) + + containerGroup := containerinstance.ContainerGroup{ + Name: &name, + Type: &OSType, + Location: &location, + Tags: expandTags(tags), + } + + _, error := containterGroupsClient.CreateOrUpdate(resGroup, name, containerGroup) + if error != nil { + return error + } - //containterGroupsClient.CreateOrUpdate() return nil } func resourceArmContainerGroupRead(d *schema.ResourceData, meta interface{}) error { From c5847c3c7dca6d25c9be06f9580a8175b0f95785 Mon Sep 17 00:00:00 2001 From: Abhijeet Gaiha Date: Mon, 4 Sep 2017 18:49:54 +0530 Subject: [PATCH 03/20] WIP: Container group resource --- azurerm/resource_arm_container_group.go | 125 +++++++++++++++++++----- 1 file changed, 98 insertions(+), 27 deletions(-) diff --git a/azurerm/resource_arm_container_group.go b/azurerm/resource_arm_container_group.go index 3cd524eab901..7c19c0b0b1db 100644 --- a/azurerm/resource_arm_container_group.go +++ b/azurerm/resource_arm_container_group.go @@ -1,6 +1,8 @@ package azurerm import ( + "strings" + "github.com/Azure/azure-sdk-for-go/arm/containerinstance" "github.com/hashicorp/terraform/helper/schema" ) @@ -33,20 +35,8 @@ func resourceArmContainerGroup() *schema.Resource { ForceNew: true, }, - "cpu_cores": { - Type: schema.TypeInt, - Optional: true, - ForceNew: true, - }, - - "command_line": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - }, - - "env_vars": { - Type: schema.TypeString, + "cpu": { + Type: schema.TypeFloat, Optional: true, ForceNew: true, }, @@ -75,17 +65,17 @@ func resourceArmContainerGroup() *schema.Resource { ForceNew: true, }, + "protocol": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "tags": tagsSchema(), }, } } -// func containerSchema() *schema.Resource { -// return &schema.Resource{ -// Type:schema -// } -// } - func resourceArmContainerGroupCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*ArmClient) containterGroupsClient := client.containerGroupsClient @@ -95,22 +85,77 @@ func resourceArmContainerGroupCreate(d *schema.ResourceData, meta interface{}) e name := d.Get("name").(string) location := d.Get("location").(string) OSType := d.Get("os_type").(string) + IPAddressType := d.Get("ip_address_type").(string) + protocol := d.Get("protocol").(string) tags := d.Get("tags").(map[string]interface{}) // per container properties - // image := d.Get("image").(string) - // cores := d.Get("cpu_cores").(int) - // cmdLine := d.Get("command_line").(string) - // envVars := d.Get("env_vars").(string) - // IPAddressType := d.Get("ip_address_type").(string) - // memory := d.Get("memory").(float32) - // port := d.Get("port").(int) + image := d.Get("image").(string) + cpu := d.Get("cpu").(float64) + memory := d.Get("memory").(float64) + port := d.Get("port").(int32) + + // type ContainerGroupProperties struct { + // ProvisioningState *string `json:"provisioningState,omitempty"` + // Containers *[]Container `json:"containers,omitempty"` + // ImageRegistryCredentials *[]ImageRegistryCredential `json:"imageRegistryCredentials,omitempty"` + // RestartPolicy ContainerRestartPolicy `json:"restartPolicy,omitempty"` + // IPAddress *IPAddress `json:"ipAddress,omitempty"` + // OsType OperatingSystemTypes `json:"osType,omitempty"` + // State *string `json:"state,omitempty"` + // Volumes *[]Volume `json:"volumes,omitempty"` + // } + + // type ContainerProperties struct { + // Image *string `json:"image,omitempty"` + // Command *[]string `json:"command,omitempty"` + // Ports *[]ContainerPort `json:"ports,omitempty"` + // EnvironmentVariables *[]EnvironmentVariable `json:"environmentVariables,omitempty"` + // InstanceView *ContainerPropertiesInstanceView `json:"instanceView,omitempty"` + // Resources *ResourceRequirements `json:"resources,omitempty"` + // VolumeMounts *[]VolumeMount `json:"volumeMounts,omitempty"` + // } + + // per container port (port number only) + containerPort := containerinstance.ContainerPort{ + Port: &port, + } + + container := containerinstance.Container{ + Name: &name, + ContainerProperties: &containerinstance.ContainerProperties{ + Image: &image, + Ports: &[]containerinstance.ContainerPort{containerPort}, + Resources: &containerinstance.ResourceRequirements{ + Requests: &containerinstance.ResourceRequests{ + MemoryInGB: &memory, + CPU: &cpu, + }, + }, + }, + } + + // container group port (port number + protocol) + containerGroupPort := containerinstance.Port{ + Port: &port, + } + + if strings.ToUpper(protocol) == "TCP" || strings.ToUpper(protocol) == "UDP" { + containerGroupPort.Protocol = containerinstance.ContainerGroupNetworkProtocol(strings.ToUpper(protocol)) + } containerGroup := containerinstance.ContainerGroup{ Name: &name, Type: &OSType, Location: &location, Tags: expandTags(tags), + ContainerGroupProperties: &containerinstance.ContainerGroupProperties{ + Containers: &[]containerinstance.Container{container}, + IPAddress: &containerinstance.IPAddress{ + Type: &IPAddressType, + Ports: &[]containerinstance.Port{containerGroupPort}, + }, + }, } _, error := containterGroupsClient.CreateOrUpdate(resGroup, name, containerGroup) @@ -121,8 +166,34 @@ func resourceArmContainerGroupCreate(d *schema.ResourceData, meta interface{}) e return nil } func resourceArmContainerGroupRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient) + containterGroupsClient := client.containerGroupsClient + + // container group properties + resGroup := d.Get("resource_group_name").(string) + name := d.Get("name").(string) + + _, error := containterGroupsClient.Get(resGroup, name) + + if error != nil { + return error + } + return nil } func resourceArmContainerGroupDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*ArmClient) + containterGroupsClient := client.containerGroupsClient + + // container group properties + resGroup := d.Get("resource_group_name").(string) + name := d.Get("name").(string) + + _, error := containterGroupsClient.Delete(resGroup, name) + + if error != nil { + return error + } + return nil } From 92ae41703f5cac0fac7a7867bf7a3ca2752b7b6c Mon Sep 17 00:00:00 2001 From: Abhijeet Gaiha Date: Tue, 5 Sep 2017 07:27:54 +0530 Subject: [PATCH 04/20] WIP: Container groups resource --- azurerm/resource_arm_container_group.go | 55 ++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/azurerm/resource_arm_container_group.go b/azurerm/resource_arm_container_group.go index 7c19c0b0b1db..cd768536c842 100644 --- a/azurerm/resource_arm_container_group.go +++ b/azurerm/resource_arm_container_group.go @@ -1,6 +1,7 @@ package azurerm import ( + "fmt" "strings" "github.com/Azure/azure-sdk-for-go/arm/containerinstance" @@ -71,6 +72,11 @@ func resourceArmContainerGroup() *schema.Resource { ForceNew: true, }, + "ip_address": { + Type: schema.TypeString, + Computed: true, + }, + "tags": tagsSchema(), }, } @@ -78,7 +84,7 @@ func resourceArmContainerGroup() *schema.Resource { func resourceArmContainerGroupCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*ArmClient) - containterGroupsClient := client.containerGroupsClient + containerGroupsClient := client.containerGroupsClient // container group properties resGroup := d.Get("resource_group_name").(string) @@ -158,27 +164,64 @@ func resourceArmContainerGroupCreate(d *schema.ResourceData, meta interface{}) e }, } - _, error := containterGroupsClient.CreateOrUpdate(resGroup, name, containerGroup) + _, error := containerGroupsClient.CreateOrUpdate(resGroup, name, containerGroup) if error != nil { return error } + read, readErr := containerGroupsClient.Get(resGroup, name) + if readErr != nil { + return readErr + } + + if read.ID == nil { + return fmt.Errorf("Cannot read container group %s (resource group %s) ID", name, resGroup) + } + + d.SetId(*read.ID) + return nil } func resourceArmContainerGroupRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*ArmClient) containterGroupsClient := client.containerGroupsClient - // container group properties - resGroup := d.Get("resource_group_name").(string) - name := d.Get("name").(string) + id, err := parseAzureResourceID(d.Id()) - _, error := containterGroupsClient.Get(resGroup, name) + if err != nil { + return err + } + + resGroup := id.ResourceGroup + name := id.Path["containergroups"] + + resp, error := containterGroupsClient.Get(resGroup, name) if error != nil { return error } + d.Set("name", name) + d.Set("resource_group_name", resGroup) + d.Set("location", azureRMNormalizeLocation(*resp.Location)) + flattenAndSetTags(d, resp.Tags) + + d.Set("os_type", string(resp.OsType)) + d.Set("ip_address_type", *resp.IPAddress.Type) + d.Set("ip_address", *resp.IPAddress.IP) + + ports := *resp.IPAddress.Ports + d.Set("protocol", string(ports[0].Protocol)) + + containers := *resp.Containers + d.Set("image", containers[0].Image) + resourceRequirements := *containers[0].Resources + resourceRequests := *resourceRequirements.Requests + d.Set("cpu", *resourceRequests.CPU) + d.Set("memory", *resourceRequests.MemoryInGB) + containerPorts := *containers[0].Ports + d.Set("port", containerPorts[0].Port) + return nil } func resourceArmContainerGroupDelete(d *schema.ResourceData, meta interface{}) error { From 89fdecadc617eb5ae07f1ffe26135f27c3f7d573 Mon Sep 17 00:00:00 2001 From: Abhijeet Gaiha Date: Tue, 5 Sep 2017 08:35:09 +0530 Subject: [PATCH 05/20] WIP Container Instance Resource: basic works. --- azurerm/resource_arm_container_group.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/azurerm/resource_arm_container_group.go b/azurerm/resource_arm_container_group.go index cd768536c842..5d754397c641 100644 --- a/azurerm/resource_arm_container_group.go +++ b/azurerm/resource_arm_container_group.go @@ -99,7 +99,7 @@ func resourceArmContainerGroupCreate(d *schema.ResourceData, meta interface{}) e image := d.Get("image").(string) cpu := d.Get("cpu").(float64) memory := d.Get("memory").(float64) - port := d.Get("port").(int32) + port := int32(d.Get("port").(int)) // type ContainerGroupProperties struct { // ProvisioningState *string `json:"provisioningState,omitempty"` @@ -152,7 +152,6 @@ func resourceArmContainerGroupCreate(d *schema.ResourceData, meta interface{}) e containerGroup := containerinstance.ContainerGroup{ Name: &name, - Type: &OSType, Location: &location, Tags: expandTags(tags), ContainerGroupProperties: &containerinstance.ContainerGroupProperties{ @@ -161,6 +160,7 @@ func resourceArmContainerGroupCreate(d *schema.ResourceData, meta interface{}) e Type: &IPAddressType, Ports: &[]containerinstance.Port{containerGroupPort}, }, + OsType: containerinstance.OperatingSystemTypes(OSType), }, } @@ -193,7 +193,7 @@ func resourceArmContainerGroupRead(d *schema.ResourceData, meta interface{}) err } resGroup := id.ResourceGroup - name := id.Path["containergroups"] + name := id.Path["containerGroups"] resp, error := containterGroupsClient.Get(resGroup, name) From a1365c7fe7260ec537dc7e4f608bb9d3f4615e2f Mon Sep 17 00:00:00 2001 From: Abhijeet Gaiha Date: Tue, 5 Sep 2017 10:41:31 +0530 Subject: [PATCH 06/20] WIP Container groups resource - formatting changes. --- azurerm/provider.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azurerm/provider.go b/azurerm/provider.go index 22f1697c9f08..6d1bceeab784 100644 --- a/azurerm/provider.go +++ b/azurerm/provider.go @@ -74,7 +74,7 @@ func Provider() terraform.ResourceProvider { "azurerm_cdn_profile": resourceArmCdnProfile(), "azurerm_container_registry": resourceArmContainerRegistry(), "azurerm_container_service": resourceArmContainerService(), - "azurerm_container_group": resourceArmContainerGroup(), + "azurerm_container_group": resourceArmContainerGroup(), "azurerm_cosmosdb_account": resourceArmCosmosDBAccount(), "azurerm_dns_a_record": resourceArmDnsARecord(), "azurerm_dns_aaaa_record": resourceArmDnsAAAARecord(), @@ -245,7 +245,7 @@ func determineAzureResourceProvidersToRegister(providerList []resources.Provider "Microsoft.Compute": struct{}{}, "Microsoft.ContainerRegistry": struct{}{}, "Microsoft.ContainerService": struct{}{}, - "Microsoft.ContainerInstance": struct{}{}, + "Microsoft.ContainerInstance": struct{}{}, "Microsoft.DocumentDB": struct{}{}, "Microsoft.EventGrid": struct{}{}, "Microsoft.EventHub": struct{}{}, From 51356a49b0f1290b13cb920907ebb5f5cd626f5d Mon Sep 17 00:00:00 2001 From: Abhijeet Gaiha Date: Wed, 6 Sep 2017 08:17:04 +0530 Subject: [PATCH 07/20] WIP Container Groups resource --- azurerm/resource_arm_container_group.go | 180 ++++++++++++++---------- 1 file changed, 103 insertions(+), 77 deletions(-) diff --git a/azurerm/resource_arm_container_group.go b/azurerm/resource_arm_container_group.go index 5d754397c641..19fd9aa80ef0 100644 --- a/azurerm/resource_arm_container_group.go +++ b/azurerm/resource_arm_container_group.go @@ -30,54 +30,70 @@ func resourceArmContainerGroup() *schema.Resource { ForceNew: true, }, - "image": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - }, - - "cpu": { - Type: schema.TypeFloat, - Optional: true, - ForceNew: true, - }, - "ip_address_type": { Type: schema.TypeString, Optional: true, ForceNew: true, }, - "memory": { - Type: schema.TypeFloat, - Optional: true, - ForceNew: true, - }, - "os_type": { Type: schema.TypeString, Optional: true, ForceNew: true, }, - "port": { - Type: schema.TypeInt, - Optional: true, - ForceNew: true, - }, - - "protocol": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - }, + "tags": tagsSchema(), "ip_address": { Type: schema.TypeString, Computed: true, }, - "tags": tagsSchema(), + "container": { + Type: schema.TypeList, + Required: true, + ForceNew: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + + "name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "image": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + }, + + "cpu": { + Type: schema.TypeFloat, + Required: true, + ForceNew: true, + }, + + "memory": { + Type: schema.TypeFloat, + Required: true, + ForceNew: true, + }, + + "port": { + Type: schema.TypeInt, + Required: true, + ForceNew: true, + }, + + "protocol": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + }, + }, + }, }, } } @@ -91,15 +107,62 @@ func resourceArmContainerGroupCreate(d *schema.ResourceData, meta interface{}) e name := d.Get("name").(string) location := d.Get("location").(string) OSType := d.Get("os_type").(string) + if OSType == "" { + OSType = "linux" + } IPAddressType := d.Get("ip_address_type").(string) - protocol := d.Get("protocol").(string) + if IPAddressType == "" { + IPAddressType = "public" + } tags := d.Get("tags").(map[string]interface{}) - // per container properties - image := d.Get("image").(string) - cpu := d.Get("cpu").(float64) - memory := d.Get("memory").(float64) - port := int32(d.Get("port").(int)) + containersConfig := d.Get("container").([]interface{}) + containers := make([]containerinstance.Container, len(containersConfig)) + containerGroupPorts := make([]containerinstance.Port, len(containersConfig)) + + for index, containerConfig := range containersConfig { + data := containerConfig.(map[string]interface{}) + + // required + name := data["name"].(string) + image := data["image"].(string) + + // optional + cpu := data["cpu"].(float64) + memory := data["memory"].(float64) + port := int32(data["port"].(int)) + protocol := data["protocol"].(string) + + containerPort := containerinstance.ContainerPort{ + Port: &port, + } + + // container group port (port number + protocol) + containerGroupPort := containerinstance.Port{ + Port: &port, + } + + if strings.ToUpper(protocol) == "TCP" || strings.ToUpper(protocol) == "UDP" { + containerGroupPort.Protocol = containerinstance.ContainerGroupNetworkProtocol(strings.ToUpper(protocol)) + } + containerGroupPorts[index] = containerGroupPort + + container := containerinstance.Container{ + Name: &name, + ContainerProperties: &containerinstance.ContainerProperties{ + Image: &image, + Ports: &[]containerinstance.ContainerPort{containerPort}, + Resources: &containerinstance.ResourceRequirements{ + Requests: &containerinstance.ResourceRequests{ + MemoryInGB: &memory, + CPU: &cpu, + }, + }, + }, + } + + containers[index] = container + } // type ContainerGroupProperties struct { // ProvisioningState *string `json:"provisioningState,omitempty"` @@ -122,43 +185,15 @@ func resourceArmContainerGroupCreate(d *schema.ResourceData, meta interface{}) e // VolumeMounts *[]VolumeMount `json:"volumeMounts,omitempty"` // } - // per container port (port number only) - containerPort := containerinstance.ContainerPort{ - Port: &port, - } - - container := containerinstance.Container{ - Name: &name, - ContainerProperties: &containerinstance.ContainerProperties{ - Image: &image, - Ports: &[]containerinstance.ContainerPort{containerPort}, - Resources: &containerinstance.ResourceRequirements{ - Requests: &containerinstance.ResourceRequests{ - MemoryInGB: &memory, - CPU: &cpu, - }, - }, - }, - } - - // container group port (port number + protocol) - containerGroupPort := containerinstance.Port{ - Port: &port, - } - - if strings.ToUpper(protocol) == "TCP" || strings.ToUpper(protocol) == "UDP" { - containerGroupPort.Protocol = containerinstance.ContainerGroupNetworkProtocol(strings.ToUpper(protocol)) - } - containerGroup := containerinstance.ContainerGroup{ Name: &name, Location: &location, Tags: expandTags(tags), ContainerGroupProperties: &containerinstance.ContainerGroupProperties{ - Containers: &[]containerinstance.Container{container}, + Containers: &containers, IPAddress: &containerinstance.IPAddress{ Type: &IPAddressType, - Ports: &[]containerinstance.Port{containerGroupPort}, + Ports: &containerGroupPorts, }, OsType: containerinstance.OperatingSystemTypes(OSType), }, @@ -210,17 +245,8 @@ func resourceArmContainerGroupRead(d *schema.ResourceData, meta interface{}) err d.Set("ip_address_type", *resp.IPAddress.Type) d.Set("ip_address", *resp.IPAddress.IP) - ports := *resp.IPAddress.Ports - d.Set("protocol", string(ports[0].Protocol)) - - containers := *resp.Containers - d.Set("image", containers[0].Image) - resourceRequirements := *containers[0].Resources - resourceRequests := *resourceRequirements.Requests - d.Set("cpu", *resourceRequests.CPU) - d.Set("memory", *resourceRequests.MemoryInGB) - containerPorts := *containers[0].Ports - d.Set("port", containerPorts[0].Port) + // ports := *resp.IPAddress.Ports + // containers := *resp.Containers return nil } From b95a6186074f272e2f216412cd02fd0b2bf296d5 Mon Sep 17 00:00:00 2001 From: Abhijeet Gaiha Date: Wed, 6 Sep 2017 17:45:25 +0530 Subject: [PATCH 08/20] WIP Container groups resource --- azurerm/resource_arm_container_group.go | 68 +++++++++++-------------- 1 file changed, 30 insertions(+), 38 deletions(-) diff --git a/azurerm/resource_arm_container_group.go b/azurerm/resource_arm_container_group.go index 19fd9aa80ef0..35d524845662 100644 --- a/azurerm/resource_arm_container_group.go +++ b/azurerm/resource_arm_container_group.go @@ -12,7 +12,6 @@ func resourceArmContainerGroup() *schema.Resource { return &schema.Resource{ Create: resourceArmContainerGroupCreate, Read: resourceArmContainerGroupRead, - Update: resourceArmContainerGroupCreate, Delete: resourceArmContainerGroupDelete, Schema: map[string]*schema.Schema{ @@ -31,18 +30,20 @@ func resourceArmContainerGroup() *schema.Resource { }, "ip_address_type": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: ignoreCaseDiffSuppressFunc, }, "os_type": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, + Type: schema.TypeString, + Required: true, + ForceNew: true, + DiffSuppressFunc: ignoreCaseDiffSuppressFunc, }, - "tags": tagsSchema(), + "tags": tagsForceNewSchema(), "ip_address": { Type: schema.TypeString, @@ -107,13 +108,7 @@ func resourceArmContainerGroupCreate(d *schema.ResourceData, meta interface{}) e name := d.Get("name").(string) location := d.Get("location").(string) OSType := d.Get("os_type").(string) - if OSType == "" { - OSType = "linux" - } IPAddressType := d.Get("ip_address_type").(string) - if IPAddressType == "" { - IPAddressType = "public" - } tags := d.Get("tags").(map[string]interface{}) containersConfig := d.Get("container").([]interface{}) @@ -164,27 +159,6 @@ func resourceArmContainerGroupCreate(d *schema.ResourceData, meta interface{}) e containers[index] = container } - // type ContainerGroupProperties struct { - // ProvisioningState *string `json:"provisioningState,omitempty"` - // Containers *[]Container `json:"containers,omitempty"` - // ImageRegistryCredentials *[]ImageRegistryCredential `json:"imageRegistryCredentials,omitempty"` - // RestartPolicy ContainerRestartPolicy `json:"restartPolicy,omitempty"` - // IPAddress *IPAddress `json:"ipAddress,omitempty"` - // OsType OperatingSystemTypes `json:"osType,omitempty"` - // State *string `json:"state,omitempty"` - // Volumes *[]Volume `json:"volumes,omitempty"` - // } - - // type ContainerProperties struct { - // Image *string `json:"image,omitempty"` - // Command *[]string `json:"command,omitempty"` - // Ports *[]ContainerPort `json:"ports,omitempty"` - // EnvironmentVariables *[]EnvironmentVariable `json:"environmentVariables,omitempty"` - // InstanceView *ContainerPropertiesInstanceView `json:"instanceView,omitempty"` - // Resources *ResourceRequirements `json:"resources,omitempty"` - // VolumeMounts *[]VolumeMount `json:"volumeMounts,omitempty"` - // } - containerGroup := containerinstance.ContainerGroup{ Name: &name, Location: &location, @@ -215,7 +189,7 @@ func resourceArmContainerGroupCreate(d *schema.ResourceData, meta interface{}) e d.SetId(*read.ID) - return nil + return resourceArmContainerGroupRead(d, meta) } func resourceArmContainerGroupRead(d *schema.ResourceData, meta interface{}) error { client := meta.(*ArmClient) @@ -245,8 +219,26 @@ func resourceArmContainerGroupRead(d *schema.ResourceData, meta interface{}) err d.Set("ip_address_type", *resp.IPAddress.Type) d.Set("ip_address", *resp.IPAddress.IP) - // ports := *resp.IPAddress.Ports - // containers := *resp.Containers + ports := *resp.IPAddress.Ports + containers := *resp.Containers + + containerConfigs := make([]interface{}, 0, len(containers)) + for index, container := range containers { + containerConfig := make(map[string]interface{}) + containerConfig["name"] = *container.Name + containerConfig["image"] = *container.Image + + resourceRequests := *(*container.Resources).Requests + containerConfig["cpu"] = *resourceRequests.CPU + containerConfig["memory"] = *resourceRequests.MemoryInGB + + containerConfig["port"] = *(*container.Ports)[0].Port + containerConfig["protocol"] = string(ports[index].Protocol) + + containerConfigs = append(containerConfigs, containerConfig) + } + + d.Set("container", containerConfigs) return nil } From b9e32977adfef2c3645c475497f17b291369a405 Mon Sep 17 00:00:00 2001 From: Abhijeet Gaiha Date: Wed, 6 Sep 2017 19:26:49 +0530 Subject: [PATCH 09/20] WIP Container Group Resource --- azurerm/resource_arm_container_group.go | 51 ++++++++++++++----------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/azurerm/resource_arm_container_group.go b/azurerm/resource_arm_container_group.go index 35d524845662..72c894fa5786 100644 --- a/azurerm/resource_arm_container_group.go +++ b/azurerm/resource_arm_container_group.go @@ -83,7 +83,7 @@ func resourceArmContainerGroup() *schema.Resource { "port": { Type: schema.TypeInt, - Required: true, + Optional: true, ForceNew: true, }, @@ -112,10 +112,10 @@ func resourceArmContainerGroupCreate(d *schema.ResourceData, meta interface{}) e tags := d.Get("tags").(map[string]interface{}) containersConfig := d.Get("container").([]interface{}) - containers := make([]containerinstance.Container, len(containersConfig)) - containerGroupPorts := make([]containerinstance.Port, len(containersConfig)) + containers := make([]containerinstance.Container, 0, len(containersConfig)) + containerGroupPorts := make([]containerinstance.Port, 0, len(containersConfig)) - for index, containerConfig := range containersConfig { + for _, containerConfig := range containersConfig { data := containerConfig.(map[string]interface{}) // required @@ -128,25 +128,10 @@ func resourceArmContainerGroupCreate(d *schema.ResourceData, meta interface{}) e port := int32(data["port"].(int)) protocol := data["protocol"].(string) - containerPort := containerinstance.ContainerPort{ - Port: &port, - } - - // container group port (port number + protocol) - containerGroupPort := containerinstance.Port{ - Port: &port, - } - - if strings.ToUpper(protocol) == "TCP" || strings.ToUpper(protocol) == "UDP" { - containerGroupPort.Protocol = containerinstance.ContainerGroupNetworkProtocol(strings.ToUpper(protocol)) - } - containerGroupPorts[index] = containerGroupPort - container := containerinstance.Container{ Name: &name, ContainerProperties: &containerinstance.ContainerProperties{ Image: &image, - Ports: &[]containerinstance.ContainerPort{containerPort}, Resources: &containerinstance.ResourceRequirements{ Requests: &containerinstance.ResourceRequests{ MemoryInGB: &memory, @@ -156,7 +141,29 @@ func resourceArmContainerGroupCreate(d *schema.ResourceData, meta interface{}) e }, } - containers[index] = container + if port != 0 { + // container port (port number) + containerPort := containerinstance.ContainerPort{ + Port: &port, + } + + container.Ports = &[]containerinstance.ContainerPort{containerPort} + + // container group port (port number + protocol) + containerGroupPort := containerinstance.Port{ + Port: &port, + } + + if protocol != "" && (strings.ToUpper(protocol) == "TCP" || strings.ToUpper(protocol) == "UDP") { + containerGroupPort.Protocol = containerinstance.ContainerGroupNetworkProtocol(strings.ToUpper(protocol)) + } else if protocol != "" { + return fmt.Errorf("Invalid protocol %s for container %s", protocol, name) + } + + containerGroupPorts = append(containerGroupPorts, containerGroupPort) + } + + containers = append(containers, container) } containerGroup := containerinstance.ContainerGroup{ @@ -219,11 +226,10 @@ func resourceArmContainerGroupRead(d *schema.ResourceData, meta interface{}) err d.Set("ip_address_type", *resp.IPAddress.Type) d.Set("ip_address", *resp.IPAddress.IP) - ports := *resp.IPAddress.Ports containers := *resp.Containers containerConfigs := make([]interface{}, 0, len(containers)) - for index, container := range containers { + for _, container := range containers { containerConfig := make(map[string]interface{}) containerConfig["name"] = *container.Name containerConfig["image"] = *container.Image @@ -233,7 +239,6 @@ func resourceArmContainerGroupRead(d *schema.ResourceData, meta interface{}) err containerConfig["memory"] = *resourceRequests.MemoryInGB containerConfig["port"] = *(*container.Ports)[0].Port - containerConfig["protocol"] = string(ports[index].Protocol) containerConfigs = append(containerConfigs, containerConfig) } From ad6b4ec5eead09d4875bc8202fde1ddff4bca026 Mon Sep 17 00:00:00 2001 From: Abhijeet Gaiha Date: Thu, 7 Sep 2017 07:00:18 +0530 Subject: [PATCH 10/20] WIP Container Groups Provider: Added Basic Tests --- azurerm/resource_arm_container_group.go | 5 +- azurerm/resource_arm_container_group_test.go | 173 +++++++++++++++++++ 2 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 azurerm/resource_arm_container_group_test.go diff --git a/azurerm/resource_arm_container_group.go b/azurerm/resource_arm_container_group.go index 72c894fa5786..49771a72f3fc 100644 --- a/azurerm/resource_arm_container_group.go +++ b/azurerm/resource_arm_container_group.go @@ -121,10 +121,10 @@ func resourceArmContainerGroupCreate(d *schema.ResourceData, meta interface{}) e // required name := data["name"].(string) image := data["image"].(string) - - // optional cpu := data["cpu"].(float64) memory := data["memory"].(float64) + + // optional port := int32(data["port"].(int)) protocol := data["protocol"].(string) @@ -239,6 +239,7 @@ func resourceArmContainerGroupRead(d *schema.ResourceData, meta interface{}) err containerConfig["memory"] = *resourceRequests.MemoryInGB containerConfig["port"] = *(*container.Ports)[0].Port + // protocol isn't returned in container config containerConfigs = append(containerConfigs, containerConfig) } diff --git a/azurerm/resource_arm_container_group_test.go b/azurerm/resource_arm_container_group_test.go new file mode 100644 index 000000000000..b67c6e5efe9d --- /dev/null +++ b/azurerm/resource_arm_container_group_test.go @@ -0,0 +1,173 @@ +package azurerm + +import ( + "fmt" + "net/http" + "testing" + + "github.com/hashicorp/terraform/helper/acctest" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccAzureRMContainerGroup_basicLinux(t *testing.T) { + ri := acctest.RandInt() + + name := fmt.Sprintf("acctestcontainergroup-%d", ri) + resourceGroupName := fmt.Sprintf("acctestRG-%d", ri) + + config := testAccAzureRMContainerGroupBasicLinux(name, resourceGroupName, testLocation()) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMContainerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerGroupExists("azurerm_container_group.test"), + ), + }, + }, + }) +} + +func TestAccAzureRMContainerGroup_basicWindows(t *testing.T) { + ri := acctest.RandInt() + + name := fmt.Sprintf("acctestcontainergroup-%d", ri) + resourceGroupName := fmt.Sprintf("acctestRG-%d", ri) + + config := testAccAzureRMContainerGroupBasicWindows(name, resourceGroupName, testLocation()) + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testCheckAzureRMContainerGroupDestroy, + Steps: []resource.TestStep{ + { + Config: config, + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMContainerGroupExists("azurerm_container_group.test"), + ), + }, + }, + }) +} + +func testAccAzureRMContainerGroupBasicLinux(name string, resourceGroupName string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "%s" + location = "%s" +} + +resource "azurerm_container_group" "test" { + + name = "%s" + location = "%s" + resource_group_name = "${azurerm_resource_group.test.name}" + ip_address_type="public" + os_type = "linux" + + container { + name = "%s" + image = "nginx:latest" + cpu ="1" + memory = "1.0" + port = "80" +# protocol = "TCP" + } + + tags { + environment = "testing" + } + } +`, resourceGroupName, location, name, location, name) +} + +func testAccAzureRMContainerGroupBasicWindows(name string, resourceGroupName string, location string) string { + return fmt.Sprintf(` +resource "azurerm_resource_group" "test" { + name = "%s" + location = "%s" +} + +resource "azurerm_container_group" "test" { + + name = "%s" + location = "%s" + resource_group_name = "${azurerm_resource_group.test.name}" + ip_address_type="public" + os_type = "windows" + + container { + name = "%s" + image = "winappimage:latest" + cpu ="2.0" + memory = "3.5" + port = "80" +# protocol = "TCP" + } + + tags { + environment = "testing" + } + } +`, resourceGroupName, location, name, location, name) +} + +func testCheckAzureRMContainerGroupExists(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + // Ensure we have enough information in state to look up in API + rs, ok := s.RootModule().Resources[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + name := rs.Primary.Attributes["name"] + resourceGroup, hasResourceGroup := rs.Primary.Attributes["resource_group_name"] + if !hasResourceGroup { + return fmt.Errorf("Bad: no resource group found in state for Container Registry: %s", name) + } + + conn := testAccProvider.Meta().(*ArmClient).containerGroupsClient + + resp, err := conn.Get(resourceGroup, name) + if err != nil { + return fmt.Errorf("Bad: Get on containerGroupsClient: %+v", err) + } + + if resp.StatusCode == http.StatusNotFound { + return fmt.Errorf("Bad: Container Group %q (resource group: %q) does not exist", name, resourceGroup) + } + + return nil + } +} + +func testCheckAzureRMContainerGroupDestroy(s *terraform.State) error { + conn := testAccProvider.Meta().(*ArmClient).containerGroupsClient + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_container_group" { + continue + } + + name := rs.Primary.Attributes["name"] + resourceGroup := rs.Primary.Attributes["resource_group_name"] + + resp, err := conn.Get(resourceGroup, name) + + if err != nil { + return nil + } + + if resp.StatusCode != http.StatusNotFound { + return fmt.Errorf("Container Group still exists:\n%#v", resp) + } + } + + return nil +} From 8ad469bd3a9c950b4397a24ea0211db9d9232f58 Mon Sep 17 00:00:00 2001 From: Abhijeet Gaiha Date: Thu, 7 Sep 2017 07:25:47 +0530 Subject: [PATCH 11/20] WIP Container Groups Resource : Added docs --- website/azurerm.erb | 3 + website/docs/r/container_group.html.markdown | 105 +++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 website/docs/r/container_group.html.markdown diff --git a/website/azurerm.erb b/website/azurerm.erb index ad9f44fad760..1d06c6caf58c 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -86,6 +86,9 @@ > Container Resources