-
Notifications
You must be signed in to change notification settings - Fork 9.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New Data Source: aws_glue_script #4481
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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, | ||
}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you could argue these could be one field, in case additional languages are added in the future? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure why the Glue API distinguishes between the return values. It only returns one of them at a time currently 😕 Maybe it will return multiple in the future. We tend to opt for sticking with API rather than making our own choices for UX due to past maintenance issues. I'm tempted to leave this as-is hoping that AWS has a good reason for this API design decision. |
||
}, | ||
} | ||
} | ||
|
||
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 | ||
} |
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) | ||
} |
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 = [ | ||
# ... | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it'd be good to give a working example here imo |
||
] | ||
} | ||
|
||
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`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would this be better as Required with no default set?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It defaults to Python if you do not provide a value 😉