From 51356a49b0f1290b13cb920907ebb5f5cd626f5d Mon Sep 17 00:00:00 2001 From: Abhijeet Gaiha Date: Wed, 6 Sep 2017 08:17:04 +0530 Subject: [PATCH 1/3] 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 2/3] 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 3/3] 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) }