Skip to content

Commit

Permalink
Support: HPCS Resource and Datasource
Browse files Browse the repository at this point in the history
  • Loading branch information
kavya498 committed Jul 17, 2021
1 parent e94ae1a commit 34abfd4
Show file tree
Hide file tree
Showing 13 changed files with 1,645 additions and 62 deletions.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/IBM/go-sdk-core/v5 v5.5.1
github.com/IBM/ibm-cos-sdk-go v1.7.0
github.com/IBM/ibm-cos-sdk-go-config v1.2.0
github.com/IBM/ibm-hpcs-tke-sdk v0.0.0-20210716185544-e8403b3501ef
github.com/IBM/keyprotect-go-client v0.7.0
github.com/IBM/networking-go-sdk v0.18.0
github.com/IBM/platform-services-go-sdk v0.18.16
Expand Down Expand Up @@ -41,7 +42,7 @@ require (
github.com/minsikl/netscaler-nitro-go v0.0.0-20170827154432-5b14ce3643e3
github.com/mitchellh/go-homedir v1.1.0
github.com/softlayer/softlayer-go v1.0.3
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97
golang.org/x/tools v0.0.0-20210107193943-4ed967dd8eff // indirect
gotest.tools v2.2.0+incompatible
)
Expand Down
54 changes: 8 additions & 46 deletions go.sum

Large diffs are not rendered by default.

292 changes: 292 additions & 0 deletions ibm/data_source_ibm_hpcs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,292 @@
// Copyright IBM Corp. 2017, 2021 All Rights Reserved.
// Licensed under the Mozilla Public License v2.0

package ibm

import (
"context"
"fmt"

"github.com/IBM/ibm-hpcs-tke-sdk/tkesdk"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"

"github.com/IBM-Cloud/bluemix-go/api/resource/resourcev2/controllerv2"
"github.com/IBM-Cloud/bluemix-go/models"
)

func dataSourceIBMHPCS() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceIBMHPCSRead,

Schema: map[string]*schema.Schema{
"name": {
Description: "Resource instance name for example, myobjectstorage",
Type: schema.TypeString,
Required: true,
},

"resource_group_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "The id of the resource group in which the instance is present",
},

"location": {
Description: "The location or the environment in which instance exists",
Type: schema.TypeString,
Optional: true,
Computed: true,
},

"service": {
Description: "The service type of the instance",
Type: schema.TypeString,
Optional: true,
Default: "hs-crypto",
},
"units": {
Type: schema.TypeInt,
Computed: true,
Description: "The number of operational crypto units for your service instance",
},
"failover_units": {
Type: schema.TypeInt,
Computed: true,
Description: "The number of failover crypto units for your service instance",
},

"plan": {
Description: "The plan type of the instance",
Type: schema.TypeString,
Computed: true,
},

"status": {
Description: "The resource instance status",
Type: schema.TypeString,
Computed: true,
},

"crn": {
Type: schema.TypeString,
Computed: true,
Description: "CRN of resource instance",
},

"guid": {
Type: schema.TypeString,
Computed: true,
Description: "Guid of resource instance",
},
"extensions": {
Type: schema.TypeMap,
Computed: true,
Description: "The extended metadata as a map associated with the resource instance.",
},
"hsm_info": {
Type: schema.TypeList,
Computed: true,
Description: "HSM Info of HPCS CryptoUnits",
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"hsm_id": {
Type: schema.TypeString,
Computed: true,
},
"hsm_location": {
Type: schema.TypeString,
Computed: true,
},
"hsm_type": {
Type: schema.TypeString,
Computed: true,
},
"signature_threshold": {
Type: schema.TypeInt,
Computed: true,
},
"revocation_threshold": {
Type: schema.TypeInt,
Computed: true,
},
"current_mk_status": {
Type: schema.TypeString,
Computed: true,
},
"new_mk_status": {
Type: schema.TypeString,
Computed: true,
},
"current_mkvp": {
Type: schema.TypeString,
Computed: true,
},
"new_mkvp": {
Type: schema.TypeString,
Computed: true,
},
"admins": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Computed: true,
},
"ski": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
},
},
},
},
}
}

func dataSourceIBMHPCSRead(context context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
rsConClient, err := meta.(ClientSession).ResourceControllerAPIV2()
if err != nil {
return diag.FromErr(err)
}
rsAPI := rsConClient.ResourceServiceInstanceV2()
name := d.Get("name").(string)

rsInstQuery := controllerv2.ServiceInstanceQuery{
Name: name,
}

if rsGrpID, ok := d.GetOk("resource_group_id"); ok {
rsInstQuery.ResourceGroupID = rsGrpID.(string)
} else {
defaultRg, err := defaultResourceGroup(meta)
if err != nil {
return diag.FromErr(err)
}
rsInstQuery.ResourceGroupID = defaultRg
}

rsCatClient, err := meta.(ClientSession).ResourceCatalogAPI()
if err != nil {
return diag.FromErr(err)
}
rsCatRepo := rsCatClient.ResourceCatalog()

if service, ok := d.GetOk("service"); ok {

serviceOff, err := rsCatRepo.FindByName(service.(string), true)
if err != nil {
return diag.FromErr(fmt.Errorf("[ERROR] Error retrieving service offering: %s", err))
}

rsInstQuery.ServiceID = serviceOff[0].ID
}

var instances []models.ServiceInstanceV2

instances, err = rsAPI.ListInstances(rsInstQuery)
if err != nil {
return diag.FromErr(err)
}
var filteredInstances []models.ServiceInstanceV2
var location string

if loc, ok := d.GetOk("location"); ok {
location = loc.(string)
for _, instance := range instances {
if getLocation(instance) == location {
filteredInstances = append(filteredInstances, instance)
}
}
} else {
filteredInstances = instances
}

if len(filteredInstances) == 0 {
return diag.FromErr(fmt.Errorf("[ERROR] No resource instance found with name [%s]\nIf not specified please specify more filters like resource_group_id if instance doesn't exists in default group, location or service", name))
}

var instance models.ServiceInstanceV2

if len(filteredInstances) > 1 {
return diag.FromErr(fmt.Errorf(
"[ERROR] More than one resource instance found with name matching [%s]\nIf not specified please specify more filters like resource_group_id if instance doesn't exists in default group, location or service", name))
}
instance = filteredInstances[0]

d.SetId(instance.ID)
d.Set("status", instance.State)
d.Set("resource_group_id", instance.ResourceGroupID)
d.Set("location", instance.RegionID)
serviceOff, err := rsCatRepo.GetServiceName(instance.ServiceID)
if err != nil {
return diag.FromErr(fmt.Errorf("[ERROR] Error retrieving service offering: %s", err))
}

d.Set("service", serviceOff)
d.Set("guid", instance.Guid)
if len(instance.Extensions) == 0 {
d.Set("extensions", instance.Extensions)
} else {
d.Set("extensions", Flatten(instance.Extensions))
}
if instance.Parameters != nil {
if units, ok := instance.Parameters["units"]; ok {
d.Set("units", units)
}
if failover_units, ok := instance.Parameters["failover_units"]; ok {
d.Set("failover_units", failover_units)
}
}
servicePlan, err := rsCatRepo.GetServicePlanName(instance.ResourcePlanID)
if err != nil {
return diag.FromErr(fmt.Errorf("[ERROR] Error retrieving plan: %s", err))
}
d.Set("plan", servicePlan)
d.Set("crn", instance.Crn.String())

ci, err := hsmClient(d, meta)
if err != nil {
return diag.FromErr(err)
}
ci.InstanceId = instance.Guid
hsmInfo, err := tkesdk.Query(ci)
if err != nil {
return diag.FromErr(fmt.Errorf("[ERROR] Error Quering HSM config %s", err))
}
d.Set("hsm_info", FlattenHSMInfo(hsmInfo))

return nil
}

func FlattenHSMInfo(hsmInfo []tkesdk.HsmInfo) []map[string]interface{} {
info := make([]map[string]interface{}, 0)
for _, h := range hsmInfo {
hsm := make(map[string]interface{})
hsm["hsm_id"] = h.HsmId
hsm["hsm_location"] = h.HsmLocation
hsm["hsm_type"] = h.HsmType
hsm["signature_threshold"] = h.SignatureThreshold
hsm["revocation_threshold"] = h.RevocationThreshold
hsm["current_mk_status"] = h.CurrentMKStatus
hsm["new_mk_status"] = h.NewMKStatus
hsm["current_mkvp"] = h.CurrentMKVP
hsm["new_mkvp"] = h.NewMKVP
admin := make([]map[string]interface{}, 0)
for _, a := range h.Admins {
ad := make(map[string]interface{})
ad["name"] = a.AdminName
ad["ski"] = a.AdminSKI
admin = append(admin, ad)
}
hsm["admins"] = admin
info = append(info, hsm)
}
return info
}
38 changes: 38 additions & 0 deletions ibm/data_source_ibm_hpcs_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright IBM Corp. 2017, 2021 All Rights Reserved.
// Licensed under the Mozilla Public License v2.0

package ibm

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAccIBMHPCSDatasourceBasic(t *testing.T) {
instanceName := "test-hpcs"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccCheckIBMHPCSDatasourceConfig(instanceName),
Destroy: true,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("data.ibm_hpcs.hpcs", "name", instanceName),
resource.TestCheckResourceAttr("data.ibm_hpcs.hpcs", "service", "hs-crypto"),
),
},
},
})
}

func testAccCheckIBMHPCSDatasourceConfig(instanceName string) string {
return fmt.Sprintf(`
data "ibm_hpcs" "hpcs" {
name = "%s"
}
`, instanceName)

}
12 changes: 0 additions & 12 deletions ibm/internal/hashcode/hashcode.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,6 @@ import (
)

// String hashes a string to a unique hashcode.
//
// Deprecated: This will be removed in v2 without replacement. If you need
// its functionality, you can copy it, import crc32 directly, or reference the
// v1 package.
//
// crc32 returns a uint32, but for our use we need
// and non negative integer. Here we cast to an integer
// and invert it if the result is negative.
func String(s string) int {
v := int(crc32.ChecksumIEEE([]byte(s)))
if v >= 0 {
Expand All @@ -31,10 +23,6 @@ func String(s string) int {
}

// Strings hashes a list of strings to a unique hashcode.
//
// Deprecated: This will be removed in v2 without replacement. If you need
// its functionality, you can copy it, import crc32 directly, or reference the
// v1 package.
func Strings(strings []string) string {
var buf bytes.Buffer

Expand Down
3 changes: 3 additions & 0 deletions ibm/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,7 @@ func Provider() *schema.Provider {
"ibm_dns_domain": dataSourceIBMDNSDomain(),
"ibm_dns_secondary": dataSourceIBMDNSSecondary(),
"ibm_event_streams_topic": dataSourceIBMEventStreamsTopic(),
"ibm_hpcs": dataSourceIBMHPCS(),
"ibm_iam_access_group": dataSourceIBMIAMAccessGroup(),
"ibm_iam_account_settings": dataSourceIBMIAMAccountSettings(),
"ibm_iam_auth_token": dataSourceIBMIAMAuthToken(),
Expand Down Expand Up @@ -479,6 +480,7 @@ func Provider() *schema.Provider {
"ibm_event_streams_topic": resourceIBMEventStreamsTopic(),
"ibm_firewall": resourceIBMFirewall(),
"ibm_firewall_policy": resourceIBMFirewallPolicy(),
"ibm_hpcs": resourceIBMHPCS(),
"ibm_iam_access_group": resourceIBMIAMAccessGroup(),
"ibm_iam_account_settings": resourceIbmIamAccountSettings(),
"ibm_iam_custom_role": resourceIBMIAMCustomRole(),
Expand Down Expand Up @@ -687,6 +689,7 @@ func Validator() ValidatorDict {
"ibm_function_rule": resourceIBMFuncRuleValidator(),
"ibm_function_trigger": resourceIBMFuncTriggerValidator(),
"ibm_function_namespace": resourceIBMFuncNamespaceValidator(),
"ibm_hpcs": resourceIBMHPCSValidator(),
"ibm_is_dedicated_host_group": resourceIbmIsDedicatedHostGroupValidator(),
"ibm_is_dedicated_host": resourceIbmIsDedicatedHostValidator(),
"ibm_is_dedicated_host_disk_management": resourceIBMISDedicatedHostDiskManagementValidator(),
Expand Down
Loading

0 comments on commit 34abfd4

Please sign in to comment.