Skip to content

Commit

Permalink
Merge pull request #33 from philips-software/feature/subnet
Browse files Browse the repository at this point in the history
Container host subnet support
  • Loading branch information
loafoe authored Jan 7, 2021
2 parents 0650152 + 7d65c10 commit 15c408c
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 71 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*.out
*.tf
*.exe
.swp
.DS_Store
terraform-provider-hsdp
build/
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).

## v0.8.6
- Support for setting subnet for Container Hosts
- Fix Container Host import suppot
- Update Terraform to 0.14.4

## v0.8.5
- Wrap more error conditions
- Use UTC timezone for FHIR parsing
Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# syntax = docker/dockerfile:1-experimental

ARG hsdp_provider_version=0.8.1
ARG hsdp_provider_version=0.8.5
FROM --platform=${BUILDPLATFORM} golang:1.15.6-alpine AS build
ARG TARGETOS
ARG TARGETARCH
Expand All @@ -12,7 +12,7 @@ COPY . .
RUN --mount=type=cache,target=/root/.cache/go-build \
GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o /out/terraform-provider-hsdp -ldflags "-X main.GitCommit=${GIT_COMMIT}" .

FROM hashicorp/terraform:0.14.3
FROM hashicorp/terraform:0.14.4
RUN apk add --no-cache tzdata
ARG hsdp_provider_version
ENV HSDP_PROVIDER_VERSION ${hsdp_provider_version}
Expand Down
4 changes: 2 additions & 2 deletions docs/resources/cdr_org.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ The following example creates and onboards a CDR FHIR organization
```hcl
data "hsdp_cdr_fhir_store" "sandbox" {
base_url = "https://cdr-stu3-sandbox.hsdp.io"
fhir_org_id = var.iam_org_id
fhir_org_id = var.root_org_id
}
resource "hsdp_cdr_org" "hospital" {
Expand All @@ -20,7 +20,7 @@ resource "hsdp_cdr_org" "hospital" {
name = "Hospital"
part_of = var.fhir_org_id
part_of = var.root_org_id
}
```

Expand Down
1 change: 1 addition & 0 deletions docs/resources/container_host.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ The following arguments are supported:
* `volume_size` - (Optional) Volume size in GB. Supported value range `1-1000` (1 TB max)
* `security_groups` - (Optional) list(string) of Security groups to attach. Default `[]`
* `user_groups` - (Optional) list(string) of User groups to attach. Default `[]`
* `subnet` - (Optional) This will cause a new instance to get deployed on a specific subnet. Conflicts with `subnet_type`. You should only use this option if you have very specific requirements that dictate all the instances you are creating need to reside in the same AZ. An example of this would be a cluster of systems that need to reside in the same datacenter.
* `subnet_type` - (Optional) What subnet type to use. Can be `public` or `private`. Default is `private`.
* `tags` - (Optional) Map of tags to assign to the instances

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/hashicorp/terraform-plugin-sdk/v2 v2.2.0
github.com/herkyl/patchwerk v0.0.0-20190629103337-f0ea77068152
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
github.com/philips-software/go-hsdp-api v0.27.2-0.20210107132609-ce098e1dc5a2
github.com/philips-software/go-hsdp-api v0.27.2-0.20210107164517-dbff7659673c
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.5.1
)
Expand Down
52 changes: 2 additions & 50 deletions go.sum

Large diffs are not rendered by default.

71 changes: 55 additions & 16 deletions hsdp/resource_container_host.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ func tagsSchema() *schema.Schema {

func resourceContainerHost() *schema.Resource {
return &schema.Resource{
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
CreateContext: resourceContainerHostCreate,
ReadContext: resourceContainerHostRead,
UpdateContext: resourceContainerHostUpdate,
Expand All @@ -40,7 +43,6 @@ func resourceContainerHost() *schema.Resource {
Update: schema.DefaultTimeout(15 * time.Minute),
Delete: schema.DefaultTimeout(30 * time.Minute),
},

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Expand Down Expand Up @@ -109,25 +111,27 @@ func resourceContainerHost() *schema.Resource {
Elem: &schema.Schema{Type: schema.TypeString},
},
"subnet_type": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"public", "private"}, false),
Default: "private",
ForceNew: true,
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
ConflictsWith: []string{"subnet"},
},
"private_ip": {
"subnet": {
Type: schema.TypeString,
ForceNew: true,
Optional: true,
Computed: true,
},
"public_ip": {
"private_ip": {
Type: schema.TypeString,
Computed: true,
},
"role": {
"public_ip": {
Type: schema.TypeString,
Computed: true,
},
"subnet": {
"role": {
Type: schema.TypeString,
Computed: true,
},
Expand All @@ -150,7 +154,7 @@ func resourceContainerHost() *schema.Resource {
},
"tags": tagsSchema(),
},
SchemaVersion: 1,
SchemaVersion: 2,
}
}

Expand Down Expand Up @@ -191,6 +195,10 @@ func resourceContainerHostCreate(ctx context.Context, d *schema.ResourceData, m
userGroups := expandStringList(d.Get("user_groups").(*schema.Set).List())
instanceRole := d.Get("instance_role").(string)
subnetType := d.Get("subnet_type").(string)
if subnetType == "" {
subnetType = "private"
}
subnet := d.Get("subnet").(string)
tagList := d.Get("tags").(map[string]interface{})
tags := make(map[string]string)
for t, v := range tagList {
Expand All @@ -199,7 +207,7 @@ func resourceContainerHostCreate(ctx context.Context, d *schema.ResourceData, m
}
}

ch, _, err := client.Create(tagName,
ch, resp, err := client.Create(tagName,
cartel.SecurityGroups(securityGroups...),
cartel.UserGroups(userGroups...),
cartel.VolumeType(volumeType),
Expand All @@ -211,9 +219,16 @@ func resourceContainerHostCreate(ctx context.Context, d *schema.ResourceData, m
cartel.InstanceRole(instanceRole),
cartel.SubnetType(subnetType),
cartel.Tags(tags),
cartel.InSubnet(subnet),
)
if err != nil {
return diag.FromErr(fmt.Errorf("create error: %d: %s", ch.Code, ch.Description))
if resp == nil {
return diag.FromErr(fmt.Errorf("create error (resp=nil): %w", err))
}
if ch == nil {
return diag.FromErr(fmt.Errorf("create error (instance=nil): %w", err))
}
return diag.FromErr(fmt.Errorf("create error (description=[%s]): %w", ch.Description, err))
}
d.SetId(ch.InstanceID())

Expand All @@ -240,7 +255,7 @@ func resourceContainerHostCreate(ctx context.Context, d *schema.ResourceData, m
return resourceContainerHostRead(ctx, d, m)
}

func resourceContainerHostUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
func resourceContainerHostUpdate(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(*Config)

var diags diag.Diagnostics
Expand Down Expand Up @@ -326,7 +341,7 @@ func resourceContainerHostUpdate(ctx context.Context, d *schema.ResourceData, m

}

func resourceContainerHostRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
func resourceContainerHostRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(*Config)

var diags diag.Diagnostics
Expand All @@ -337,6 +352,24 @@ func resourceContainerHostRead(ctx context.Context, d *schema.ResourceData, m in
}

tagName := d.Get("name").(string)

if tagName == "" { // This is an import, find and set the tagName
instances, _, err := client.GetAllInstances()
if err != nil {
return diag.FromErr(fmt.Errorf("cartel.GetAllInstances: %w", err))
}
id := d.Id()
_ = d.Set("encrypt_volumes", true)
_ = d.Set("volume_size", 0)
for _, i := range *instances {
if i.InstanceID == id {
_ = d.Set("name", i.NameTag)
tagName = i.NameTag
break
}
}
}

state, resp, err := client.GetDeploymentState(tagName)
if err != nil {
if resp != nil && resp.StatusCode == http.StatusBadRequest {
Expand Down Expand Up @@ -366,18 +399,24 @@ func resourceContainerHostRead(ctx context.Context, d *schema.ResourceData, m in
_ = d.Set("security_groups", difference(ch.SecurityGroups, []string{"base"})) // Remove "base"
_ = d.Set("user_groups", ch.LdapGroups)
_ = d.Set("instance_type", ch.InstanceType)
_ = d.Set("instance_role", ch.Role)
_ = d.Set("vpc", ch.Vpc)
_ = d.Set("zone", ch.Zone)
_ = d.Set("launch_time", ch.LaunchTime)
_ = d.Set("private_ip", ch.PrivateAddress)
_ = d.Set("public_ip", ch.PublicAddress)
_ = d.Set("subnet", ch.Subnet)
subnetType := "private"
if ch.PublicAddress != "" {
subnetType = "public"
}
_ = d.Set("subnet_type", subnetType)
_ = d.Set("tags", normalizeTags(ch.Tags))

return diags
}

func resourceContainerHostDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
func resourceContainerHostDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
config := m.(*Config)

var diags diag.Diagnostics
Expand Down
17 changes: 17 additions & 0 deletions hsdp/validators.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package hsdp
import (
"encoding/json"
"fmt"
"github.com/philips-software/go-hsdp-api/cartel"
"strings"

creds "github.com/philips-software/go-hsdp-api/credentials"
Expand All @@ -28,6 +29,22 @@ func validatePolicyJSON(val interface{}, key string) (warns []string, errs []err
return
}

func validateSubnet(client *cartel.Client, v string) error {
subnets, _, err := client.GetAllSubnets()

if err != nil {
return err
}
var availableSubnets []string
for _, subnet := range *subnets {
availableSubnets = append(availableSubnets, subnet.ID)
if v == subnet.ID {
return nil
}
}
return fmt.Errorf("unsupported subnet: %s (available: %s)", v, strings.Join(availableSubnets, ", "))
}

var thresholdMapping = map[string]string{
"cpu": "threshold_cpu",
"memory": "threshold_memory",
Expand Down

0 comments on commit 15c408c

Please sign in to comment.