Skip to content

Commit

Permalink
Merge pull request #4481 from terraform-providers/f-aws_glue_script
Browse files Browse the repository at this point in the history
New Data Source: aws_glue_script
  • Loading branch information
bflad authored May 22, 2018
2 parents 126d78b + 9cafba8 commit 198b6db
Show file tree
Hide file tree
Showing 5 changed files with 323 additions and 0 deletions.
184 changes: 184 additions & 0 deletions aws/data_source_aws_glue_script.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
package aws

import (
"errors"
"fmt"
"log"
"time"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/glue"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
)

func dataSourceAwsGlueScript() *schema.Resource {
return &schema.Resource{
Read: dataSourceAwsGlueScriptRead,
Schema: map[string]*schema.Schema{
"dag_edge": {
Type: schema.TypeList,
Required: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"source": {
Type: schema.TypeString,
Required: true,
},
"target": {
Type: schema.TypeString,
Required: true,
},
"target_parameter": {
Type: schema.TypeString,
Optional: true,
},
},
},
},
"dag_node": {
Type: schema.TypeList,
Required: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"args": {
Type: schema.TypeList,
Required: true,
MinItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
"param": {
Type: schema.TypeBool,
Optional: true,
},
"value": {
Type: schema.TypeString,
Required: true,
},
},
},
},
"id": {
Type: schema.TypeString,
Required: true,
},
"line_number": {
Type: schema.TypeInt,
Optional: true,
},
"node_type": {
Type: schema.TypeString,
Required: true,
},
},
},
},
"language": {
Type: schema.TypeString,
Optional: true,
Default: glue.LanguagePython,
ValidateFunc: validation.StringInSlice([]string{
glue.LanguagePython,
glue.LanguageScala,
}, false),
},
"python_script": {
Type: schema.TypeString,
Computed: true,
},
"scala_code": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func dataSourceAwsGlueScriptRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).glueconn

dagEdge := d.Get("dag_edge").([]interface{})
dagNode := d.Get("dag_node").([]interface{})

input := &glue.CreateScriptInput{
DagEdges: expandGlueCodeGenEdges(dagEdge),
DagNodes: expandGlueCodeGenNodes(dagNode),
}

if v, ok := d.GetOk("language"); ok && v.(string) != "" {
input.Language = aws.String(v.(string))
}

log.Printf("[DEBUG] Creating Glue Script: %s", input)
output, err := conn.CreateScript(input)
if err != nil {
return fmt.Errorf("error creating Glue script: %s", err)
}

if output == nil {
return errors.New("script not created")
}

d.SetId(time.Now().UTC().String())
d.Set("python_script", output.PythonScript)
d.Set("scala_code", output.ScalaCode)

return nil
}

func expandGlueCodeGenNodeArgs(l []interface{}) []*glue.CodeGenNodeArg {
args := []*glue.CodeGenNodeArg{}

for _, mRaw := range l {
m := mRaw.(map[string]interface{})
arg := &glue.CodeGenNodeArg{
Name: aws.String(m["name"].(string)),
Param: aws.Bool(m["param"].(bool)),
Value: aws.String(m["value"].(string)),
}
args = append(args, arg)
}

return args
}

func expandGlueCodeGenEdges(l []interface{}) []*glue.CodeGenEdge {
edges := []*glue.CodeGenEdge{}

for _, mRaw := range l {
m := mRaw.(map[string]interface{})
edge := &glue.CodeGenEdge{
Source: aws.String(m["source"].(string)),
Target: aws.String(m["target"].(string)),
}
if v, ok := m["target_parameter"]; ok && v.(string) != "" {
edge.TargetParameter = aws.String(v.(string))
}
edges = append(edges, edge)
}

return edges
}

func expandGlueCodeGenNodes(l []interface{}) []*glue.CodeGenNode {
nodes := []*glue.CodeGenNode{}

for _, mRaw := range l {
m := mRaw.(map[string]interface{})
node := &glue.CodeGenNode{
Args: expandGlueCodeGenNodeArgs(m["args"].([]interface{})),
Id: aws.String(m["id"].(string)),
NodeType: aws.String(m["node_type"].(string)),
}
if v, ok := m["line_number"]; ok && v.(int) != 0 {
node.LineNumber = aws.Int64(int64(v.(int)))
}
nodes = append(nodes, node)
}

return nodes
}
52 changes: 52 additions & 0 deletions aws/data_source_aws_glue_script_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package aws

import (
"fmt"
"testing"

"github.com/hashicorp/terraform/helper/resource"
)

func TestAccDataSourceAWSGlueScript_Language_Python(t *testing.T) {
dataSourceName := "data.aws_glue_script.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAWSGlueScriptConfig_Language("PYTHON"),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet(dataSourceName, "python_script"),
),
},
},
})
}

func TestAccDataSourceAWSGlueScript_Language_Scala(t *testing.T) {
dataSourceName := "data.aws_glue_script.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceAWSGlueScriptConfig_Language("SCALA"),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet(dataSourceName, "scala_code"),
),
},
},
})
}

func testAccDataSourceAWSGlueScriptConfig_Language(language string) string {
return fmt.Sprintf(`
data "aws_glue_script" "test" {
dag_edge = []
dag_node = []
language = "%s"
}
`, language)
}
1 change: 1 addition & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ func Provider() terraform.ResourceProvider {
"aws_elasticache_replication_group": dataSourceAwsElasticacheReplicationGroup(),
"aws_elb_hosted_zone_id": dataSourceAwsElbHostedZoneId(),
"aws_elb_service_account": dataSourceAwsElbServiceAccount(),
"aws_glue_script": dataSourceAwsGlueScript(),
"aws_iam_account_alias": dataSourceAwsIamAccountAlias(),
"aws_iam_group": dataSourceAwsIAMGroup(),
"aws_iam_instance_profile": dataSourceAwsIAMInstanceProfile(),
Expand Down
3 changes: 3 additions & 0 deletions website/aws.erb
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@
<li<%= sidebar_current("docs-aws-datasource-elb-service-account") %>>
<a href="/docs/providers/aws/d/elb_service_account.html">aws_elb_service_account</a>
</li>
<li<%= sidebar_current("docs-aws-datasource-glue-script") %>>
<a href="/docs/providers/aws/d/glue_script.html">aws_glue_script</a>
</li>
<li<%= sidebar_current("docs-aws-datasource-iam-account-alias") %>>
<a href="/docs/providers/aws/d/iam_account_alias.html">aws_iam_account_alias</a>
</li>
Expand Down
83 changes: 83 additions & 0 deletions website/docs/d/glue_script.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
layout: "aws"
page_title: "AWS: aws_glue_script"
sidebar_current: "docs-aws-datasource-glue-script"
description: |-
Generate Glue script from Directed Acyclic Graph
---

# Data Source: aws_glue_script

Use this data source to generate a Glue script from a Directed Acyclic Graph (DAG).

## Example Usage

### Generate Python Script

```hcl
data "aws_glue_script" "example" {
language = "PYTHON"
dag_edge = [
# ...
]
dag_node = [
# ...
]
}
output "python_script" {
value = "${data.aws_glue_script.example.python_script}"
}
```

### Generate Scala Code

```hcl
data "aws_glue_script" "example" {
language = "SCALA"
dag_edge = [
# ...
]
dag_node = [
# ...
]
}
output "scala_code" {
value = "${data.aws_glue_script.example.scala_code}"
}
```

## Argument Reference

* `dag_edge` - (Required) A list of the edges in the DAG. Defined below.
* `dag_node` - (Required) A list of the nodes in the DAG. Defined below.
* `language` - (Optional) The programming language of the resulting code from the DAG. Defaults to `PYTHON`. Valid values are `PYTHON` and `SCALA`.

### dag_edge Argument Reference

* `source` - (Required) The ID of the node at which the edge starts.
* `target` - (Required) The ID of the node at which the edge ends.
* `target_parameter` - (Optional) The target of the edge.

### dag_node Argument Reference

* `args` - (Required) Nested configuration an argument or property of a node. Defined below.
* `id` - (Required) A node identifier that is unique within the node's graph.
* `node_type` - (Required) The type of node this is.
* `line_number` - (Optional) The line number of the node.

#### args Argument Reference

* `name` - (Required) The name of the argument or property.
* `value` - (Required) The value of the argument or property.
* `param` - (Optional) Boolean if the value is used as a parameter. Defaults to `false`.

## Attributes Reference

* `python_script` - The Python script generated from the DAG when the `language` argument is set to `PYTHON`.
* `scala_code` - The Scala code generated from the DAG when the `language` argument is set to `SCALA`.

0 comments on commit 198b6db

Please sign in to comment.