Skip to content

Commit

Permalink
Merge pull request #16167 from ewbankkit/f-aws_appmesh_virtual_node-c…
Browse files Browse the repository at this point in the history
…onnection_pool-outlier_detection

r/aws_appmesh_virtual_node: Add connection pool and outlier detection
  • Loading branch information
breathingdust authored Dec 4, 2020
2 parents eac6c79 + e3a381b commit 1745978
Show file tree
Hide file tree
Showing 5 changed files with 1,314 additions and 687 deletions.
11 changes: 7 additions & 4 deletions aws/resource_aws_appmesh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ func TestAccAWSAppmesh_serial(t *testing.T) {
"tags": testAccAwsAppmeshRoute_tags,
},
"VirtualGateway": {
"backendDefaults": testAccAwsAppmeshVirtualGateway_BackendDefaults,
"basic": testAccAwsAppmeshVirtualGateway_basic,
"disappears": testAccAwsAppmeshVirtualGateway_disappears,
"backendDefaults": testAccAwsAppmeshVirtualGateway_BackendDefaults,
"listenerConnectionPool": testAccAwsAppmeshVirtualGateway_ListenerConnectionPool,
"listenerHealthChecks": testAccAwsAppmeshVirtualGateway_ListenerHealthChecks,
"listenerTls": testAccAwsAppmeshVirtualGateway_ListenerTls,
Expand All @@ -45,14 +45,17 @@ func TestAccAWSAppmesh_serial(t *testing.T) {
},
"VirtualNode": {
"basic": testAccAwsAppmeshVirtualNode_basic,
"disappears": testAccAwsAppmeshVirtualNode_disappears,
"backendClientPolicyAcm": testAccAwsAppmeshVirtualNode_backendClientPolicyAcm,
"backendClientPolicyFile": testAccAwsAppmeshVirtualNode_backendClientPolicyFile,
"backendDefaults": testAccAwsAppmeshVirtualNode_backendDefaults,
"clientPolicyAcm": testAccAwsAppmeshVirtualNode_clientPolicyAcm,
"clientPolicyFile": testAccAwsAppmeshVirtualNode_clientPolicyFile,
"cloudMapServiceDiscovery": testAccAwsAppmeshVirtualNode_cloudMapServiceDiscovery,
"listenerConnectionPool": testAccAwsAppmeshVirtualNode_listenerConnectionPool,
"listenerOutlierDetection": testAccAwsAppmeshVirtualNode_listenerOutlierDetection,
"listenerHealthChecks": testAccAwsAppmeshVirtualNode_listenerHealthChecks,
"listenerTimeout": testAccAwsAppmeshVirtualNode_listenerTimeout,
"listenerTls": testAccAwsAppmeshVirtualNode_listenerTls,
"logging": testAccAwsAppmeshVirtualNode_logging,
"tls": testAccAwsAppmeshVirtualNode_tls,
"tags": testAccAwsAppmeshVirtualNode_tags,
},
"VirtualRouter": {
Expand Down
221 changes: 211 additions & 10 deletions aws/resource_aws_appmesh_virtual_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,110 @@ func resourceAwsAppmeshVirtualNode() *schema.Resource {
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"connection_pool": {
Type: schema.TypeList,
Optional: true,
MinItems: 0,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"grpc": {
Type: schema.TypeList,
Optional: true,
MinItems: 0,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"max_requests": {
Type: schema.TypeInt,
Required: true,
ValidateFunc: validation.IntAtLeast(1),
},
},
},
ExactlyOneOf: []string{
"spec.0.listener.0.connection_pool.0.grpc",
"spec.0.listener.0.connection_pool.0.http",
"spec.0.listener.0.connection_pool.0.http2",
"spec.0.listener.0.connection_pool.0.tcp",
},
},

"http": {
Type: schema.TypeList,
Optional: true,
MinItems: 0,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"max_connections": {
Type: schema.TypeInt,
Required: true,
ValidateFunc: validation.IntAtLeast(1),
},

"max_pending_requests": {
Type: schema.TypeInt,
Optional: true,
ValidateFunc: validation.IntAtLeast(1),
},
},
},
ExactlyOneOf: []string{
"spec.0.listener.0.connection_pool.0.grpc",
"spec.0.listener.0.connection_pool.0.http",
"spec.0.listener.0.connection_pool.0.http2",
"spec.0.listener.0.connection_pool.0.tcp",
},
},

"http2": {
Type: schema.TypeList,
Optional: true,
MinItems: 0,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"max_requests": {
Type: schema.TypeInt,
Required: true,
ValidateFunc: validation.IntAtLeast(1),
},
},
},
ExactlyOneOf: []string{
"spec.0.listener.0.connection_pool.0.grpc",
"spec.0.listener.0.connection_pool.0.http",
"spec.0.listener.0.connection_pool.0.http2",
"spec.0.listener.0.connection_pool.0.tcp",
},
},

"tcp": {
Type: schema.TypeList,
Optional: true,
MinItems: 0,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"max_connections": {
Type: schema.TypeInt,
Required: true,
ValidateFunc: validation.IntAtLeast(1),
},
},
},
ExactlyOneOf: []string{
"spec.0.listener.0.connection_pool.0.grpc",
"spec.0.listener.0.connection_pool.0.http",
"spec.0.listener.0.connection_pool.0.http2",
"spec.0.listener.0.connection_pool.0.tcp",
},
},
},
},
},

"health_check": {
Type: schema.TypeList,
Optional: true,
Expand Down Expand Up @@ -155,6 +259,70 @@ func resourceAwsAppmeshVirtualNode() *schema.Resource {
},
},

"outlier_detection": {
Type: schema.TypeList,
Optional: true,
MinItems: 0,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"base_ejection_duration": {
Type: schema.TypeList,
Required: true,
MinItems: 1,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"unit": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice(appmesh.DurationUnit_Values(), false),
},

"value": {
Type: schema.TypeInt,
Required: true,
},
},
},
},

"interval": {
Type: schema.TypeList,
Required: true,
MinItems: 1,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"unit": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice(appmesh.DurationUnit_Values(), false),
},

"value": {
Type: schema.TypeInt,
Required: true,
},
},
},
},

"max_ejection_percent": {
Type: schema.TypeInt,
Required: true,
ValidateFunc: validation.IntBetween(0, 100),
},

"max_server_errors": {
Type: schema.TypeInt,
Required: true,
ValidateFunc: validation.IntAtLeast(1),
},
},
},
},

"port_mapping": {
Type: schema.TypeList,
Required: true,
Expand Down Expand Up @@ -234,6 +402,12 @@ func resourceAwsAppmeshVirtualNode() *schema.Resource {
},
},
},
ExactlyOneOf: []string{
"spec.0.listener.0.timeout.0.grpc",
"spec.0.listener.0.timeout.0.http",
"spec.0.listener.0.timeout.0.http2",
"spec.0.listener.0.timeout.0.tcp",
},
},

"http": {
Expand Down Expand Up @@ -286,6 +460,12 @@ func resourceAwsAppmeshVirtualNode() *schema.Resource {
},
},
},
ExactlyOneOf: []string{
"spec.0.listener.0.timeout.0.grpc",
"spec.0.listener.0.timeout.0.http",
"spec.0.listener.0.timeout.0.http2",
"spec.0.listener.0.timeout.0.tcp",
},
},

"http2": {
Expand Down Expand Up @@ -338,6 +518,12 @@ func resourceAwsAppmeshVirtualNode() *schema.Resource {
},
},
},
ExactlyOneOf: []string{
"spec.0.listener.0.timeout.0.grpc",
"spec.0.listener.0.timeout.0.http",
"spec.0.listener.0.timeout.0.http2",
"spec.0.listener.0.timeout.0.tcp",
},
},

"tcp": {
Expand Down Expand Up @@ -369,6 +555,12 @@ func resourceAwsAppmeshVirtualNode() *schema.Resource {
},
},
},
ExactlyOneOf: []string{
"spec.0.listener.0.timeout.0.grpc",
"spec.0.listener.0.timeout.0.http",
"spec.0.listener.0.timeout.0.http2",
"spec.0.listener.0.timeout.0.tcp",
},
},
},
},
Expand Down Expand Up @@ -402,6 +594,7 @@ func resourceAwsAppmeshVirtualNode() *schema.Resource {
},
},
},
ExactlyOneOf: []string{"spec.0.listener.0.tls.0.certificate.0.acm", "spec.0.listener.0.tls.0.certificate.0.file"},
},

"file": {
Expand All @@ -424,6 +617,7 @@ func resourceAwsAppmeshVirtualNode() *schema.Resource {
},
},
},
ExactlyOneOf: []string{"spec.0.listener.0.tls.0.certificate.0.acm", "spec.0.listener.0.tls.0.certificate.0.file"},
},
},
},
Expand Down Expand Up @@ -663,10 +857,11 @@ func resourceAwsAppmeshVirtualNodeCreate(d *schema.ResourceData, meta interface{
req.MeshOwner = aws.String(v.(string))
}

log.Printf("[DEBUG] Creating App Mesh virtual node: %#v", req)
log.Printf("[DEBUG] Creating App Mesh virtual node: %s", req)
resp, err := conn.CreateVirtualNode(req)

if err != nil {
return fmt.Errorf("error creating App Mesh virtual node: %s", err)
return fmt.Errorf("error creating App Mesh virtual node: %w", err)
}

d.SetId(aws.StringValue(resp.VirtualNode.Metadata.Uid))
Expand All @@ -687,14 +882,17 @@ func resourceAwsAppmeshVirtualNodeRead(d *schema.ResourceData, meta interface{})
}

resp, err := conn.DescribeVirtualNode(req)

if isAWSErr(err, appmesh.ErrCodeNotFoundException, "") {
log.Printf("[WARN] App Mesh virtual node (%s) not found, removing from state", d.Id())
d.SetId("")
return nil
}

if err != nil {
return fmt.Errorf("error reading App Mesh virtual node: %s", err)
return fmt.Errorf("error reading App Mesh virtual node (%s): %w", d.Id(), err)
}

if aws.StringValue(resp.VirtualNode.Status.Status) == appmesh.VirtualNodeStatusCodeDeleted {
log.Printf("[WARN] App Mesh virtual node (%s) not found, removing from state", d.Id())
d.SetId("")
Expand All @@ -711,17 +909,17 @@ func resourceAwsAppmeshVirtualNodeRead(d *schema.ResourceData, meta interface{})
d.Set("resource_owner", resp.VirtualNode.Metadata.ResourceOwner)
err = d.Set("spec", flattenAppmeshVirtualNodeSpec(resp.VirtualNode.Spec))
if err != nil {
return fmt.Errorf("error setting spec: %s", err)
return fmt.Errorf("error setting spec: %w", err)
}

tags, err := keyvaluetags.AppmeshListTags(conn, arn)

if err != nil {
return fmt.Errorf("error listing tags for App Mesh virtual node (%s): %s", arn, err)
return fmt.Errorf("error listing tags for App Mesh virtual node (%s): %w", arn, err)
}

if err := d.Set("tags", tags.IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil {
return fmt.Errorf("error setting tags: %s", err)
return fmt.Errorf("error setting tags: %w", err)
}

return nil
Expand All @@ -741,10 +939,11 @@ func resourceAwsAppmeshVirtualNodeUpdate(d *schema.ResourceData, meta interface{
req.MeshOwner = aws.String(v.(string))
}

log.Printf("[DEBUG] Updating App Mesh virtual node: %#v", req)
log.Printf("[DEBUG] Updating App Mesh virtual node: %s", req)
_, err := conn.UpdateVirtualNode(req)

if err != nil {
return fmt.Errorf("error updating App Mesh virtual node: %s", err)
return fmt.Errorf("error updating App Mesh virtual node (%s): %w", d.Id(), err)
}
}

Expand All @@ -753,7 +952,7 @@ func resourceAwsAppmeshVirtualNodeUpdate(d *schema.ResourceData, meta interface{
o, n := d.GetChange("tags")

if err := keyvaluetags.AppmeshUpdateTags(conn, arn, o, n); err != nil {
return fmt.Errorf("error updating App Mesh virtual node (%s) tags: %s", arn, err)
return fmt.Errorf("error updating App Mesh virtual node (%s) tags: %w", arn, err)
}
}

Expand All @@ -768,11 +967,13 @@ func resourceAwsAppmeshVirtualNodeDelete(d *schema.ResourceData, meta interface{
MeshName: aws.String(d.Get("mesh_name").(string)),
VirtualNodeName: aws.String(d.Get("name").(string)),
})

if isAWSErr(err, appmesh.ErrCodeNotFoundException, "") {
return nil
}

if err != nil {
return fmt.Errorf("error deleting App Mesh virtual node: %s", err)
return fmt.Errorf("error deleting App Mesh virtual node (%s): %w", d.Id(), err)
}

return nil
Expand Down
Loading

0 comments on commit 1745978

Please sign in to comment.