Skip to content

Commit

Permalink
Add RTS service (#10)
Browse files Browse the repository at this point in the history
* Add RTS service

* Add RTS service docs
  • Loading branch information
d-apurva authored and niuzhenguo committed Jul 18, 2018
1 parent d26c0a1 commit 703e769
Show file tree
Hide file tree
Showing 33 changed files with 2,980 additions and 1 deletion.
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

0 comments on commit 703e769

Please sign in to comment.