diff --git a/go.mod b/go.mod index a550120bede..2dae4a8eccd 100644 --- a/go.mod +++ b/go.mod @@ -28,7 +28,7 @@ require ( github.com/IBM/scc-go-sdk/v4 v4.0.2 github.com/IBM/schematics-go-sdk v0.2.1 github.com/IBM/secrets-manager-go-sdk v1.0.49 - github.com/IBM/vpc-go-sdk v0.30.0 + github.com/IBM/vpc-go-sdk v0.32.0 github.com/ScaleFT/sshkeys v0.0.0-20200327173127-6142f742bca5 github.com/Shopify/sarama v1.29.1 github.com/apache/openwhisk-client-go v0.0.0-20200201143223-a804fb82d105 diff --git a/go.sum b/go.sum index 6397f99b42a..655bff5ff21 100644 --- a/go.sum +++ b/go.sum @@ -99,8 +99,8 @@ github.com/IBM/schematics-go-sdk v0.2.1 h1:byATysGD+Z1k/wdtNqQmKALcAPjgSLuSyzcab github.com/IBM/schematics-go-sdk v0.2.1/go.mod h1:Tw2OSAPdpC69AxcwoyqcYYaGTTW6YpERF9uNEU+BFRQ= github.com/IBM/secrets-manager-go-sdk v1.0.50-0.20230202132733-fd8f31729d57 h1:/l0OC4K6m+xiruPvXiOtqawg+uwwg+18e8LqEAIUcyk= github.com/IBM/secrets-manager-go-sdk v1.0.50-0.20230202132733-fd8f31729d57/go.mod h1:QyDSznC6gJEXIGaj+JPxoEVtyXfkaxzId87mxcEb+vM= -github.com/IBM/vpc-go-sdk v0.30.0 h1:OCHTcU6j4tFmpoW/SJD58UjfmtuPz9SvRxc5V9qBY8g= -github.com/IBM/vpc-go-sdk v0.30.0/go.mod h1:jYjS3EySPkC7DuOg33gMHtm8DcIf75Tc+Gxo3zmMBTQ= +github.com/IBM/vpc-go-sdk v0.32.0 h1:LDuU8xkeBISvLc6/artN7aQ1YsdKvDWRXalfsPHUBu4= +github.com/IBM/vpc-go-sdk v0.32.0/go.mod h1:jYjS3EySPkC7DuOg33gMHtm8DcIf75Tc+Gxo3zmMBTQ= github.com/Logicalis/asn1 v0.0.0-20190312173541-d60463189a56 h1:vuquMR410psHNax14XKNWa0Ae/kYgWJcXi0IFuX60N0= github.com/Logicalis/asn1 v0.0.0-20190312173541-d60463189a56/go.mod h1:Zb3OT4l0mf7P/GOs2w2Ilj5sdm5Whoq3pa24dAEBHFc= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= diff --git a/ibm/service/vpc/data_source_ibm_is_instance.go b/ibm/service/vpc/data_source_ibm_is_instance.go index d53debad958..7b101b01a71 100644 --- a/ibm/service/vpc/data_source_ibm_is_instance.go +++ b/ibm/service/vpc/data_source_ibm_is_instance.go @@ -59,7 +59,32 @@ func DataSourceIBMISInstance() *schema.Resource { Computed: true, Description: "Indicates whether the metadata service endpoint is available to the virtual server instance", }, + isInstanceMetadataService: { + Type: schema.TypeList, + Computed: true, + Description: "The metadata service configuration", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + isInstanceMetadataServiceEnabled1: { + Type: schema.TypeBool, + Computed: true, + Description: "Indicates whether the metadata service endpoint will be available to the virtual server instance", + }, + isInstanceMetadataServiceProtocol: { + Type: schema.TypeString, + Computed: true, + Description: "The communication protocol to use for the metadata service endpoint. Applies only when the metadata service is enabled.", + }, + + isInstanceMetadataServiceRespHopLimit: { + Type: schema.TypeInt, + Computed: true, + Description: "The hop limit (IP time to live) for IP response packets from the metadata service", + }, + }, + }, + }, isInstancePEM: { Type: schema.TypeString, Optional: true, @@ -713,7 +738,22 @@ func instanceGetByName(d *schema.ResourceData, meta interface{}, name string) er } if instance.MetadataService != nil { d.Set(isInstanceMetadataServiceEnabled, instance.MetadataService.Enabled) + + metadataService := []map[string]interface{}{} + metadataServiceMap := map[string]interface{}{} + + metadataServiceMap[isInstanceMetadataServiceEnabled1] = instance.MetadataService.Enabled + if instance.MetadataService.Protocol != nil { + metadataServiceMap[isInstanceMetadataServiceProtocol] = instance.MetadataService.Protocol + } + if instance.MetadataService.ResponseHopLimit != nil { + metadataServiceMap[isInstanceMetadataServiceRespHopLimit] = instance.MetadataService.ResponseHopLimit + } + + metadataService = append(metadataService, metadataServiceMap) + d.Set(isInstanceMetadataService, metadataService) } + if instance.AvailabilityPolicy != nil && instance.AvailabilityPolicy.HostFailure != nil { d.Set(isInstanceAvailablePolicyHostFailure, *instance.AvailabilityPolicy.HostFailure) } diff --git a/ibm/service/vpc/data_source_ibm_is_instance_template.go b/ibm/service/vpc/data_source_ibm_is_instance_template.go index 44a07f5696f..e725cab0baf 100644 --- a/ibm/service/vpc/data_source_ibm_is_instance_template.go +++ b/ibm/service/vpc/data_source_ibm_is_instance_template.go @@ -120,6 +120,32 @@ func DataSourceIBMISInstanceTemplate() *schema.Resource { Computed: true, Description: "Indicates whether the metadata service endpoint is available to the virtual server instance", }, + isInstanceMetadataService: { + Type: schema.TypeList, + Computed: true, + Description: "The metadata service configuration", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + isInstanceMetadataServiceEnabled1: { + Type: schema.TypeBool, + Computed: true, + Description: "Indicates whether the metadata service endpoint will be available to the virtual server instance", + }, + + isInstanceMetadataServiceProtocol: { + Type: schema.TypeString, + Computed: true, + Description: "The communication protocol to use for the metadata service endpoint. Applies only when the metadata service is enabled.", + }, + + isInstanceMetadataServiceRespHopLimit: { + Type: schema.TypeInt, + Computed: true, + Description: "The hop limit (IP time to live) for IP response packets from the metadata service", + }, + }, + }, + }, isInstanceAvailablePolicyHostFailure: { Type: schema.TypeString, Computed: true, @@ -448,6 +474,20 @@ func dataSourceIBMISInstanceTemplateRead(context context.Context, d *schema.Reso if instance.MetadataService != nil { d.Set(isInstanceTemplateMetadataServiceEnabled, instance.MetadataService.Enabled) + + metadataService := []map[string]interface{}{} + metadataServiceMap := map[string]interface{}{} + + metadataServiceMap[isInstanceMetadataServiceEnabled1] = instance.MetadataService.Enabled + if instance.MetadataService.Protocol != nil { + metadataServiceMap[isInstanceMetadataServiceProtocol] = instance.MetadataService.Protocol + } + if instance.MetadataService.ResponseHopLimit != nil { + metadataServiceMap[isInstanceMetadataServiceRespHopLimit] = instance.MetadataService.ResponseHopLimit + } + + metadataService = append(metadataService, metadataServiceMap) + d.Set(isInstanceMetadataService, metadataService) } if instance.Profile != nil { @@ -729,6 +769,19 @@ func dataSourceIBMISInstanceTemplateRead(context context.Context, d *schema.Reso if instance.MetadataService != nil { d.Set(isInstanceTemplateMetadataServiceEnabled, instance.MetadataService.Enabled) + metadataService := []map[string]interface{}{} + metadataServiceMap := map[string]interface{}{} + + metadataServiceMap[isInstanceMetadataServiceEnabled1] = instance.MetadataService.Enabled + if instance.MetadataService.Protocol != nil { + metadataServiceMap[isInstanceMetadataServiceProtocol] = instance.MetadataService.Protocol + } + if instance.MetadataService.ResponseHopLimit != nil { + metadataServiceMap[isInstanceMetadataServiceRespHopLimit] = instance.MetadataService.ResponseHopLimit + } + + metadataService = append(metadataService, metadataServiceMap) + d.Set(isInstanceMetadataService, metadataService) } if instance.Profile != nil { diff --git a/ibm/service/vpc/data_source_ibm_is_instance_templates.go b/ibm/service/vpc/data_source_ibm_is_instance_templates.go index b57ece64a5f..02db3fa65f7 100644 --- a/ibm/service/vpc/data_source_ibm_is_instance_templates.go +++ b/ibm/service/vpc/data_source_ibm_is_instance_templates.go @@ -111,6 +111,32 @@ func DataSourceIBMISInstanceTemplates() *schema.Resource { Computed: true, Description: "Indicates whether the metadata service endpoint is available to the virtual server instance", }, + isInstanceMetadataService: { + Type: schema.TypeList, + Computed: true, + Description: "The metadata service configuration", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + isInstanceMetadataServiceEnabled1: { + Type: schema.TypeBool, + Computed: true, + Description: "Indicates whether the metadata service endpoint will be available to the virtual server instance", + }, + + isInstanceMetadataServiceProtocol: { + Type: schema.TypeString, + Computed: true, + Description: "The communication protocol to use for the metadata service endpoint. Applies only when the metadata service is enabled.", + }, + + isInstanceMetadataServiceRespHopLimit: { + Type: schema.TypeInt, + Computed: true, + Description: "The hop limit (IP time to live) for IP response packets from the metadata service", + }, + }, + }, + }, isInstanceTemplatesHref: { Type: schema.TypeString, Computed: true, @@ -151,6 +177,7 @@ func DataSourceIBMISInstanceTemplates() *schema.Resource { Computed: true, Description: "The unique identifier or CRN of the default IAM trusted profile to use for this virtual server instance.", }, + isInstanceTemplateVolumeAttachments: { Type: schema.TypeList, Computed: true, @@ -473,6 +500,20 @@ func dataSourceIBMISInstanceTemplatesRead(d *schema.ResourceData, meta interface if instance.MetadataService != nil { template[isInstanceTemplateMetadataServiceEnabled] = *instance.MetadataService.Enabled + + metadataService := []map[string]interface{}{} + metadataServiceMap := map[string]interface{}{} + + metadataServiceMap[isInstanceMetadataServiceEnabled1] = instance.MetadataService.Enabled + if instance.MetadataService.Protocol != nil { + metadataServiceMap[isInstanceMetadataServiceProtocol] = instance.MetadataService.Protocol + } + if instance.MetadataService.ResponseHopLimit != nil { + metadataServiceMap[isInstanceMetadataServiceRespHopLimit] = instance.MetadataService.ResponseHopLimit + } + + metadataService = append(metadataService, metadataServiceMap) + template[isInstanceMetadataService] = metadataService } if instance.AvailabilityPolicy != nil && instance.AvailabilityPolicy.HostFailure != nil { diff --git a/ibm/service/vpc/data_source_ibm_is_instances.go b/ibm/service/vpc/data_source_ibm_is_instances.go index 149793e5b19..414748d1dbe 100644 --- a/ibm/service/vpc/data_source_ibm_is_instances.go +++ b/ibm/service/vpc/data_source_ibm_is_instances.go @@ -121,6 +121,32 @@ func DataSourceIBMISInstances() *schema.Resource { Computed: true, Description: "Indicates whether the metadata service endpoint is available to the virtual server instance", }, + isInstanceMetadataService: { + Type: schema.TypeList, + Computed: true, + Description: "The metadata service configuration", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + isInstanceMetadataServiceEnabled1: { + Type: schema.TypeBool, + Computed: true, + Description: "Indicates whether the metadata service endpoint will be available to the virtual server instance", + }, + + isInstanceMetadataServiceProtocol: { + Type: schema.TypeString, + Computed: true, + Description: "The communication protocol to use for the metadata service endpoint. Applies only when the metadata service is enabled.", + }, + + isInstanceMetadataServiceRespHopLimit: { + Type: schema.TypeInt, + Computed: true, + Description: "The hop limit (IP time to live) for IP response packets from the metadata service", + }, + }, + }, + }, "status": { Type: schema.TypeString, Computed: true, @@ -806,6 +832,18 @@ func instancesList(d *schema.ResourceData, meta interface{}) error { l["memory"] = *instance.Memory if instance.MetadataService != nil { l[isInstanceMetadataServiceEnabled] = *instance.MetadataService.Enabled + metadataService := []map[string]interface{}{} + metadataServiceMap := map[string]interface{}{} + + metadataServiceMap[isInstanceMetadataServiceEnabled1] = instance.MetadataService.Enabled + if instance.MetadataService.Protocol != nil { + metadataServiceMap[isInstanceMetadataServiceProtocol] = instance.MetadataService.Protocol + } + if instance.MetadataService.ResponseHopLimit != nil { + metadataServiceMap[isInstanceMetadataServiceRespHopLimit] = instance.MetadataService.ResponseHopLimit + } + metadataService = append(metadataService, metadataServiceMap) + l[isInstanceMetadataService] = metadataService } l["status"] = *instance.Status l["resource_group"] = *instance.ResourceGroup.ID diff --git a/ibm/service/vpc/resource_ibm_is_instance.go b/ibm/service/vpc/resource_ibm_is_instance.go index 5b1709c8341..1d065ef0b56 100644 --- a/ibm/service/vpc/resource_ibm_is_instance.go +++ b/ibm/service/vpc/resource_ibm_is_instance.go @@ -117,9 +117,13 @@ const ( isInstanceDefaultTrustedProfileTarget = "default_trusted_profile_target" isInstanceMetadataServiceEnabled = "metadata_service_enabled" - isInstanceAccessTags = "access_tags" - isInstanceUserTagType = "user" - isInstanceAccessTagType = "access" + isInstanceAccessTags = "access_tags" + isInstanceUserTagType = "user" + isInstanceAccessTagType = "access" + isInstanceMetadataService = "metadata_service" + isInstanceMetadataServiceEnabled1 = "enabled" + isInstanceMetadataServiceProtocol = "protocol" + isInstanceMetadataServiceRespHopLimit = "response_hop_limit" ) func ResourceIBMISInstance() *schema.Resource { @@ -814,12 +818,49 @@ func ResourceIBMISInstance() *schema.Resource { }, }, isInstanceMetadataServiceEnabled: { - Type: schema.TypeBool, - Optional: true, - Computed: true, - Description: "Indicates whether the metadata service endpoint is available to the virtual server instance", + Type: schema.TypeBool, + Optional: true, + Computed: true, + ConflictsWith: []string{isInstanceMetadataService}, + Deprecated: "Use metadata_service instead", + Description: "Indicates whether the metadata service endpoint is available to the virtual server instance", }, + isInstanceMetadataService: { + Type: schema.TypeList, + Optional: true, + Computed: true, + MinItems: 1, + MaxItems: 1, + ConflictsWith: []string{isInstanceMetadataServiceEnabled}, + Description: "The metadata service configuration", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + isInstanceMetadataServiceEnabled1: { + Type: schema.TypeBool, + Optional: true, + Computed: true, + Description: "Indicates whether the metadata service endpoint will be available to the virtual server instance", + }, + + isInstanceMetadataServiceProtocol: { + Type: schema.TypeString, + Optional: true, + Computed: true, + Description: "The communication protocol to use for the metadata service endpoint. Applies only when the metadata service is enabled.", + ValidateFunc: validate.InvokeValidator("ibm_is_instance", isInstanceMetadataServiceProtocol), + }, + + isInstanceMetadataServiceRespHopLimit: { + Type: schema.TypeInt, + Optional: true, + Computed: true, + Description: "The hop limit (IP time to live) for IP response packets from the metadata service", + ValidateFunc: validate.InvokeValidator("ibm_is_instance", isInstanceMetadataServiceRespHopLimit), + }, + }, + }, + }, flex.ResourceControllerURL: { Type: schema.TypeString, Computed: true, @@ -954,7 +995,24 @@ func ResourceIBMISInstance() *schema.Resource { func ResourceIBMISInstanceValidator() *validate.ResourceValidator { actions := "stop, start, reboot" host_failure := "restart, stop" + metadataServiceProtocol := "https, http" validateSchema := make([]validate.ValidateSchema, 0) + + validateSchema = append(validateSchema, + validate.ValidateSchema{ + Identifier: isInstanceMetadataServiceRespHopLimit, + ValidateFunctionIdentifier: validate.IntBetween, + Type: validate.TypeInt, + Optional: true, + MinValue: "1", + MaxValue: "64"}) + validateSchema = append(validateSchema, + validate.ValidateSchema{ + Identifier: isInstanceMetadataServiceProtocol, + ValidateFunctionIdentifier: validate.ValidateAllowedStringValue, + Type: validate.TypeString, + Optional: true, + AllowedValues: metadataServiceProtocol}) validateSchema = append(validateSchema, validate.ValidateSchema{ Identifier: isInstanceName, @@ -1356,6 +1414,10 @@ func instanceCreateByImage(d *schema.ResourceData, meta interface{}, profile, na } } + if metadataService := GetInstanceMetadataServiceOptions(d); metadataService != nil { + instanceproto.MetadataService = metadataService + } + options := &vpcv1.CreateInstanceOptions{ InstancePrototype: instanceproto, } @@ -1725,6 +1787,10 @@ func instanceCreateByCatalogOffering(d *schema.ResourceData, meta interface{}, p } } + if metadataService := GetInstanceMetadataServiceOptions(d); metadataService != nil { + instanceproto.MetadataService = metadataService + } + options := &vpcv1.CreateInstanceOptions{ InstancePrototype: instanceproto, } @@ -2091,6 +2157,10 @@ func instanceCreateByTemplate(d *schema.ResourceData, meta interface{}, profile, } } + if metadataService := GetInstanceMetadataServiceOptions(d); metadataService != nil { + instanceproto.MetadataService = metadataService + } + options := &vpcv1.CreateInstanceOptions{ InstancePrototype: instanceproto, } @@ -2105,10 +2175,6 @@ func instanceCreateByTemplate(d *schema.ResourceData, meta interface{}, profile, log.Printf("[INFO] Instance : %s", *instance.ID) d.Set(isInstanceStatus, instance.Status) - if instance.MetadataService != nil { - d.Set(isInstanceMetadataServiceEnabled, instance.MetadataService.Enabled) - } - _, err = isWaitForInstanceAvailable(sess, d.Id(), d.Timeout(schema.TimeoutCreate), d) if err != nil { return err @@ -2465,6 +2531,10 @@ func instanceCreateByVolume(d *schema.ResourceData, meta interface{}, profile, n } } + if metadataService := GetInstanceMetadataServiceOptions(d); metadataService != nil { + instanceproto.MetadataService = metadataService + } + options := &vpcv1.CreateInstanceOptions{ InstancePrototype: instanceproto, } @@ -2999,7 +3069,20 @@ func instanceGet(d *schema.ResourceData, meta interface{}, id string) error { } if instance.MetadataService != nil { d.Set(isInstanceMetadataServiceEnabled, instance.MetadataService.Enabled) + metadataService := []map[string]interface{}{} + metadataServiceMap := map[string]interface{}{} + + metadataServiceMap[isInstanceMetadataServiceEnabled1] = instance.MetadataService.Enabled + if instance.MetadataService.Protocol != nil { + metadataServiceMap[isInstanceMetadataServiceProtocol] = instance.MetadataService.Protocol + } + if instance.MetadataService.ResponseHopLimit != nil { + metadataServiceMap[isInstanceMetadataServiceRespHopLimit] = instance.MetadataService.ResponseHopLimit + } + metadataService = append(metadataService, metadataServiceMap) + d.Set(isInstanceMetadataService, metadataService) } + if instance.Disks != nil { disks := []map[string]interface{}{} for _, disksItem := range instance.Disks { @@ -3595,6 +3678,50 @@ func instanceUpdate(d *schema.ResourceData, meta interface{}) error { return err } } + + if d.HasChange(isInstanceMetadataService) && !d.IsNewResource() { + metadataServiceIntf := d.Get(isInstanceMetadataService) + updatedoptions := &vpcv1.UpdateInstanceOptions{ + ID: &id, + } + metadataServicePatchModel := &vpcv1.InstanceMetadataServicePatch{} + instancePatchModel := &vpcv1.InstancePatch{} + metadataServiceMap := metadataServiceIntf.([]interface{})[0].(map[string]interface{}) + if d.HasChange(isInstanceMetadataService + ".0." + isInstanceMetadataServiceEnabled1) { + enabledIntf, ok := metadataServiceMap[isInstanceMetadataServiceEnabled1] + if ok { + enabled := enabledIntf.(bool) + metadataServicePatchModel.Enabled = &enabled + } + } + if d.HasChange(isInstanceMetadataService + ".0." + isInstanceMetadataServiceProtocol) { + protocolIntf, ok := metadataServiceMap[isInstanceMetadataServiceProtocol] + if ok { + protocol := protocolIntf.(string) + metadataServicePatchModel.Protocol = &protocol + } + } + if d.HasChange(isInstanceMetadataService + ".0." + isInstanceMetadataServiceRespHopLimit) { + respHopLimitIntf, ok := metadataServiceMap[isInstanceMetadataServiceRespHopLimit] + if ok { + respHopLimit := int64(respHopLimitIntf.(int)) + metadataServicePatchModel.ResponseHopLimit = &respHopLimit + } + } + instancePatchModel.MetadataService = metadataServicePatchModel + + instancePatch, err := instancePatchModel.AsPatch() + if err != nil { + return fmt.Errorf("Error calling asPatch for InstancePatch: %s", err) + } + updatedoptions.InstancePatch = instancePatch + + _, _, err = instanceC.UpdateInstance(updatedoptions) + if err != nil { + return err + } + } + if d.HasChange(isInstanceAvailablePolicyHostFailure) && !d.IsNewResource() { updatedoptions := &vpcv1.UpdateInstanceOptions{ @@ -4100,3 +4227,29 @@ func resourceIbmIsInstanceDedicatedHostGroupReferenceDeletedToMap(dedicatedHostG return dedicatedHostGroupReferenceDeletedMap } + +func GetInstanceMetadataServiceOptions(d *schema.ResourceData) (metadataService *vpcv1.InstanceMetadataServicePrototype) { + + if metadataServiceIntf, ok := d.GetOk(isInstanceMetadataService); ok { + metadataService = &vpcv1.InstanceMetadataServicePrototype{} + metadataServiceMap := metadataServiceIntf.([]interface{})[0].(map[string]interface{}) + enabledIntf, ok := metadataServiceMap[isInstanceMetadataServiceEnabled1] + + if ok { + enabled := enabledIntf.(bool) + metadataService.Enabled = &enabled + } + protocolIntf, ok := metadataServiceMap[isInstanceMetadataServiceProtocol] + if ok && protocolIntf.(string) != "" { + protocol := protocolIntf.(string) + metadataService.Protocol = &protocol + } + respHopLimitIntf, ok := metadataServiceMap[isInstanceMetadataServiceRespHopLimit] + if ok && int64(respHopLimitIntf.(int)) != 0 { + respHopLimit := int64(respHopLimitIntf.(int)) + metadataService.ResponseHopLimit = &respHopLimit + } + return + } + return nil +} diff --git a/ibm/service/vpc/resource_ibm_is_instance_template.go b/ibm/service/vpc/resource_ibm_is_instance_template.go index a5b03fde1cc..a27b3710074 100644 --- a/ibm/service/vpc/resource_ibm_is_instance_template.go +++ b/ibm/service/vpc/resource_ibm_is_instance_template.go @@ -107,13 +107,51 @@ func ResourceIBMISInstanceTemplate() *schema.Resource { }, isInstanceTemplateMetadataServiceEnabled: { - Type: schema.TypeBool, - Optional: true, - ForceNew: true, - Default: false, - Description: "Indicates whether the metadata service endpoint is available to the virtual server instance", + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + Computed: true, + Deprecated: "Use metadata_service instead", + ConflictsWith: []string{isInstanceMetadataService}, + Description: "Indicates whether the metadata service endpoint is available to the virtual server instance", }, + isInstanceMetadataService: { + Type: schema.TypeList, + Optional: true, + Computed: true, + MinItems: 1, + MaxItems: 1, + ConflictsWith: []string{isInstanceTemplateMetadataServiceEnabled}, + Description: "The metadata service configuration", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + isInstanceMetadataServiceEnabled1: { + Type: schema.TypeBool, + Optional: true, + ForceNew: true, + Computed: true, + Description: "Indicates whether the metadata service endpoint will be available to the virtual server instance", + }, + + isInstanceMetadataServiceProtocol: { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + Description: "The communication protocol to use for the metadata service endpoint. Applies only when the metadata service is enabled.", + }, + + isInstanceMetadataServiceRespHopLimit: { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + Computed: true, + Description: "The hop limit (IP time to live) for IP response packets from the metadata service", + }, + }, + }, + }, isInstanceTemplateVPC: { Type: schema.TypeString, ForceNew: true, @@ -693,6 +731,11 @@ func instanceTemplateCreateByCatalogOffering(d *schema.ResourceData, meta interf Enabled: &metadataServiceEnabled, } } + + if metadataService := GetInstanceTemplateMetadataServiceOptions(d); metadataService != nil { + instanceproto.MetadataService = metadataService + } + if defaultTrustedProfileTargetIntf, ok := d.GetOk(isInstanceDefaultTrustedProfileTarget); ok { defaultTrustedProfiletarget := defaultTrustedProfileTargetIntf.(string) @@ -1111,6 +1154,11 @@ func instanceTemplateCreate(d *schema.ResourceData, meta interface{}, profile, n Enabled: &metadataServiceEnabled, } } + + if metadataService := GetInstanceTemplateMetadataServiceOptions(d); metadataService != nil { + instanceproto.MetadataService = metadataService + } + if defaultTrustedProfileTargetIntf, ok := d.GetOk(isInstanceDefaultTrustedProfileTarget); ok { defaultTrustedProfiletarget := defaultTrustedProfileTargetIntf.(string) @@ -1570,6 +1618,19 @@ func instanceTemplateGet(d *schema.ResourceData, meta interface{}, ID string) er } if instance.MetadataService != nil { d.Set(isInstanceTemplateMetadataServiceEnabled, instance.MetadataService.Enabled) + metadataService := []map[string]interface{}{} + metadataServiceMap := map[string]interface{}{} + + metadataServiceMap[isInstanceMetadataServiceEnabled1] = instance.MetadataService.Enabled + if instance.MetadataService.Protocol != nil { + metadataServiceMap[isInstanceMetadataServiceProtocol] = instance.MetadataService.Protocol + } + if instance.MetadataService.ResponseHopLimit != nil { + metadataServiceMap[isInstanceMetadataServiceRespHopLimit] = instance.MetadataService.ResponseHopLimit + } + metadataService = append(metadataService, metadataServiceMap) + d.Set(isInstanceMetadataService, metadataService) + } var placementTargetMap map[string]interface{} @@ -1850,3 +1911,28 @@ func instanceTemplateExists(d *schema.ResourceData, meta interface{}, ID string) } return true, nil } + +func GetInstanceTemplateMetadataServiceOptions(d *schema.ResourceData) (metadataService *vpcv1.InstanceMetadataServicePrototype) { + if metadataServiceIntf, ok := d.GetOk(isInstanceMetadataService); ok { + metadataServiceMap := metadataServiceIntf.([]interface{})[0].(map[string]interface{}) + enabledIntf, ok := metadataServiceMap[isInstanceMetadataServiceEnabled1] + metadataService = &vpcv1.InstanceMetadataServicePrototype{} + if ok { + enabled := enabledIntf.(bool) + metadataService.Enabled = &enabled + } + protocolIntf, ok := metadataServiceMap[isInstanceMetadataServiceProtocol] + if ok && protocolIntf.(string) != "" { + protocol := protocolIntf.(string) + metadataService.Protocol = &protocol + } + respHopLimitIntf, ok := metadataServiceMap[isInstanceMetadataServiceRespHopLimit] + if ok && int64(respHopLimitIntf.(int)) != 0 { + respHopLimit := int64(respHopLimitIntf.(int)) + metadataService.ResponseHopLimit = &respHopLimit + } + + return + } + return nil +} diff --git a/ibm/service/vpc/resource_ibm_is_instance_template_test.go b/ibm/service/vpc/resource_ibm_is_instance_template_test.go index d7b77b90888..31af702aa8c 100644 --- a/ibm/service/vpc/resource_ibm_is_instance_template_test.go +++ b/ibm/service/vpc/resource_ibm_is_instance_template_test.go @@ -123,10 +123,11 @@ func TestAccIBMISInstanceTemplate_metadata_service(t *testing.T) { CheckDestroy: testAccCheckIBMISInstanceTemplateDestroy, Steps: []resource.TestStep{ { - Config: testAccCheckIBMISInstanceMetadataServiceTemplateConfig(vpcName, subnetName, sshKeyName, publicKey, templateName, true), + Config: testAccCheckIBMISInstanceMetadataServiceTemplateConfig(vpcName, subnetName, sshKeyName, publicKey, templateName, true, "https", 10), Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr( - "ibm_is_instance_template.instancetemplate1", "metadata_service_enabled", "true"), + resource.TestCheckResourceAttr("ibm_is_instance_template.instancetemplate1", "metadata_service.0.enabled", "true"), + resource.TestCheckResourceAttr("ibm_is_instance_template.instancetemplate1", "metadata_service.0.protocol", "https"), + resource.TestCheckResourceAttr("ibm_is_instance_template.instancetemplate1", "metadata_service.0.response_hop_limit", "10"), ), }, }, @@ -379,7 +380,7 @@ func testAccCheckIBMISInstanceTemplateRipConfig(vpcName, subnetName, sshKeyName, } -func testAccCheckIBMISInstanceMetadataServiceTemplateConfig(vpcName, subnetName, sshKeyName, publicKey, templateName string, metadataService bool) string { +func testAccCheckIBMISInstanceMetadataServiceTemplateConfig(vpcName, subnetName, sshKeyName, publicKey, templateName string, metadataService bool, protocol string, hop_limit int) string { return fmt.Sprintf(` resource "ibm_is_vpc" "vpc2" { @@ -398,12 +399,9 @@ func testAccCheckIBMISInstanceMetadataServiceTemplateConfig(vpcName, subnetName, public_key = "%s" } - data "ibm_is_images" "is_images" { - } - resource "ibm_is_instance_template" "instancetemplate1" { name = "%s" - image = data.ibm_is_images.is_images.images.0.id + image = "%s" profile = "bx2-8x32" primary_network_interface { @@ -413,11 +411,15 @@ func testAccCheckIBMISInstanceMetadataServiceTemplateConfig(vpcName, subnetName, vpc = ibm_is_vpc.vpc2.id zone = "us-south-2" keys = [ibm_is_ssh_key.sshkey.id] - metadata_service_enabled = %t + metadata_service { + enabled = %t + protocol = "%s" + response_hop_limit = %d + } } - `, vpcName, subnetName, sshKeyName, publicKey, templateName, metadataService) + `, vpcName, subnetName, sshKeyName, publicKey, templateName, acc.IsImage, metadataService, protocol, hop_limit) } diff --git a/ibm/service/vpc/resource_ibm_is_instance_test.go b/ibm/service/vpc/resource_ibm_is_instance_test.go index 5a83c6c86fe..26c7eeb8ab4 100644 --- a/ibm/service/vpc/resource_ibm_is_instance_test.go +++ b/ibm/service/vpc/resource_ibm_is_instance_test.go @@ -433,7 +433,7 @@ func TestAccIBMISInstance_metadata_service(t *testing.T) { name := fmt.Sprintf("tf-instnace-%d", acctest.RandIntRange(10, 100)) subnetname := fmt.Sprintf("tf-subnet-%d", acctest.RandIntRange(10, 100)) publicKey := strings.TrimSpace(` -ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCKVmnMOlHKcZK8tpt3MP1lqOLAcqcJzhsvJcjscgVERRN7/9484SOBJ3HSKxxNG5JN8owAjy5f9yYwcUg+JaUVuytn5Pv3aeYROHGGg+5G346xaq3DAwX6Y5ykr2fvjObgncQBnuU5KHWCECO/4h8uWuwh/kfniXPVjFToc+gnkqA+3RKpAecZhFXwfalQ9mMuYGFxn+fwn8cYEApsJbsEmb0iJwPiZ5hjFC8wREuiTlhPHDgkBLOiycd20op2nXzDbHfCHInquEe/gYxEitALONxm0swBOwJZwlTDOB7C6y2dzlrtxr1L59m7pCkWI4EtTRLvleehBoj3u7jB4usR + ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDVtuCfWKVGKaRmaRG6JQZY8YdxnDgGzVOK93IrV9R5Hl0JP1oiLLWlZQS2reAKb8lBqyDVEREpaoRUDjqDqXG8J/kR42FKN51su914pjSBc86wJ02VtT1Wm1zRbSg67kT+g8/T1jCgB5XBODqbcICHVP8Z1lXkgbiHLwlUrbz6OZkGJHo/M/kD1Eme8lctceIYNz/Ilm7ewMXZA4fsidpto9AjyarrJLufrOBl4MRVcZTDSJ7rLP982aHpu9pi5eJAjOZc7Og7n4ns3NFppiCwgVMCVUQbN5GBlWhZ1OsT84ZiTf+Zy8ew+Yg5T7Il8HuC7loWnz+esQPf0s3xhC/kTsGgZreIDoh/rxJfD67wKXetNSh5RH/n5BqjaOuXPFeNXmMhKlhj9nJ8scayx/wsvOGuocEIkbyJSLj3sLUU403OafgatEdnJOwbqg6rUNNF5RIjpJpL7eEWlKIi1j9LyhmPJ+fEO7TmOES82VpCMHpLbe4gf/MhhJ/Xy8DKh9s= root@ffd8363b1226 `) sshname := fmt.Sprintf("tf-ssh-%d", acctest.RandIntRange(10, 100)) @@ -447,15 +447,35 @@ ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCKVmnMOlHKcZK8tpt3MP1lqOLAcqcJzhsvJcjscgVE Check: resource.ComposeTestCheckFunc( testAccCheckIBMISInstanceExists("ibm_is_instance.testacc_instance", instance), resource.TestCheckResourceAttr( - "ibm_is_instance.testacc_instance", "metadata_service_enabled", "false"), + "ibm_is_instance.testacc_instance", "metadata_service.0.enabled", "false"), + resource.TestCheckResourceAttr( + "ibm_is_instance.testacc_instance", "metadata_service.0.protocol", "http"), + resource.TestCheckResourceAttr( + "ibm_is_instance.testacc_instance", "metadata_service.0.response_hop_limit", "1"), ), }, { - Config: testAccCheckIBMISInstanceWithMetaConfig(vpcname, subnetname, sshname, publicKey, name, true), + Config: testAccCheckIBMISInstanceWithMetaConfig(vpcname, subnetname, sshname, publicKey, name, true, "https", 5), Check: resource.ComposeTestCheckFunc( testAccCheckIBMISInstanceExists("ibm_is_instance.testacc_instance", instance), resource.TestCheckResourceAttr( "ibm_is_instance.testacc_instance", "metadata_service_enabled", "true"), + resource.TestCheckResourceAttr( + "ibm_is_instance.testacc_instance", "metadata_service.0.protocol", "https"), + resource.TestCheckResourceAttr( + "ibm_is_instance.testacc_instance", "metadata_service.0.response_hop_limit", "5"), + ), + }, + { + Config: testAccCheckIBMISInstanceWithMetaConfig(vpcname, subnetname, sshname, publicKey, name, true, "http", 10), + Check: resource.ComposeTestCheckFunc( + testAccCheckIBMISInstanceExists("ibm_is_instance.testacc_instance", instance), + resource.TestCheckResourceAttr( + "ibm_is_instance.testacc_instance", "metadata_service_enabled", "true"), + resource.TestCheckResourceAttr( + "ibm_is_instance.testacc_instance", "metadata_service.0.protocol", "http"), + resource.TestCheckResourceAttr( + "ibm_is_instance.testacc_instance", "metadata_service.0.response_hop_limit", "10"), ), }, }, @@ -910,7 +930,7 @@ func testAccCheckIBMISInstanceWithMetaConfigDefault(vpcname, subnetname, sshname }`, vpcname, subnetname, acc.ISZoneName, acc.ISCIDR, sshname, publicKey, name, acc.IsImage, acc.InstanceProfileName, acc.ISZoneName) } -func testAccCheckIBMISInstanceWithMetaConfig(vpcname, subnetname, sshname, publicKey, name string, metadata_service_enabled bool) string { +func testAccCheckIBMISInstanceWithMetaConfig(vpcname, subnetname, sshname, publicKey, name string, metadata_service_enabled bool, protocol string, hop_limit int) string { return fmt.Sprintf(` resource "ibm_is_vpc" "testacc_vpc" { name = "%s" @@ -942,8 +962,12 @@ func testAccCheckIBMISInstanceWithMetaConfig(vpcname, subnetname, sshname, publi subnet = ibm_is_subnet.testacc_subnet.id name = "eth1" } - metadata_service_enabled=%t - }`, vpcname, subnetname, acc.ISZoneName, acc.ISCIDR, sshname, publicKey, name, acc.IsImage, acc.InstanceProfileName, acc.ISZoneName, metadata_service_enabled) + metadata_service { + enabled = %t + protocol = "%s" + response_hop_limit = %d + } + }`, vpcname, subnetname, acc.ISZoneName, acc.ISCIDR, sshname, publicKey, name, acc.IsImage, acc.InstanceProfileName, acc.ISZoneName, metadata_service_enabled, protocol, hop_limit) } func testAccCheckIBMISInstanceConfig(vpcname, subnetname, sshname, publicKey, name, userData string) string { diff --git a/website/docs/d/is_instance.html.markdown b/website/docs/d/is_instance.html.markdown index 92b3f9bd3da..e02c125398b 100644 --- a/website/docs/d/is_instance.html.markdown +++ b/website/docs/d/is_instance.html.markdown @@ -136,6 +136,16 @@ In addition to all argument reference list, you can access the following attribu - `more_info` - (String) Link to documentation about the reason for this lifecycle state. - `lifecycle_state`- (String) The lifecycle state of the virtual server instance. [ **deleting**, **failed**, **pending**, **stable**, **suspended**, **updating**, **waiting** ] - `metadata_service_enabled` - (Boolean) Indicates whether the metadata service endpoint is available to the virtual server instance. + + ~> **NOTE** + `metadata_service_enabled` is deprecated and will be removed in the future. Refer `metadata_service` instead +- `metadata_service` - (List) The metadata service configuration. + + Nested scheme for `metadata_service`: + - `enabled` - (Boolean) Indicates whether the metadata service endpoint will be available to the virtual server instance. + - `protocol` - (String) The communication protocol to use for the metadata service endpoint. + - `response_hop_limit` - (Integer) The hop limit (IP time to live) for IP response packets from the metadata service. + - `network_interfaces`- (List) A list of more network interfaces that the instance uses. Nested scheme for `network_interfaces`: diff --git a/website/docs/d/is_instance_template.html.markdown b/website/docs/d/is_instance_template.html.markdown index 32f507609e8..dbe863c3b24 100644 --- a/website/docs/d/is_instance_template.html.markdown +++ b/website/docs/d/is_instance_template.html.markdown @@ -71,6 +71,16 @@ You can access the following attribute references after your data source is crea - `image` - (String) The ID of the image to create the template. - `keys` - (String) List of SSH key IDs used to allow log in user to the instances. - `metadata_service_enabled` - (Boolean) Indicates whether the metadata service endpoint is available to the virtual server instance. + + ~> **NOTE** + `metadata_service_enabled` is deprecated and will be removed in the future. Refer `metadata_service` instead + - `metadata_service` - (List) The metadata service configuration. + + Nested scheme for `metadata_service`: + - `enabled` - (Boolean) Indicates whether the metadata service endpoint will be available to the virtual server instance. + - `protocol` - (String) The communication protocol to use for the metadata service endpoint. + - `response_hop_limit` - (Integer) The hop limit (IP time to live) for IP response packets from the metadata service. + - `name` - (String) The name of the instance template. - `network_interfaces` - (List) A nested block describes the network interfaces for the template. diff --git a/website/docs/d/is_instance_templates.html.markdown b/website/docs/d/is_instance_templates.html.markdown index 4515f1eff97..84aaf636ab1 100644 --- a/website/docs/d/is_instance_templates.html.markdown +++ b/website/docs/d/is_instance_templates.html.markdown @@ -60,6 +60,16 @@ You can access the following attribute references after your data source is crea - `image` - (String) The ID of the image to create the template. - `keys` - (String) List of SSH key IDs used to allow log in user to the instances. - `metadata_service_enabled` - (Boolean) Indicates whether the metadata service endpoint is available to the virtual server instance. + + ~> **NOTE** + `metadata_service_enabled` is deprecated and will be removed in the future. Refer `metadata_service` instead + - `metadata_service` - (List) The metadata service configuration. + + Nested scheme for `metadata_service`: + - `enabled` - (Boolean) Indicates whether the metadata service endpoint will be available to the virtual server instance. + - `protocol` - (String) The communication protocol to use for the metadata service endpoint. + - `response_hop_limit` - (Integer) The hop limit (IP time to live) for IP response packets from the metadata service. + - `name` - (String) The name of the instance template. - `network_interfaces` - (List) A nested block describes the network interfaces for the template. diff --git a/website/docs/d/is_instances.html.markdown b/website/docs/d/is_instances.html.markdown index 32742aaa506..0559a69e674 100644 --- a/website/docs/d/is_instances.html.markdown +++ b/website/docs/d/is_instances.html.markdown @@ -102,6 +102,16 @@ In addition to all argument reference list, you can access the following attribu - `lifecycle_state`- (String) The lifecycle state of the virtual server instance. [ **deleting**, **failed**, **pending**, **stable**, **suspended**, **updating**, **waiting** ] - `memory`- (Integer) The amount of memory that was allocated to the instance. - `metadata_service_enabled` - (Boolean) Indicates whether the metadata service endpoint is available to the virtual server instance. + + ~> **NOTE** + `metadata_service_enabled` is deprecated and will be removed in the future. Refer `metadata_service` instead + - `metadata_service` - (List) The metadata service configuration. + + Nested scheme for `metadata_service`: + - `enabled` - (Boolean) Indicates whether the metadata service endpoint will be available to the virtual server instance. + - `protocol` - (String) The communication protocol to use for the metadata service endpoint. + - `response_hop_limit` - (Integer) The hop limit (IP time to live) for IP response packets from the metadata service. + - `network_interfaces`- (List) A list of more network interfaces that the instance uses. Nested scheme for `network_interfaces`: diff --git a/website/docs/r/is_instance.html.markdown b/website/docs/r/is_instance.html.markdown index 1ba262c4874..ba8a5729344 100644 --- a/website/docs/r/is_instance.html.markdown +++ b/website/docs/r/is_instance.html.markdown @@ -328,7 +328,33 @@ resource "ibm_is_instance" "example" { } } ``` +### Example to create an instance with metadata service configuration ### +```terraform + +resource "ibm_is_instance" "example" { + metadata_service { + enabled = true + protocol = "https" + response_hop_limit = 5 + } + name = "example-vsi-catalog" + profile = "cx2-2x4" + catalog_offering { + version_crn = data.ibm_is_images.example.images.0.catalog_offering.0.version.0.crn + } + primary_network_interface { + subnet = ibm_is_subnet.example.id + } + vpc = ibm_is_vpc.example.id + zone = "us-south-1" + keys = [ibm_is_ssh_key.example.id] + network_interfaces { + subnet = ibm_is_subnet.example.id + name = "eth1" + } +} +``` ## Timeouts The `ibm_is_instance` resource provides the following [[Timeouts](https://www.terraform.io/docs/language/resources/syntax.html) configuration options: @@ -403,6 +429,15 @@ Review the argument references that you can specify for your resource. - `more_info` - (String) Link to documentation about the reason for this lifecycle state. - `lifecycle_state`- (String) The lifecycle state of the virtual server instance. [ **deleting**, **failed**, **pending**, **stable**, **suspended**, **updating**, **waiting** ] - `metadata_service_enabled` - (Optional, Boolean) Indicates whether the metadata service endpoint is available to the virtual server instance. Default value : **false** + + ~> **NOTE** + `metadata_service_enabled` is deprecated and will be removed in the future. Use `metadata_service` instead +- `metadata_service` - (Optional, List) The metadata service configuration. + + Nested scheme for `metadata_service`: + - `enabled` - (Optional, Bool) Indicates whether the metadata service endpoint will be available to the virtual server instance. Default is **false** + - `protocol` - (Optional, String) The communication protocol to use for the metadata service endpoint. Applies only when the metadata service is enabled. Default is **http** + - `response_hop_limit` - (Optional, Integer) The hop limit (IP time to live) for IP response packets from the metadata service. Default is **1** - `name` - (Optional, String) The instance name. - `network_interfaces` (Optional, Forces new resource, List) A list of more network interfaces that are set up for the instance. diff --git a/website/docs/r/is_instance_template.html.markdown b/website/docs/r/is_instance_template.html.markdown index ed5ed42169f..dddc1244d4e 100644 --- a/website/docs/r/is_instance_template.html.markdown +++ b/website/docs/r/is_instance_template.html.markdown @@ -105,7 +105,6 @@ resource "ibm_is_instance_template" "example1" { name = "example-template" image = ibm_is_image.example.id profile = "bx2-8x32" - metadata_service_enabled = false primary_network_interface { subnet = ibm_is_subnet.example.id @@ -171,6 +170,34 @@ resource "ibm_is_instance_template" "example4" { ``` +``` +resource "ibm_is_instance_template" "example4" { + name = "example-template" + image = ibm_is_image.example.id + profile = "bx2-8x32" + + metadata_service { + enabled = true + protocol = "https" + response_hop_limit = 5 + } + + primary_network_interface { + subnet = ibm_is_subnet.example.id + allow_ip_spoofing = true + } + + dedicated_host = ibm_is_dedicated_host.example.id + vpc = ibm_is_vpc.vpc2.id + zone = "us-south-2" + keys = [ibm_is_ssh_key.example.id] + + boot_volume { + name = "example-boot-volume" + delete_volume_on_instance_delete = true + } +} +``` ## Argument reference Review the argument references that you can specify for your resource. - `availability_policy_host_failure` - (Optional, String) The availability policy to use for this virtual server instance. The action to perform if the compute host experiences a failure. Supported values are `restart` and `stop`. @@ -211,6 +238,15 @@ Review the argument references that you can specify for your resource. - `keys` - (Required, List) List of SSH key IDs used to allow log in user to the instances. - `metadata_service_enabled` - (Optional, Forces new resource, Boolean) Indicates whether the metadata service endpoint is available to the virtual server instance. Default value : **false** + + ~> **NOTE** + `metadata_service_enabled` is deprecated and will be removed in the future. Use `metadata_service` instead +- `metadata_service` - (Optional, List) The metadata service configuration. + + Nested scheme for `metadata_service`: + - `enabled` - (Optional, Forces new resource, Boolean) Indicates whether the metadata service endpoint will be available to the virtual server instance. Default is **false** + - `protocol` - (Optional, Forces new resource, String) The communication protocol to use for the metadata service endpoint. Applies only when the metadata service is enabled. Default is **http** + - `response_hop_limit` - (Optional, Forces new resource, Integer) The hop limit (IP time to live) for IP response packets from the metadata service. Default is **1** - `name` - (Optional, String) The name of the instance template. - `placement_group` - (Optional, Force new resource, String) The placement restrictions to use for the virtual server instance. Unique Identifier of the placement group where the instance is placed.