Skip to content

Commit

Permalink
Merge pull request #1930 from nathanjsweet/master
Browse files Browse the repository at this point in the history
Adding Ports To Container Groups
  • Loading branch information
katbyte authored Jan 11, 2019
2 parents b604089 + f80e912 commit 6889f3e
Show file tree
Hide file tree
Showing 3 changed files with 206 additions and 80 deletions.
209 changes: 148 additions & 61 deletions azurerm/resource_arm_container_group.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
package azurerm

import (
"bytes"
"fmt"
"log"
"strings"

"github.com/hashicorp/terraform/helper/hashcode"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/suppress"

"github.com/Azure/azure-sdk-for-go/services/containerinstance/mgmt/2018-10-01/containerinstance"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"

"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
Expand All @@ -24,9 +29,10 @@ func resourceArmContainerGroup() *schema.Resource {

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validate.NoEmptyStrings,
},

"location": locationSchema(),
Expand All @@ -38,7 +44,7 @@ func resourceArmContainerGroup() *schema.Resource {
Optional: true,
Default: "Public",
ForceNew: true,
DiffSuppressFunc: ignoreCaseDiffSuppressFunc,
DiffSuppressFunc: suppress.CaseDifference,
ValidateFunc: validation.StringInSlice([]string{
string(containerinstance.Public),
}, true),
Expand All @@ -48,7 +54,7 @@ func resourceArmContainerGroup() *schema.Resource {
Type: schema.TypeString,
Required: true,
ForceNew: true,
DiffSuppressFunc: ignoreCaseDiffSuppressFunc,
DiffSuppressFunc: suppress.CaseDifference,
ValidateFunc: validation.StringInSlice([]string{
string(containerinstance.Windows),
string(containerinstance.Linux),
Expand All @@ -64,23 +70,23 @@ func resourceArmContainerGroup() *schema.Resource {
"server": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validate.NoEmptyStrings,
ForceNew: true,
ValidateFunc: validate.NoEmptyStrings,
},

"username": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validate.NoEmptyStrings,
ForceNew: true,
ValidateFunc: validate.NoEmptyStrings,
},

"password": {
Type: schema.TypeString,
Required: true,
Sensitive: true,
ValidateFunc: validate.NoEmptyStrings,
ForceNew: true,
ValidateFunc: validate.NoEmptyStrings,
},
},
},
Expand All @@ -93,24 +99,14 @@ func resourceArmContainerGroup() *schema.Resource {
Optional: true,
ForceNew: true,
Default: string(containerinstance.Always),
DiffSuppressFunc: ignoreCaseDiffSuppressFunc,
DiffSuppressFunc: suppress.CaseDifference,
ValidateFunc: validation.StringInSlice([]string{
string(containerinstance.Always),
string(containerinstance.Never),
string(containerinstance.OnFailure),
}, true),
},

"ip_address": {
Type: schema.TypeString,
Computed: true,
},

"fqdn": {
Type: schema.TypeString,
Computed: true,
},

"dns_name_label": {
Type: schema.TypeString,
Optional: true,
Expand All @@ -124,15 +120,17 @@ func resourceArmContainerGroup() *schema.Resource {
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validate.NoEmptyStrings,
},

"image": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validate.NoEmptyStrings,
},

"cpu": {
Expand All @@ -151,20 +149,55 @@ func resourceArmContainerGroup() *schema.Resource {
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
ValidateFunc: validation.IntBetween(1, 65535),
Computed: true,
Deprecated: "Deprecated in favor of `ports`",
ValidateFunc: validate.PortNumber,
},

"protocol": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
DiffSuppressFunc: ignoreCaseDiffSuppressFunc,
Computed: true,
Deprecated: "Deprecated in favor of `ports`",
DiffSuppressFunc: suppress.CaseDifference,
ValidateFunc: validation.StringInSlice([]string{
string(containerinstance.TCP),
string(containerinstance.UDP),
}, true),
},

"ports": {
Type: schema.TypeSet,
Optional: true,
ForceNew: true,
Computed: true,
Set: resourceArmContainerGroupPortsHash,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"port": {
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
Computed: true,
ValidateFunc: validate.PortNumber,
},

"protocol": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
//Default: string(containerinstance.TCP), restore in 2.0
ValidateFunc: validation.StringInSlice([]string{
string(containerinstance.TCP),
string(containerinstance.UDP),
}, false),
},
},
},
},

"environment_variables": {
Type: schema.TypeMap,
ForceNew: true,
Expand Down Expand Up @@ -199,15 +232,17 @@ func resourceArmContainerGroup() *schema.Resource {
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validate.NoEmptyStrings,
},

"mount_path": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validate.NoEmptyStrings,
},

"read_only": {
Expand All @@ -218,28 +253,41 @@ func resourceArmContainerGroup() *schema.Resource {
},

"share_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validate.NoEmptyStrings,
},

"storage_account_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validate.NoEmptyStrings,
},

"storage_account_key": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validate.NoEmptyStrings,
},
},
},
},
},
},
},

"ip_address": {
Type: schema.TypeString,
Computed: true,
},

"fqdn": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
Expand Down Expand Up @@ -413,27 +461,44 @@ func expandContainerGroupContainers(d *schema.ResourceData) (*[]containerinstanc
},
}

if v := data["port"]; v != 0 {
port := int32(v.(int))
if v, ok := data["ports"].(*schema.Set); ok && len(v.List()) > 0 {
var ports []containerinstance.ContainerPort
for _, v := range v.List() {
portObj := v.(map[string]interface{})

// container port (port number)
container.Ports = &[]containerinstance.ContainerPort{
{
Port: &port,
},
}
port := int32(portObj["port"].(int))
proto := portObj["protocol"].(string)

// container group port (port number + protocol)
containerGroupPort := containerinstance.Port{
Port: &port,
ports = append(ports, containerinstance.ContainerPort{
Port: &port,
Protocol: containerinstance.ContainerNetworkProtocol(proto),
})
containerGroupPorts = append(containerGroupPorts, containerinstance.Port{
Port: &port,
Protocol: containerinstance.ContainerGroupNetworkProtocol(proto),
})
}
container.Ports = &ports
} else {
if v := int32(data["port"].(int)); v != 0 {
ports := []containerinstance.ContainerPort{
{
Port: &v,
},
}

if v, ok := data["protocol"]; ok {
protocol := v.(string)
containerGroupPort.Protocol = containerinstance.ContainerGroupNetworkProtocol(strings.ToUpper(protocol))
}
port := containerinstance.Port{
Port: &v,
}

if v, ok := data["protocol"].(string); ok {
ports[0].Protocol = containerinstance.ContainerNetworkProtocol(v)
port.Protocol = containerinstance.ContainerGroupNetworkProtocol(v)
}

containerGroupPorts = append(containerGroupPorts, containerGroupPort)
container.Ports = &ports
containerGroupPorts = append(containerGroupPorts, port)
}
}

// Set both sensitive and non-secure environment variables
Expand Down Expand Up @@ -620,7 +685,6 @@ func flattenContainerGroupContainers(d *schema.ResourceData, containers *[]conta
for i, c := range d.Get("container").([]interface{}) {
cfg := c.(map[string]interface{})
nameIndexMap[cfg["name"].(string)] = i

}

containerCfg := make([]interface{}, 0, len(*containers))
Expand Down Expand Up @@ -650,8 +714,20 @@ func flattenContainerGroupContainers(d *schema.ResourceData, containers *[]conta
}
}

if len(*container.Ports) > 0 {
containerPort := *(*container.Ports)[0].Port
if cPorts := container.Ports; cPorts != nil && len(*cPorts) > 0 {
ports := make([]interface{}, 0)
for _, p := range *cPorts {
port := make(map[string]interface{})
if v := p.Port; v != nil {
port["port"] = int(*v)
}
port["protocol"] = string(p.Protocol)
ports = append(ports, port)
}
containerConfig["ports"] = schema.NewSet(resourceArmContainerGroupPortsHash, ports)

//old deprecated code
containerPort := *(*cPorts)[0].Port
containerConfig["port"] = containerPort
// protocol isn't returned in container config, have to search in container group ports
protocol := ""
Expand Down Expand Up @@ -799,3 +875,14 @@ func flattenContainerVolumes(volumeMounts *[]containerinstance.VolumeMount, cont

return volumeConfigs
}

func resourceArmContainerGroupPortsHash(v interface{}) int {
var buf bytes.Buffer

if m, ok := v.(map[string]interface{}); ok {
buf.WriteString(fmt.Sprintf("%d-", m["port"].(int)))
buf.WriteString(fmt.Sprintf("%s-", m["protocol"].(string)))
}

return hashcode.String(buf.String())
}
Loading

0 comments on commit 6889f3e

Please sign in to comment.