Skip to content
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

Add RTS service #10

Merged
merged 2 commits into from
Jul 18, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions huaweicloud/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -500,3 +500,10 @@ func (c *Config) getHwEndpointType() golangsdk.Availability {
}
return golangsdk.AvailabilityPublic
}

func (c *Config) orchestrationV1Client(region string) (*golangsdk.ServiceClient, error) {
return huaweisdk.NewOrchestrationV1(c.HwClient, golangsdk.EndpointOpts{
Region: c.determineRegion(region),
Availability: c.getHwEndpointType(),
})
}
95 changes: 95 additions & 0 deletions huaweicloud/data_source_huaweicloud_rts_stack_resource_v1.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package huaweicloud

import (
"fmt"

"github.com/hashicorp/terraform/helper/schema"
"github.com/huaweicloud/golangsdk/openstack/rts/v1/stackresources"
)

func dataSourceRTSStackResourcesV1() *schema.Resource {
return &schema.Resource{
Read: dataSourceRTSStackResourcesV1Read,

Schema: map[string]*schema.Schema{
"region": &schema.Schema{
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"stack_name": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"resource_name": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"logical_resource_id": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"required_by": &schema.Schema{
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
"resource_status": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"resource_status_reason": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"physical_resource_id": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"resource_type": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
},
}
}

func dataSourceRTSStackResourcesV1Read(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
orchestrationClient, err := config.orchestrationV1Client(GetRegion(d, config))

listOpts := stackresources.ListOpts{
Name: d.Get("resource_name").(string),
PhysicalID: d.Get("physical_resource_id").(string),
Type: d.Get("resource_type").(string),
}

refinedResources, err := stackresources.List(orchestrationClient, d.Get("stack_name").(string), listOpts)
if err != nil {
return fmt.Errorf("Unable to retrieve Stack Resources: %s", err)
}

if len(refinedResources) < 1 {
return fmt.Errorf("No matching resource found. " +
"Please change your search criteria and try again.")
}

if len(refinedResources) > 1 {
return fmt.Errorf("Multiple resources matched; use additional constraints to reduce matches to a single resource")
}

stackResource := refinedResources[0]
d.SetId(stackResource.PhysicalID)

d.Set("resource_name", stackResource.Name)
d.Set("resource_status", stackResource.Status)
d.Set("logical_resource_id", stackResource.LogicalID)
d.Set("physical_resource_id", stackResource.PhysicalID)
d.Set("required_by", stackResource.RequiredBy)
d.Set("resource_status_reason", stackResource.StatusReason)
d.Set("resource_type", stackResource.Type)
d.Set("region", GetRegion(d, config))
return nil
}
89 changes: 89 additions & 0 deletions huaweicloud/data_source_huaweicloud_rts_stack_resource_v1_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package huaweicloud

import (
"fmt"
"testing"

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

func TestAccRTSStackResourcesV1DataSource_basic(t *testing.T) {

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccDataSourceRTSStackResourcesV1Config,
Check: resource.ComposeTestCheckFunc(
testAccCheckRTSStackResourcesV1DataSourceID("data.huaweicloud_rts_stack_resource_v1.resource_1"),
resource.TestCheckResourceAttr(
"data.huaweicloud_rts_stack_resource_v1.resource_1", "resource_name", "random"),
resource.TestCheckResourceAttr(
"data.huaweicloud_rts_stack_resource_v1.resource_1", "resource_type", "OS::Heat::RandomString"),
resource.TestCheckResourceAttr(
"data.huaweicloud_rts_stack_resource_v1.resource_1", "resource_status", "CREATE_COMPLETE"),
),
},
},
})
}

func testAccCheckRTSStackResourcesV1DataSourceID(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Can't find stack resource data source: %s", n)
}

if rs.Primary.ID == "" {
return fmt.Errorf("stack resource data source ID not set")
}

return nil
}
}

const testAccDataSourceRTSStackResourcesV1Config = `

resource "huaweicloud_rts_stack_v1" "stack_1" {
name = "huaweicloud_rts_stack"
disable_rollback= true
timeout_mins=60
template_body = <<JSON
{
"outputs": {
"str1": {
"description": "The description of the nat server.",
"value": {
"get_resource": "random"
}
}
},
"heat_template_version": "2013-05-23",
"description": "A HOT template that create a single server and boot from volume.",
"parameters": {
"key_name": {
"type": "string",
"description": "Name of existing key pair for the instance to be created.",
"default": "KeyPair-click2cloud"
}
},
"resources": {
"random": {
"type": "OS::Heat::RandomString",
"properties": {
"length": "6"
}
}
}
}
JSON
}

data "huaweicloud_rts_stack_resource_v1" "resource_1" {
stack_name = "${huaweicloud_rts_stack_v1.stack_1.name}"
resource_name = "random"
}
`
121 changes: 121 additions & 0 deletions huaweicloud/data_source_huaweicloud_rts_stack_v1.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package huaweicloud

import (
"fmt"
"log"
"reflect"
"unsafe"

"github.com/hashicorp/errwrap"
"github.com/hashicorp/terraform/helper/schema"
"github.com/huaweicloud/golangsdk/openstack/rts/v1/stacks"
"github.com/huaweicloud/golangsdk/openstack/rts/v1/stacktemplates"
)

func dataSourceRTSStackV1() *schema.Resource {
return &schema.Resource{
Read: dataSourceRTSStackV1Read,

Schema: map[string]*schema.Schema{
"region": &schema.Schema{
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
},
"status": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"name": &schema.Schema{
Type: schema.TypeString,
Required: true,
},
"status_reason": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"outputs": {
Type: schema.TypeMap,
Computed: true,
},
"parameters": &schema.Schema{
Type: schema.TypeMap,
Computed: true,
},
"timeout_mins": &schema.Schema{
Type: schema.TypeInt,
Computed: true,
},
"disable_rollback": &schema.Schema{
Type: schema.TypeBool,
Computed: true,
},
"capabilities": &schema.Schema{
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
"notification_topics": &schema.Schema{
Type: schema.TypeSet,
Computed: true,
Elem: &schema.Schema{Type: schema.TypeString},
Set: schema.HashString,
},
"template_body": {
Type: schema.TypeString,
Computed: true,
},
},
}
}

func dataSourceRTSStackV1Read(d *schema.ResourceData, meta interface{}) error {
config := meta.(*Config)
orchestrationClient, err := config.orchestrationV1Client(GetRegion(d, config))
if err != nil {
return fmt.Errorf("Error creating OpenTelekomCloud rts client: %s", err)
}
stackName := d.Get("name").(string)

stack, err := stacks.Get(orchestrationClient, stackName).Extract()
if err != nil {
return fmt.Errorf("Unable to retrieve stack %s: %s", stackName, err)
}

log.Printf("[INFO] Retrieved Stack %s", stackName)
d.SetId(stack.ID)

d.Set("disable_rollback", stack.DisableRollback)

d.Set("parameters", stack.Parameters)
d.Set("status_reason", stack.StatusReason)
d.Set("name", stack.Name)
d.Set("outputs", flattenStackOutputs(stack.Outputs))
d.Set("capabilities", stack.Capabilities)
d.Set("notification_topics", stack.NotificationTopics)
d.Set("timeout_mins", stack.Timeout)
d.Set("status", stack.Status)
d.Set("region", GetRegion(d, config))

out, err := stacktemplates.Get(orchestrationClient, stack.Name, stack.ID).Extract()
if err != nil {
return err
}

sTemplate := BytesToString(out)
template, error := normalizeStackTemplate(sTemplate)
if error != nil {
return errwrap.Wrapf("template body contains an invalid JSON or YAML: {{err}}", err)
}
d.Set("template_body", template)

return nil
}

func BytesToString(b []byte) string {
bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
sh := reflect.StringHeader{Data: bh.Data, Len: bh.Len}
return *(*string)(unsafe.Pointer(&sh))
}
Loading