Skip to content

Commit

Permalink
Support data volume in instance group.
Browse files Browse the repository at this point in the history
  • Loading branch information
deepaksibm authored and hkantare committed May 26, 2021
1 parent 224f4f7 commit a517b7a
Show file tree
Hide file tree
Showing 8 changed files with 421 additions and 62 deletions.
54 changes: 54 additions & 0 deletions examples/ibm-is-ng/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,60 @@ resource "ibm_is_subnet" "subnet1" {
ipv4_cidr_block = "10.240.0.0/28"
}

resource "ibm_is_instance_template" "instancetemplate1" {
name = "testtemplate"
image = "r006-14140f94-fcc4-11e9-96e7-a72723715315"
profile = "bx2-8x32"

primary_network_interface {
subnet = ibm_is_subnet.subnet2.id
allow_ip_spoofing = true
}

vpc = ibm_is_vpc.vpc2.id
zone = "us-south-2"
keys = [ibm_is_ssh_key.sshkey.id]

boot_volume {
name = "testbootvol"
delete_volume_on_instance_delete = true
}
volume_attachments {
delete_volume_on_instance_delete = true
name = "volatt-01"
volume_prototype {
iops = 3000
profile = "general-purpose"
capacity = 200
}
}
}

resource "ibm_is_instance_template" "instancetemplate2" {
name = "testtemplate1"
image = "r006-14140f94-fcc4-11e9-96e7-a72723715315"
profile = "bx2-8x32"

primary_network_interface {
subnet = ibm_is_subnet.subnet2.id
allow_ip_spoofing = true
}

vpc = ibm_is_vpc.vpc2.id
zone = "us-south-2"
keys = [ibm_is_ssh_key.sshkey.id]

boot_volume {
name = "testbootvol"
delete_volume_on_instance_delete = true
}
volume_attachments {
delete_volume_on_instance_delete = true
name = "volatt-01"
volume = ibm_is_volume.vol1.id
}
}

resource "ibm_is_lb" "lb2" {
name = "mylb"
subnets = [ibm_is_subnet.subnet1.id]
Expand Down
54 changes: 53 additions & 1 deletion ibm/data_source_ibm_is_instance_templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,34 @@ func dataSourceIBMISInstanceTemplates() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},
isInstanceTemplateVolAttVolPrototype: {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
isInstanceTemplateVolAttVolIops: {
Type: schema.TypeInt,
Computed: true,
Description: "The maximum I/O operations per second (IOPS) for the volume.",
},
isInstanceTemplateVolAttVolProfile: {
Type: schema.TypeString,
Computed: true,
Description: "The globally unique name for the volume profile to use for this volume.",
},
isInstanceTemplateVolAttVolCapacity: {
Type: schema.TypeInt,
Computed: true,
Description: "The capacity of the volume in gigabytes. The specified minimum and maximum capacity values for creating or updating volumes may expand in the future.",
},
isInstanceTemplateVolAttVolEncryptionKey: {
Type: schema.TypeString,
Computed: true,
Description: "The CRN of the [Key Protect Root Key](https://cloud.ibm.com/docs/key-protect?topic=key-protect-getting-started-tutorial) or [Hyper Protect Crypto Service Root Key](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-get-started) for this resource.",
},
},
},
},
},
},
},
Expand Down Expand Up @@ -387,7 +415,31 @@ func dataSourceIBMISInstanceTemplatesRead(d *schema.ResourceData, meta interface
volumeAttach[isInstanceTemplateDeleteVolume] = *volume.DeleteVolumeOnInstanceDelete
volumeIntf := volume.Volume
volumeInst := volumeIntf.(*vpcv1.VolumeAttachmentVolumePrototypeInstanceContext)
volumeAttach[isInstanceTemplateVolAttVolume] = volumeInst.Name
newVolumeArr := []map[string]interface{}{}
newVolume := map[string]interface{}{}

if volumeInst.ID != nil {
volumeAttach[isInstanceTemplateVolAttVolume] = *volumeInst.ID
}

if volumeInst.Capacity != nil {
newVolume[isInstanceTemplateVolAttVolCapacity] = *volumeInst.Capacity
}
if volumeInst.Profile != nil {
profile := volumeInst.Profile.(*vpcv1.VolumeProfileIdentity)
newVolume[isInstanceTemplateVolAttVolProfile] = profile.Name
}

if volumeInst.Iops != nil {
newVolume[isInstanceTemplateVolAttVolIops] = *volumeInst.Iops
}
if volumeInst.EncryptionKey != nil {
encryptionKey := volumeInst.EncryptionKey.(*vpcv1.EncryptionKeyIdentity)
newVolume[isInstanceTemplateVolAttVolEncryptionKey] = *encryptionKey.CRN
}
newVolumeArr = append(newVolumeArr, newVolume)
volumeAttach[isInstanceTemplateVolAttVolPrototype] = newVolumeArr

interfacesList = append(interfacesList, volumeAttach)
}
template[isInstanceTemplateVolumeAttachments] = interfacesList
Expand Down
2 changes: 1 addition & 1 deletion ibm/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ func init() {
isImage = os.Getenv("IS_IMAGE")
if isImage == "" {
//isImage = "fc538f61-7dd6-4408-978c-c6b85b69fe76" // for classic infrastructure
isImage = "r006-ed3f775f-ad7e-4e37-ae62-7199b4988b00" // for next gen infrastructure
isImage = "r006-5b05b4fe-bcbc-4309-ad45-3354813227a0" // for next gen infrastructure
fmt.Println("[INFO] Set the environment variable IS_IMAGE for testing ibm_is_instance, ibm_is_floating_ip else it is set to default value 'r006-ed3f775f-ad7e-4e37-ae62-7199b4988b00'")
}

Expand Down
144 changes: 118 additions & 26 deletions ibm/resource_ibm_is_instance_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import (
const (
isInstanceTemplateBootVolume = "boot_volume"
isInstanceTemplateVolAttVolAutoDelete = "auto_delete"
isInstanceTemplateVolAttVol = "volume"
isInstanceTemplateVolAttachmentName = "name"
isInstanceTemplateVolAttVolPrototype = "volume_prototype"
isInstanceTemplateVolAttVolCapacity = "capacity"
isInstanceTemplateVolAttVolIops = "iops"
isInstanceTemplateVolAttVolName = "name"
Expand Down Expand Up @@ -52,10 +55,17 @@ func resourceIBMISInstanceTemplate() *schema.Resource {
Exists: resourceIBMisInstanceTemplateExists,
Importer: &schema.ResourceImporter{},

CustomizeDiff: customdiff.Sequence(
func(_ context.Context, diff *schema.ResourceDiff, v interface{}) error {
return resourceTagsCustomizeDiff(diff)
},
CustomizeDiff: customdiff.All(
customdiff.Sequence(
func(_ context.Context, diff *schema.ResourceDiff, v interface{}) error {
return resourceTagsCustomizeDiff(diff)
},
),

customdiff.Sequence(
func(_ context.Context, diff *schema.ResourceDiff, v interface{}) error {
return resourceVolumeAttachmentValidate(diff)
}),
),

Schema: map[string]*schema.Schema{
Expand Down Expand Up @@ -104,16 +114,55 @@ func resourceIBMISInstanceTemplate() *schema.Resource {
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
isInstanceTemplateVolumeDeleteOnInstanceDelete: {
Type: schema.TypeBool,
Required: true,
Type: schema.TypeBool,
Required: true,
Description: "If set to true, when deleting the instance the volume will also be deleted.",
},
"name": {
Type: schema.TypeString,
Required: true,
isInstanceTemplateVolAttachmentName: {
Type: schema.TypeString,
Required: true,
Description: "The user-defined name for this volume attachment.",
},
"volume": {
Type: schema.TypeString,
Required: true,
isInstanceTemplateVolAttVol: {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Description: "The unique identifier for this volume.",
},
isInstanceTemplateVolAttVolPrototype: {
Type: schema.TypeList,
MaxItems: 1,
MinItems: 1,
Optional: true,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
isInstanceTemplateVolAttVolIops: {
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
Description: "The maximum I/O operations per second (IOPS) for the volume.",
},
isInstanceTemplateVolAttVolProfile: {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "The globally unique name for the volume profile to use for this volume.",
},
isInstanceTemplateVolAttVolCapacity: {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
Description: "The capacity of the volume in gigabytes. The specified minimum and maximum capacity values for creating or updating volumes may expand in the future.",
},
isInstanceTemplateVolAttVolEncryptionKey: {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Description: "The CRN of the [Key Protect Root Key](https://cloud.ibm.com/docs/key-protect?topic=key-protect-getting-started-tutorial) or [Hyper Protect Crypto Service Root Key](https://cloud.ibm.com/docs/hs-crypto?topic=hs-crypto-get-started) for this resource.",
},
},
},
},
},
},
Expand Down Expand Up @@ -430,17 +479,43 @@ func instanceTemplateCreate(d *schema.ResourceData, meta interface{}, profile, n
for _, resource := range vols {
vol := resource.(map[string]interface{})
volInterface := &vpcv1.VolumeAttachmentPrototypeInstanceContext{}
deleteVol, _ := vol[isInstanceTemplateVolumeDeleteOnInstanceDelete]
deleteVolBool := deleteVol.(bool)
deleteVolBool := vol[isInstanceTemplateVolumeDeleteOnInstanceDelete].(bool)
volInterface.DeleteVolumeOnInstanceDelete = &deleteVolBool
name, _ := vol["name"]
namestr := name.(string)
volInterface.Name = &namestr
volintf, _ := vol["volume"]
volintfstr := volintf.(string)
volInterface.Volume = &vpcv1.VolumeAttachmentVolumePrototypeInstanceContext{
ID: &volintfstr,
attachmentnamestr := vol[isInstanceTemplateVolAttachmentName].(string)
volInterface.Name = &attachmentnamestr
volIdStr := vol[isInstanceTemplateVolAttVol].(string)

if volIdStr != "" {
volInterface.Volume = &vpcv1.VolumeAttachmentVolumePrototypeInstanceContextVolumeIdentity{
ID: &volIdStr,
}
} else {
newvolintf := vol[isInstanceTemplateVolAttVolPrototype].([]interface{})[0]
newvol := newvolintf.(map[string]interface{})
profileName := newvol[isInstanceTemplateVolAttVolProfile].(string)
capacity := int64(newvol[isInstanceTemplateVolAttVolCapacity].(int))

volPrototype := &vpcv1.VolumeAttachmentVolumePrototypeInstanceContextVolumePrototypeInstanceContext{
Profile: &vpcv1.VolumeProfileIdentity{
Name: &profileName,
},
Capacity: &capacity,
}
iops := int64(newvol[isInstanceTemplateVolAttVolIops].(int))
encryptionKey := newvol[isInstanceTemplateVolAttVolEncryptionKey].(string)

if iops != 0 {
volPrototype.Iops = &iops
}

if encryptionKey != "" {
volPrototype.EncryptionKey = &vpcv1.EncryptionKeyIdentity{
CRN: &encryptionKey,
}
}
volInterface.Volume = volPrototype
}

intfs = append(intfs, *volInterface)
}
instanceproto.VolumeAttachments = intfs
Expand Down Expand Up @@ -679,16 +754,33 @@ func instanceTemplateGet(d *schema.ResourceData, meta interface{}, ID string) er
volumeAttach := map[string]interface{}{}
volumeAttach[isInstanceTemplateVolAttName] = *volume.Name
volumeAttach[isInstanceTemplateDeleteVolume] = *volume.DeleteVolumeOnInstanceDelete
volumeID := map[string]interface{}{}
newVolumeArr := []map[string]interface{}{}
newVolume := map[string]interface{}{}
volumeIntf := volume.Volume
volumeInst := volumeIntf.(*vpcv1.VolumeAttachmentVolumePrototypeInstanceContext)
if volumeInst.Name != nil {
volumeID["name"] = *volumeInst.Name
if volumeInst.ID != nil {
volumeAttach[isInstanceTemplateVolAttVol] = *volumeInst.ID
}

if volumeInst.Capacity != nil {
newVolume[isInstanceTemplateVolAttVolCapacity] = *volumeInst.Capacity
}
if volumeInst.Profile != nil {
profile := volumeInst.Profile.(*vpcv1.VolumeProfileIdentity)
newVolume[isInstanceTemplateVolAttVolProfile] = profile.Name
}

if volumeInst.Iops != nil {
volumeID["iops"] = *volumeInst.Iops
newVolume[isInstanceTemplateVolAttVolIops] = *volumeInst.Iops
}
if volumeInst.EncryptionKey != nil {
encryptionKey := volumeInst.EncryptionKey.(*vpcv1.EncryptionKeyIdentity)
newVolume[isInstanceTemplateVolAttVolEncryptionKey] = *encryptionKey.CRN
}
if len(newVolume) > 0 {
newVolumeArr = append(newVolumeArr, newVolume)
}
volumeAttach[isInstanceTemplateVolAttVolume] = volumeID
volumeAttach[isInstanceTemplateVolAttVolPrototype] = newVolumeArr
interfacesList = append(interfacesList, volumeAttach)
}
d.Set(isInstanceTemplateVolumeAttachments, interfacesList)
Expand Down
Loading

0 comments on commit a517b7a

Please sign in to comment.