From c9bfc1ba9ae2401e9e9d171d592546e3fcc69fe4 Mon Sep 17 00:00:00 2001 From: chinthalapalli Date: Thu, 11 Apr 2024 20:33:27 +0530 Subject: [PATCH] removing fast resources --- .gitignore | 1 + docs/resources/cm_deploy_f5os.md | 3 +- docs/resources/cm_fast_http.md | 55 ---- docs/resources/cm_fast_template.md | 56 ---- internal/provider/fast_http_resource.go | 245 -------------- internal/provider/fast_template_resource.go | 193 ----------- .../provider/next_deploy_f5os_resource.go | 86 ++++- .../next_deploy_vmware_resource_test.go | 2 +- internal/provider/provider.go | 2 - .../bigipnext/bigipnextcm.go | 307 ++++++++++++++++-- 10 files changed, 367 insertions(+), 583 deletions(-) delete mode 100644 docs/resources/cm_fast_http.md delete mode 100644 docs/resources/cm_fast_template.md delete mode 100644 internal/provider/fast_http_resource.go delete mode 100644 internal/provider/fast_template_resource.go diff --git a/.gitignore b/.gitignore index a69f576..f6eaf1a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ example.tf terraform.tfplan terraform.tfstate +.terraform.lock.hcl *.tfvars vendor/.DS_Store terraform-provider-bigipnext diff --git a/docs/resources/cm_deploy_f5os.md b/docs/resources/cm_deploy_f5os.md index 3ea804a..1311a41 100644 --- a/docs/resources/cm_deploy_f5os.md +++ b/docs/resources/cm_deploy_f5os.md @@ -76,6 +76,7 @@ Optional: - `cpu_cores` (Number) The number of virtual processor cores to configure on the BIG-IP-Next Instance.Default is `4`. - `disk_size` (Number) The amount of disk size in GigBytes to configure on the BIG-IP-Next Instance.Default is `30`. -- `vlan_ids` (List of Number) List of integers. Specifies on which blades nodes the tenants are deployed. +- `slot_ids` (List of Number) Specifies on which list blades nodes the tenants are deployed. Required for create operations. For single blade platforms like rSeries only the value of 1 should be provided. +- `vlan_ids` (List of Number) List of vlan ids to be assigned to BIG-IP Next Instance deployed diff --git a/docs/resources/cm_fast_http.md b/docs/resources/cm_fast_http.md deleted file mode 100644 index 55e0586..0000000 --- a/docs/resources/cm_fast_http.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "bigipnext_cm_fast_http Resource - terraform-provider-bigipnext" -subcategory: "" -description: |- - Resource used to manage(CRUD) AS3 declarations using BIG-IP Next CM onto target BIG-IP Next ---- - -# bigipnext_cm_fast_http (Resource) - -Resource used to manage(CRUD) AS3 declarations using BIG-IP Next CM onto target BIG-IP Next - - - - -## Schema - -### Required - -- `application_name` (String) Name of the Application -- `name` (String) Name of the Application -- `tenant_name` (String) Name of the Tenant - -### Optional - -- `allow_overwrite` (Boolean) Allow Overwrite -- `application_description` (String) Description of the Application -- `pools` (Attributes List) List of Pools (see [below for nested schema](#nestedatt--pools)) -- `set_name` (String) Name of the AS3 Set -- `template_name` (String) Name of the AS3 Template -- `virtuals` (Attributes List) List of Virtuals (see [below for nested schema](#nestedatt--virtuals)) - -### Read-Only - -- `id` (String) Unique Identifier for the resource - - -### Nested Schema for `pools` - -Required: - -- `load_balancing_mode` (String) Load Balancing Mode -- `monitor_type` (List of String) Monitor Type -- `pool_name` (String) Name of the Pool -- `service_port` (Number) Service Port - - - -### Nested Schema for `virtuals` - -Required: - -- `pool_name` (String) Name of the Pool -- `virtual_name` (String) Name of the Virtual -- `virtual_port` (Number) Virtual Port diff --git a/docs/resources/cm_fast_template.md b/docs/resources/cm_fast_template.md deleted file mode 100644 index f3183a5..0000000 --- a/docs/resources/cm_fast_template.md +++ /dev/null @@ -1,56 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "bigipnext_cm_fast_template Resource - terraform-provider-bigipnext" -subcategory: "" -description: |- - Resource used to Manages FAST templates on Central Manager ---- - -# bigipnext_cm_fast_template (Resource) - -Resource used to Manages FAST templates on Central Manager - - - - -## Schema - -### Required - -- `application_name` (String) Name of the Application -- `template_name` (String) Name of the FAST template to be created -- `template_set` (String) Name of the FAST template set to use -If a set with given name does not exist a new set will be created automatically -- `tenant_name` (String) Name of the Tenant - -### Optional - -- `allow_overwrite` (Boolean) Allow Overwrite -- `application_description` (String) Description of the Application -- `pools` (Attributes List) List of Pools (see [below for nested schema](#nestedatt--pools)) -- `set_name` (String) Name of the AS3 Set -- `virtuals` (Attributes List) List of Virtuals (see [below for nested schema](#nestedatt--virtuals)) - -### Read-Only - -- `id` (String) Unique Identifier for the resource - - -### Nested Schema for `pools` - -Required: - -- `load_balancing_mode` (String) Load Balancing Mode -- `monitor_type` (List of String) Monitor Type -- `pool_name` (String) Name of the Pool -- `service_port` (Number) Service Port - - - -### Nested Schema for `virtuals` - -Required: - -- `pool_name` (String) Name of the Pool -- `virtual_name` (String) Name of the Virtual -- `virtual_port` (Number) Virtual Port diff --git a/internal/provider/fast_http_resource.go b/internal/provider/fast_http_resource.go deleted file mode 100644 index ee8f346..0000000 --- a/internal/provider/fast_http_resource.go +++ /dev/null @@ -1,245 +0,0 @@ -package provider - -import ( - "context" - "fmt" - - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" - "github.com/hashicorp/terraform-plugin-framework/types/basetypes" - "github.com/hashicorp/terraform-plugin-log/tflog" - bigipnextsdk "gitswarm.f5net.com/terraform-providers/bigipnext" -) - -var ( - _ resource.Resource = &NextCMFastHttpResource{} - _ resource.ResourceWithImportState = &NextCMFastHttpResource{} -) - -func NewNextCMFastHttpResource() resource.Resource { - return &NextCMFastHttpResource{} -} - -type NextCMFastHttpResource struct { - client *bigipnextsdk.BigipNextCM -} -type NextCMFastHttpResourceModel struct { - Name types.String `tfsdk:"name"` - ApplicationDescription types.String `tfsdk:"application_description"` - ApplicationName types.String `tfsdk:"application_name"` - Pools types.List `tfsdk:"pools"` - Virtuals types.List `tfsdk:"virtuals"` - SetName types.String `tfsdk:"set_name"` - TemplateName types.String `tfsdk:"template_name"` - TenantName types.String `tfsdk:"tenant_name"` - AllowOverwrite types.Bool `tfsdk:"allow_overwrite"` - Id types.String `tfsdk:"id"` -} - -type NextCMFastHttpPoolModel struct { - LoadBalancingMode types.String `tfsdk:"load_balancing_mode"` - MonitorType types.List `tfsdk:"monitor_type"` - PoolName types.String `tfsdk:"pool_name"` - ServicePort types.Int64 `tfsdk:"service_port"` -} - -// pool_name -type NextCMFastHttpVirtualModel struct { - PoolName types.String `tfsdk:"pool_name"` - VirtualName types.String `tfsdk:"virtual_name"` - VirtualPort types.Int64 `tfsdk:"virtual_port"` -} - -func (r *NextCMFastHttpResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_cm_fast_http" -} - -func (r *NextCMFastHttpResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - resp.Schema = schema.Schema{ - MarkdownDescription: "Resource used to manage(CRUD) AS3 declarations using BIG-IP Next CM onto target BIG-IP Next", - Attributes: map[string]schema.Attribute{ - "name": schema.StringAttribute{ - Required: true, - MarkdownDescription: "Name of the Application", - }, - "application_name": schema.StringAttribute{ - Required: true, - MarkdownDescription: "Name of the Application", - }, - "tenant_name": schema.StringAttribute{ - Required: true, - MarkdownDescription: "Name of the Tenant", - }, - "application_description": schema.StringAttribute{ - Optional: true, - MarkdownDescription: "Description of the Application", - }, - "pools": schema.ListNestedAttribute{ - Optional: true, - MarkdownDescription: "List of Pools", - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "load_balancing_mode": schema.StringAttribute{ - Required: true, - MarkdownDescription: "Load Balancing Mode", - }, - "monitor_type": schema.ListAttribute{ - Required: true, - ElementType: types.StringType, - MarkdownDescription: "Monitor Type", - }, - "pool_name": schema.StringAttribute{ - Required: true, - MarkdownDescription: "Name of the Pool", - }, - "service_port": schema.Int64Attribute{ - Required: true, - MarkdownDescription: "Service Port", - }, - }, - }, - }, - "virtuals": schema.ListNestedAttribute{ - Optional: true, - MarkdownDescription: "List of Virtuals", - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "pool_name": schema.StringAttribute{ - Required: true, - MarkdownDescription: "Name of the Pool", - }, - "virtual_name": schema.StringAttribute{ - Required: true, - MarkdownDescription: "Name of the Virtual", - }, - "virtual_port": schema.Int64Attribute{ - Required: true, - MarkdownDescription: "Virtual Port", - }, - }, - }, - }, - "set_name": schema.StringAttribute{ - Optional: true, - Computed: true, - MarkdownDescription: "Name of the AS3 Set", - Default: stringdefault.StaticString("Examples"), - }, - "template_name": schema.StringAttribute{ - Optional: true, - Computed: true, - MarkdownDescription: "Name of the AS3 Template", - Default: stringdefault.StaticString("http"), - }, - "allow_overwrite": schema.BoolAttribute{ - Optional: true, - Computed: true, - MarkdownDescription: "Allow Overwrite", - Default: booldefault.StaticBool(false), - }, - "id": schema.StringAttribute{ - Computed: true, - MarkdownDescription: "Unique Identifier for the resource", - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - }, - }, - }, - } -} - -func (r *NextCMFastHttpResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - r.client, resp.Diagnostics = toBigipNextCMProvider(req.ProviderData) -} - -func (r *NextCMFastHttpResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var resCfg *NextCMFastHttpResourceModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &resCfg)...) - if resp.Diagnostics.HasError() { - return - } - tflog.Info(ctx, fmt.Sprintf("[CREATE] NextCMFastHttpResource:%+v\n", resCfg.Name.ValueString())) - reqDraft := getFastRequestDraft(ctx, resCfg) - - tflog.Info(ctx, fmt.Sprintf("[CREATE] Https:%+v\n", reqDraft)) - - draftID, err := r.client.PostFastApplicationDraft(reqDraft) - if err != nil { - resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to Create FAST Draft config, got error: %s", err)) - return - } - tflog.Info(ctx, fmt.Sprintf("[CREATE] draftID:%+v\n", draftID)) - resp.Diagnostics.Append(resp.State.Set(ctx, resCfg)...) -} - -func (r *NextCMFastHttpResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var stateCfg *NextCMFastHttpResourceModel - resp.Diagnostics.Append(req.State.Get(ctx, &stateCfg)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &stateCfg)...) -} - -func (r *NextCMFastHttpResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var resCfg *NextCMFastHttpResourceModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &resCfg)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &resCfg)...) -} - -func (r *NextCMFastHttpResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var stateCfg *NextCMFastHttpResourceModel - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(req.State.Get(ctx, &stateCfg)...) - stateCfg.Id = types.StringValue("") -} - -func (r *NextCMFastHttpResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} - -func getFastRequestDraft(ctx context.Context, data *NextCMFastHttpResourceModel) *bigipnextsdk.FastRequestDraft { - var fastReqDraft bigipnextsdk.FastRequestDraft - fastReqDraft.Name = data.Name.ValueString() - fastReqDraft.Parameters.ApplicationDescription = data.ApplicationDescription.ValueString() - fastReqDraft.Parameters.ApplicationName = data.ApplicationName.ValueString() - fastReqDraft.SetName = data.SetName.ValueString() - fastReqDraft.TemplateName = data.TemplateName.ValueString() - fastReqDraft.TenantName = data.TenantName.ValueString() - fastReqDraft.AllowOverwrite = data.AllowOverwrite.ValueBool() - elements := make([]types.Object, 0, len(data.Pools.Elements())) - data.Pools.ElementsAs(ctx, &elements, false) - for _, element := range elements { - var fastPool bigipnextsdk.FastPool - var objectModel NextCMFastHttpPoolModel - element.As(ctx, &objectModel, basetypes.ObjectAsOptions{}) - fastPool.LoadBalancingMode = objectModel.LoadBalancingMode.ValueString() - objectModel.MonitorType.ElementsAs(ctx, &fastPool.MonitorType, false) - fastPool.PoolName = objectModel.PoolName.ValueString() - fastPool.ServicePort = int(objectModel.ServicePort.ValueInt64()) - fastReqDraft.Parameters.Pools = append(fastReqDraft.Parameters.Pools, fastPool) - } - vsLists := make([]types.Object, 0, len(data.Virtuals.Elements())) - data.Virtuals.ElementsAs(ctx, &vsLists, false) - for _, element := range vsLists { - var fastVS bigipnextsdk.VirtualServer - var objectModel NextCMFastHttpVirtualModel - element.As(ctx, &objectModel, basetypes.ObjectAsOptions{}) - fastVS.VirtualName = objectModel.VirtualName.ValueString() - fastVS.VirtualPort = int(objectModel.VirtualPort.ValueInt64()) - fastReqDraft.Parameters.Virtuals = append(fastReqDraft.Parameters.Virtuals, fastVS) - } - tflog.Info(ctx, fmt.Sprintf("fastReqDraft:%+v\n", fastReqDraft)) - return &fastReqDraft -} diff --git a/internal/provider/fast_template_resource.go b/internal/provider/fast_template_resource.go deleted file mode 100644 index cca1955..0000000 --- a/internal/provider/fast_template_resource.go +++ /dev/null @@ -1,193 +0,0 @@ -package provider - -import ( - "context" - "github.com/hashicorp/terraform-plugin-framework/path" - "github.com/hashicorp/terraform-plugin-framework/resource" - "github.com/hashicorp/terraform-plugin-framework/resource/schema" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/booldefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/planmodifier" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringdefault" - "github.com/hashicorp/terraform-plugin-framework/resource/schema/stringplanmodifier" - "github.com/hashicorp/terraform-plugin-framework/types" - bigipnextsdk "gitswarm.f5net.com/terraform-providers/bigipnext" -) - -var ( - _ resource.Resource = &NextCMFastTemplateResource{} - _ resource.ResourceWithImportState = &NextCMFastTemplateResource{} -) - -func NewNextCMFastTemplateResource() resource.Resource { - return &NextCMFastTemplateResource{} -} - -type NextCMFastTemplateResource struct { - client *bigipnextsdk.BigipNextCM -} -type NextCMFastTemplateResourceModel struct { - TemplateName types.String `tfsdk:"template_name"` - ApplicationDescription types.String `tfsdk:"application_description"` - ApplicationName types.String `tfsdk:"application_name"` - Pools types.List `tfsdk:"pools"` - Virtuals types.List `tfsdk:"virtuals"` - SetName types.String `tfsdk:"set_name"` - TenantName types.String `tfsdk:"tenant_name"` - AllowOverwrite types.Bool `tfsdk:"allow_overwrite"` - Id types.String `tfsdk:"id"` -} - -type NextCMFastTemplatePoolModel struct { - LoadBalancingMode types.String `tfsdk:"load_balancing_mode"` - MonitorType types.List `tfsdk:"monitor_type"` - PoolName types.String `tfsdk:"pool_name"` - ServicePort types.Int64 `tfsdk:"service_port"` -} - -// pool_name -type NextCMFastTemplateVirtualModel struct { - PoolName types.String `tfsdk:"pool_name"` - VirtualName types.String `tfsdk:"virtual_name"` - VirtualPort types.Int64 `tfsdk:"virtual_port"` -} - -func (r *NextCMFastTemplateResource) Metadata(ctx context.Context, req resource.MetadataRequest, resp *resource.MetadataResponse) { - resp.TypeName = req.ProviderTypeName + "_cm_fast_template" -} - -func (r *NextCMFastTemplateResource) Schema(ctx context.Context, req resource.SchemaRequest, resp *resource.SchemaResponse) { - resp.Schema = schema.Schema{ - MarkdownDescription: "Resource used to Manages FAST templates on Central Manager", - Attributes: map[string]schema.Attribute{ - "template_name": schema.StringAttribute{ - Required: true, - MarkdownDescription: "Name of the FAST template to be created", - }, - "template_set": schema.StringAttribute{ - Required: true, - MarkdownDescription: "Name of the FAST template set to use\nIf a set with given name does not exist a new set will be created automatically", - }, - "application_name": schema.StringAttribute{ - Required: true, - MarkdownDescription: "Name of the Application", - }, - "tenant_name": schema.StringAttribute{ - Required: true, - MarkdownDescription: "Name of the Tenant", - }, - "application_description": schema.StringAttribute{ - Optional: true, - MarkdownDescription: "Description of the Application", - }, - "pools": schema.ListNestedAttribute{ - Optional: true, - MarkdownDescription: "List of Pools", - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "load_balancing_mode": schema.StringAttribute{ - Required: true, - MarkdownDescription: "Load Balancing Mode", - }, - "monitor_type": schema.ListAttribute{ - Required: true, - ElementType: types.StringType, - MarkdownDescription: "Monitor Type", - }, - "pool_name": schema.StringAttribute{ - Required: true, - MarkdownDescription: "Name of the Pool", - }, - "service_port": schema.Int64Attribute{ - Required: true, - MarkdownDescription: "Service Port", - }, - }, - }, - }, - "virtuals": schema.ListNestedAttribute{ - Optional: true, - MarkdownDescription: "List of Virtuals", - NestedObject: schema.NestedAttributeObject{ - Attributes: map[string]schema.Attribute{ - "pool_name": schema.StringAttribute{ - Required: true, - MarkdownDescription: "Name of the Pool", - }, - "virtual_name": schema.StringAttribute{ - Required: true, - MarkdownDescription: "Name of the Virtual", - }, - "virtual_port": schema.Int64Attribute{ - Required: true, - MarkdownDescription: "Virtual Port", - }, - }, - }, - }, - "set_name": schema.StringAttribute{ - Optional: true, - Computed: true, - MarkdownDescription: "Name of the AS3 Set", - Default: stringdefault.StaticString("Examples"), - }, - "allow_overwrite": schema.BoolAttribute{ - Optional: true, - Computed: true, - MarkdownDescription: "Allow Overwrite", - Default: booldefault.StaticBool(false), - }, - "id": schema.StringAttribute{ - Computed: true, - MarkdownDescription: "Unique Identifier for the resource", - PlanModifiers: []planmodifier.String{ - stringplanmodifier.UseStateForUnknown(), - }, - }, - }, - } -} - -func (r *NextCMFastTemplateResource) Configure(ctx context.Context, req resource.ConfigureRequest, resp *resource.ConfigureResponse) { - r.client, resp.Diagnostics = toBigipNextCMProvider(req.ProviderData) -} - -func (r *NextCMFastTemplateResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) { - var resCfg *NextCMFastTemplateResourceModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &resCfg)...) - if resp.Diagnostics.HasError() { - return - } - //git tflog.Info(ctx, fmt.Sprintf("[CREATE] NextCMFastTemplateResource:%+v\n", resCfg.Name.ValueString())) - resp.Diagnostics.Append(resp.State.Set(ctx, resCfg)...) -} - -func (r *NextCMFastTemplateResource) Read(ctx context.Context, req resource.ReadRequest, resp *resource.ReadResponse) { - var stateCfg *NextCMFastTemplateResourceModel - resp.Diagnostics.Append(req.State.Get(ctx, &stateCfg)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &stateCfg)...) -} - -func (r *NextCMFastTemplateResource) Update(ctx context.Context, req resource.UpdateRequest, resp *resource.UpdateResponse) { - var resCfg *NextCMFastTemplateResourceModel - resp.Diagnostics.Append(req.Plan.Get(ctx, &resCfg)...) - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(resp.State.Set(ctx, &resCfg)...) -} - -func (r *NextCMFastTemplateResource) Delete(ctx context.Context, req resource.DeleteRequest, resp *resource.DeleteResponse) { - var stateCfg *NextCMFastTemplateResourceModel - if resp.Diagnostics.HasError() { - return - } - resp.Diagnostics.Append(req.State.Get(ctx, &stateCfg)...) - stateCfg.Id = types.StringValue("") -} - -func (r *NextCMFastTemplateResource) ImportState(ctx context.Context, req resource.ImportStateRequest, resp *resource.ImportStateResponse) { - resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp) -} diff --git a/internal/provider/next_deploy_f5os_resource.go b/internal/provider/next_deploy_f5os_resource.go index 1b62a02..bf2ef40 100644 --- a/internal/provider/next_deploy_f5os_resource.go +++ b/internal/provider/next_deploy_f5os_resource.go @@ -53,6 +53,7 @@ type F5OSInstanceModel struct { MgmtUser types.String `tfsdk:"management_user"` MgmtPassword types.String `tfsdk:"management_password"` VlanIDs types.List `tfsdk:"vlan_ids"` + SlotIDs types.List `tfsdk:"slot_ids"` CpuCores types.Int64 `tfsdk:"cpu_cores"` DiskSize types.Int64 `tfsdk:"disk_size"` TenantImageName types.String `tfsdk:"tenant_image_name"` @@ -119,7 +120,13 @@ func (r *NextDeployF5osResource) Schema(ctx context.Context, req resource.Schema Sensitive: true, }, "vlan_ids": schema.ListAttribute{ - MarkdownDescription: "List of integers. Specifies on which blades nodes the tenants are deployed.\nRequired for create operations.\nFor single blade platforms like rSeries only the value of 1 should be provided.", + MarkdownDescription: "List of vlan ids to be assigned to BIG-IP Next Instance deployed", + Optional: true, + Computed: true, + ElementType: types.Int64Type, + }, + "slot_ids": schema.ListAttribute{ + MarkdownDescription: "Specifies on which list blades nodes the tenants are deployed.\nRequired for create operations.\nFor single blade platforms like rSeries only the value of 1 should be provided.", Optional: true, Computed: true, ElementType: types.Int64Type, @@ -189,14 +196,20 @@ func (r *NextDeployF5osResource) Create(ctx context.Context, req resource.Create return } resCfg.ProviderId = types.StringValue(providerID.(string)) - providerConfig := f5osRseriesConfig(ctx, resCfg) + var providerConfig *bigipnextsdk.CMReqDeviceInstance + if providerModel.ProviderType.ValueString() == "velos" { + providerConfig = f5osVelosConfig(ctx, resCfg) + } + if providerModel.ProviderType.ValueString() == "rseries" { + providerConfig = f5osRseriesConfig(ctx, resCfg) + } tflog.Info(ctx, fmt.Sprintf("[CREATE] Deploy Next Instance:%+v\n", providerConfig.Parameters.Hostname)) respData, err := r.client.PostDeviceInstance(providerConfig, int(resCfg.Timeout.ValueInt64())) if err != nil { resp.Diagnostics.AddError("Client Error", fmt.Sprintf("Failed to Deploy Instance, got error: %s", err)) return } - tflog.Info(ctx, fmt.Sprintf("[CREATE] respData ID:%+v\n", respData)) + tflog.Info(ctx, fmt.Sprintf("[CREATE] respData ID:%+v\n", string(respData))) resCfg.Id = types.StringValue(providerConfig.Parameters.Hostname) resp.Diagnostics.Append(resp.State.Set(ctx, resCfg)...) } @@ -321,3 +334,70 @@ func f5osRseriesConfig(ctx context.Context, data *NextDeployF5osResourceModel) * tflog.Info(ctx, fmt.Sprintf("cmReqDeviceInstance : %+v", cmReqDeviceInstance)) return &cmReqDeviceInstance } + +func f5osVelosConfig(ctx context.Context, data *NextDeployF5osResourceModel) *bigipnextsdk.CMReqDeviceInstance { + var deployConfig bigipnextsdk.CMReqDeviceInstance + deployConfig.TemplateName = "default-standalone-velos" + var providerModel F5OSProviderModel + diag := data.F5OSProvider.As(ctx, &providerModel, basetypes.ObjectAsOptions{}) + if diag.HasError() { + tflog.Error(ctx, fmt.Sprintf("F5OSProvider diag Error: %+v", diag.Errors())) + } + var instanceModel F5OSInstanceModel + diag = data.F5OSInstance.As(ctx, &instanceModel, basetypes.ObjectAsOptions{}) + if diag.HasError() { + tflog.Error(ctx, fmt.Sprintf("F5OSInstanceModel diag Error: %+v", diag.Errors())) + } + var cmReqDeviceInstance bigipnextsdk.CMReqDeviceInstance + cmReqDeviceInstance.TemplateName = "default-standalone-velos" + cmReqDeviceInstance.Parameters.Hostname = (instanceModel.InstanceHostname).ValueString() + cmReqDeviceInstance.Parameters.ManagementAddress = (instanceModel.MgmtAddress).ValueString() + cmReqDeviceInstance.Parameters.ManagementNetworkWidth = int((instanceModel.MgmtPrefix).ValueInt64()) + cmReqDeviceInstance.Parameters.DefaultGateway = (instanceModel.MgmtGateway).ValueString() + cmReqDeviceInstance.Parameters.ManagementCredentialsUsername = (instanceModel.MgmtUser).ValueString() + cmReqDeviceInstance.Parameters.ManagementCredentialsPassword = (instanceModel.MgmtPassword).ValueString() + cmReqDeviceInstance.Parameters.InstanceOneTimePassword = (instanceModel.MgmtPassword).ValueString() + + var vlanIds []int + for _, val := range instanceModel.VlanIDs.Elements() { + var ss int + _ = json.Unmarshal([]byte(val.String()), &ss) + vlanIds = append(vlanIds, ss) + } + var slotIds []int + for _, val := range instanceModel.SlotIDs.Elements() { + var ss int + _ = json.Unmarshal([]byte(val.String()), &ss) + slotIds = append(slotIds, ss) + } + // var dnsServ []string + // for _, val := range data.DnsServers.Elements() { + // var ss string + // _ = json.Unmarshal([]byte(val.String()), &ss) + // dnsServ = append(dnsServ, ss) + // } + // cmReqDeviceInstance.Parameters.DnsServers = dnsServ + // var ntpServ []string + // for _, val := range data.NtpServers.Elements() { + // var ss string + // _ = json.Unmarshal([]byte(val.String()), &ss) + // ntpServ = append(ntpServ, ss) + // } + // cmReqDeviceInstance.Parameters.NtpServers = ntpServ + + cmReqDeviceInstance.Parameters.InstantiationProvider = append(cmReqDeviceInstance.Parameters.InstantiationProvider, bigipnextsdk.CMReqInstantiationProvider{ + Id: data.ProviderId.ValueString(), + Name: providerModel.ProviderName.ValueString(), + Type: "velos", + }) + cmReqDeviceInstance.Parameters.VelosProperties = append(cmReqDeviceInstance.Parameters.VelosProperties, bigipnextsdk.CMReqVelosProperties{ + TenantImageName: instanceModel.TenantImageName.ValueString(), + TenantDeploymentFile: instanceModel.TenantDeploymentFile.ValueString(), + CpuCores: int(instanceModel.CpuCores.ValueInt64()), + DiskSize: int(instanceModel.DiskSize.ValueInt64()), + VlanIds: vlanIds, + SlotIds: slotIds, + }) + tflog.Info(ctx, fmt.Sprintf("cmReqDeviceInstance : %+v", cmReqDeviceInstance)) + return &cmReqDeviceInstance +} diff --git a/internal/provider/next_deploy_vmware_resource_test.go b/internal/provider/next_deploy_vmware_resource_test.go index 9171f05..2be9c0b 100644 --- a/internal/provider/next_deploy_vmware_resource_test.go +++ b/internal/provider/next_deploy_vmware_resource_test.go @@ -226,7 +226,7 @@ func TestUnitNextDeployVmwareResourceTC5(t *testing.T) { w.WriteHeader(http.StatusOK) _, _ = fmt.Fprintf(w, `{"_embedded":{"devices":[{"_links":{"self":{"href":"/v1/inventory?filter=hostname+eq+infraanovm01/37021437-2b5f-4e44-9f5e-6ea9838c5f7e"}},"address":"10.146.194.171","certificate_validated":"2024-03-07T06:56:51.915056Z","certificate_validity":false,"hostname":"infraanovm01","id":"37021437-2b5f-4e44-9f5e-6ea9838c5f7e","mode":"STANDALONE","platform_name":"VMware","platform_type":"VE","port":5443,"version":"20.1.0-2.279.0+0.0.75"}]},"_links":{"self":{"href":"/v1/inventory?filter=hostname+eq+infraanovm01"}},"count":1,"total":1}`) }) - mux.HandleFunc("/api/device/v1/inventory/37021437-2b5f-4e44-9f5e-6ea9838c5f7e", func(w http.ResponseWriter, r *http.Request) { + mux.HandleFunc("/api/v1/spaces/default/instances/37021437-2b5f-4e44-9f5e-6ea9838c5f7e", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) _, _ = fmt.Fprintf(w, `{"_links":{"self":{"href":"/v1/deletion-tasks/02752890-5660-450c-ace9-b8e0a86a15ad"}},"path":"/v1/deletion-tasks/02752890-5660-450c-ace9-b8e0a86a15ad"}`) }) diff --git a/internal/provider/provider.go b/internal/provider/provider.go index f18ae70..08fd4b5 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -178,9 +178,7 @@ func (p *BigipNextCMProvider) Configure(ctx context.Context, req provider.Config func (p *BigipNextCMProvider) Resources(ctx context.Context) []func() resource.Resource { return []func() resource.Resource{ NewNextCMAS3DeployResource, - NewNextCMFastHttpResource, NewNextCMBackupRestoreResource, - NewNextCMFastTemplateResource, NewNextCMCertificateResource, NewNextCMImportCertificateResource, NewNextCMDeviceProviderResource, diff --git a/vendor/gitswarm.f5net.com/terraform-providers/bigipnext/bigipnextcm.go b/vendor/gitswarm.f5net.com/terraform-providers/bigipnext/bigipnextcm.go index e602bb0..7f6e112 100644 --- a/vendor/gitswarm.f5net.com/terraform-providers/bigipnext/bigipnextcm.go +++ b/vendor/gitswarm.f5net.com/terraform-providers/bigipnext/bigipnextcm.go @@ -38,10 +38,13 @@ const ( uriCertificate = "/api/v1/spaces/default/certificates" uriCMUpgradeTask = "/upgrade-manager/v1/upgrade-tasks" uriAS3Root = "/api/v1/spaces/default/appsvcs" + uriDiscoverInstance = "/v1/spaces/default/instances" // uriCertificateUpdate = "/api/certificate/v1/certificates" uriGlobalResiliency = "/api/v1/spaces/default/gslb/gr-groups" uriGetGlobalResiliency = "/v1/spaces/default/gslb/gr-groups" uriGetAlert = "/alert/v1/alerts/?limit=1&sort=-start_time&filter=source%20eq%20%27DNS%27%20and%20status%20eq%20%27ACTIVE%27&select=summary" + uriWafReport = "/api/v1/spaces/default/security/waf/reports" + uriGetWafReport = "/v1/spaces/default/security/waf/reports" ) // BIG IP Next CM Config Request structure @@ -743,6 +746,26 @@ type Instance struct { GroupSyncAddress string `json:"group_sync_address,omitempty"` } +type CMWAFReportRequestDraft struct { + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + TimeFrameInDays int `json:"time_frame_in_days,omitempty"` + TopLevel int `json:"top_level,omitempty"` + RequestType string `json:"request_type,omitempty"` + UserDefined string `json:"user_defined,omitempty"` + CreatedBy string `json:"created_by,omitempty"` + Scope struct { + Entity string `json:"entity,omitempty"` + All bool `json:"all"` + Names []string `json:"names,omitempty"` + } `json:"scope,omitempty"` + Categories []Category `json:"categories,omitempty"` + Id string `json:"id,omitempty"` +} + +type Category struct { + Name string `json:"name,omitempty"` +} type FastDeployVirtual struct { VirtualName string `json:"virtualName,omitempty"` VirtualAddress string `json:"virtualAddress,omitempty"` @@ -934,6 +957,84 @@ func (p *BigipNextCM) GetAlertMessage() error { return fmt.Errorf("task failed, summary : %+v ", summary) } +// Create a WAF Security Report +// /api/v1/spaces/default/security/waf/reports +func (p *BigipNextCM) PostWAFReport(op string, config *CMWAFReportRequestDraft) (string, string, bool, error) { + wafURL := fmt.Sprintf("%s%s", p.Host, uriWafReport) + if op == "PUT" { + wafURL = fmt.Sprintf("%s%s/%s", p.Host, uriWafReport, config.Id) + } + f5osLogger.Info("[PostWAFReport]", "URI Path", wafURL) + f5osLogger.Info("[PostWAFReport]", "Config", hclog.Fmt("%+v", config)) + + body, err := json.Marshal(config) + + if err != nil { + return "", "", false, err + } + f5osLogger.Info("[PostWAFReport]", "Body", hclog.Fmt("%+v", string(body))) + respData, err := p.doCMRequest(op, wafURL, body) + if err != nil { + return "", "", false, err + } + f5osLogger.Info("[PostWAFReport]", "Data::", hclog.Fmt("%+v", string(respData))) + + respString := make(map[string]interface{}) + err = json.Unmarshal(respData, &respString) + if err != nil { + return "", "", false, err + } + f5osLogger.Info("[PostWAFReport]", "Task ID", hclog.Fmt("%+v", respString["id"].(string))) + + wafData, err := p.GetWAFReportDetails(respString["id"].(string)) + if err != nil { + return "", "", false, err + } + + return respString["id"].(string), wafData.(map[string]interface{})["created_by"].(string), wafData.(map[string]interface{})["user_defined"].(bool), nil + +} + +// GET request to get the details of the WAF Security Report +// +// /api/v1/spaces/default/security/waf/reports{id} +func (p *BigipNextCM) GetWAFReportDetails(id string) (interface{}, error) { + getWAFReportDetailsUrl := fmt.Sprintf("%s/%s", uriGetWafReport, id) + f5osLogger.Info("[GetWAFReportDetails]", "GetWAFReportDetails Url", getWAFReportDetailsUrl) + + respData, err := p.GetCMRequest(getWAFReportDetailsUrl) + if err != nil { + return "", err + } + f5osLogger.Info("[GetWAFReportDetails]", "Data::", hclog.Fmt("%+v", string(respData))) + + var respInfo map[string]interface{} + err = json.Unmarshal(respData, &respInfo) + if err != nil { + return "", err + } + f5osLogger.Info("[GetWAFReportDetails]", "Resp Message", hclog.Fmt("%+v", respInfo)) + + return respInfo, nil +} + +// DELETE request to delete the WAF Security Report +// +// /api/v1/spaces/default/security/waf/reports{id} +func (p *BigipNextCM) DeleteWAFReport(id string) error { + + deleteWAFReportUrl := fmt.Sprintf("%s%s/%s", p.Host, uriWafReport, id) + f5osLogger.Info("[DeleteWAFReport]", "URI Path", deleteWAFReportUrl) + + _, err := p.doCMRequest("DELETE", deleteWAFReportUrl, nil) + if err != nil { + return err + } + + f5osLogger.Info("[DeleteWAFReport]", "WAF Report Deleted Successfully") + return nil +} + // mgmt/shared/fast/appsvcs/ac6b8145-c1bf-4140-b2cb-4358cc742931/deployments // create GET request to get Fast application draft deployments func (p *BigipNextCM) GetFastApplicationDraftDeployments(draftID string) error { @@ -1209,6 +1310,146 @@ func (p *BigipNextCM) DeleteAS3DeploymentTask(docID string) error { return nil } +type DiscoverInstanceRequest struct { + Address string `json:"address,omitempty"` + Port int `json:"port,omitempty"` + DeviceUser string `json:"device_user,omitempty"` + DevicePassword string `json:"device_password,omitempty"` + ManagementUser string `json:"management_user,omitempty"` + ManagementPassword string `json:"management_password,omitempty"` +} + +// create POST request to Add instance to CM +func (p *BigipNextCM) DiscoverInstance(config *DiscoverInstanceRequest) ([]byte, error) { + if config.DevicePassword == "admin" { + err := config.resetDevicePassword() + if err != nil { + return nil, err + } + f5osLogger.Info("[DiscoverInstance]", "admin password reset successfully") + time.Sleep(2 * time.Second) + config.DevicePassword = config.ManagementPassword + } + body, err := json.Marshal(config) + if err != nil { + return nil, err + } + respData, err := p.PostCMRequest(uriDiscoverInstance, body) + if err != nil { + return nil, err + } + f5osLogger.Info("[DiscoverInstance]", "Data::", hclog.Fmt("%+v", string(respData))) + respString := make(map[string]interface{}) + err = json.Unmarshal(respData, &respString) + if err != nil { + return nil, err + } + f5osLogger.Info("[DiscoverInstance]", "Task Path", hclog.Fmt("%+v", respString["path"].(string))) + pathList := strings.Split(respString["path"].(string), "/") + + err = p.acceptUntrustedCertificate(pathList[len(pathList)-1]) + if err != nil { + return nil, err + } + f5osLogger.Info("[getDiscoverInstanceTaskStatus]", "Data::", hclog.Fmt("%+v", string(respData))) + respData, err = p.getDiscoverInstanceTaskStatus(pathList[len(pathList)-1]) + if err != nil { + return nil, err + } + return respData, nil +} + +// Accept untrusted certificate for the device +func (p *BigipNextCM) acceptUntrustedCertificate(taskid string) error { + acceptUntrust := true + unTrust := make(map[string]interface{}) + if acceptUntrust { + unTrust["is_user_accepted_untrusted_cert"] = true + } + body, err := json.Marshal(unTrust) + if err != nil { + return err + } + getTaskUrl := fmt.Sprintf("%s/api%s%s/%s", p.Host, uriDiscoverInstance, "/discovery-tasks", taskid) + respData, err := p.doCMRequest("PATCH", getTaskUrl, body) + if err != nil { + return err + } + f5osLogger.Info("[AcceptUntrustedCertificate]", "Data::", hclog.Fmt("%+v", string(respData))) + return nil +} + +// Check the status of the discovery task +func (p *BigipNextCM) getDiscoverInstanceTaskStatus(taskid string) ([]byte, error) { + getTaskUrl := fmt.Sprintf("%s%s/%s", uriDiscoverInstance, "/discovery-tasks", taskid) + f5osLogger.Info("[getDiscoverInstanceTaskStatus]", "getTaskUrl", getTaskUrl) + var respInfo map[string]interface{} + timeout := 360 * time.Second + endtime := time.Now().Add(timeout) + for time.Now().Before(endtime) { + respData, err := p.GetCMRequest(getTaskUrl) + if err != nil { + return nil, err + } + f5osLogger.Info("[getDiscoverInstanceTaskStatus]", "Data::", hclog.Fmt("%+v", string(respData))) + // {"_links":{"self":{"href":"/api/v1/spaces/default/instances/discovery-tasks/2e718d16-66af-4a11-960a-cd2dfcf48229"}},"address":"10.145.71.115","created":"2024-04-05T17:43:27.382035Z","device_group":"default","device_user":"admin","fingerprint":"771caf5eaf0718911c4da754fd7bc998797066992c6ebb6129f5dcf58528aba4","id":"2e718d16-66af-4a11-960a-cd2dfcf48229","port":5443,"state":"discoveryWaitForUserInput","status":"running"} + err = json.Unmarshal(respData, &respInfo) + if err != nil { + return nil, err + } + if respInfo["status"].(string) == "completed" { + return []byte(respInfo["discovered_device_id"].(string)), nil + } + if respInfo["status"].(string) == "failed" { + return respData, fmt.Errorf("discovery-tasks failed with :%+v", respInfo["failure_reason"].(string)) + } + time.Sleep(10 * time.Second) + } + return []byte(""), fmt.Errorf("task status is still in :%+v within timeout period of:%+v", respInfo["status"].(string), timeout) +} + +// reset the device password +func (d *DiscoverInstanceRequest) resetDevicePassword() error { + urlString := fmt.Sprintf("https://%s:%d%s", d.Address, d.Port, "/api/v1/me") + f5osLogger.Info("[resetDevicePassword]", "getTaskUrl", urlString) + resetPassword := make(map[string]interface{}) + resetPassword["currentPassword"] = d.DevicePassword + resetPassword["newPassword"] = d.ManagementPassword + body, err := json.Marshal(resetPassword) + if err != nil { + return err + } + tr := &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: true, + }, + } + client := &http.Client{ + Transport: tr, + } + method := "PUT" + f5osLogger.Info("[resetDevicePassword]", "URL", hclog.Fmt("%+v", urlString)) + req, err := http.NewRequest(method, urlString, bytes.NewBuffer(body)) + if err != nil { + return err + } + req.Header.Set("Content-Type", contentTypeHeader) + req.SetBasicAuth(d.DeviceUser, string(d.DevicePassword)) + res, err := client.Do(req) + if err != nil { + return err + } + defer res.Body.Close() + bodyResp, err := io.ReadAll(res.Body) + if err != nil { + return err + } + if res.StatusCode != 204 { + return fmt.Errorf("error message: %+v (Body:%+v)", res.Status, string(bodyResp)) + } + return nil +} + // func standardizeSpaces(s string) string { // return strings.Join(strings.Fields(s), " ") // } @@ -1723,14 +1964,34 @@ func (p *BigipNextCM) GetDeviceIdByHostname(deviceHostname string) (deviceId *st return nil, fmt.Errorf("the requested device:%s, was not found", deviceHostname) } +func (p *BigipNextCM) GetDeviceInfoByID(deviceId string) (interface{}, error) { + // deviceUrl := fmt.Sprintf("%s/%s", uriInventory, deviceId) + deviceUrl := fmt.Sprintf("%s/%s", uriDiscoverInstance, deviceId) + url := fmt.Sprintf("%s%s%s", p.Host, uriCMRoot, deviceUrl) + f5osLogger.Info("[GetDeviceInfoByID]", "Request path", hclog.Fmt("%+v", url)) + dataResource, err := p.doCMRequest("GET", url, nil) + if err != nil { + return nil, err + } + f5osLogger.Info("[GetDeviceInfoByID]", "Data::", hclog.Fmt("%+v", string(dataResource))) + var deviceInfo interface{} + err = json.Unmarshal(dataResource, &deviceInfo) + if err != nil { + return nil, err + } + return deviceInfo, nil +} + // delete device from CM func (p *BigipNextCM) DeleteDevice(deviceId string) error { - deviceUrl := fmt.Sprintf("%s/%s", uriInventory, deviceId) + // deviceUrl := fmt.Sprintf("%s/%s", uriInventory, deviceId) + deviceUrl := fmt.Sprintf("%s/%s", uriDiscoverInstance, deviceId) url := fmt.Sprintf("%s%s%s", p.Host, uriCMRoot, deviceUrl) f5osLogger.Info("[DeleteDevice]", "Request path", hclog.Fmt("%+v", url)) //{"save_backup":false} var data = []byte(`{"save_backup":false}`) respData, err := p.doCMRequest("DELETE", url, data) + // respData, err := p.DeleteCMRequest("DELETE", deviceUrl, data) if err != nil { return err } @@ -2034,24 +2295,6 @@ func (p *BigipNextCM) GetDeviceProvider(providerId, providerType string) (*Devic return &providerResp, nil } -// -//func (p *BigipNextCM) AddVsphereProvider(config *ProviderRequest) ([]byte, error) { -// providerConfig := &DeviceProvider{} -// providerConfig.Name = config.ProviderName -// providerConfig.Type = "VSPHERE" -// providerConfig.Connection.Host = config.Hostname -// providerConfig.Connection.Authentication.Type = "basic" -// providerConfig.Connection.Authentication.Username = config.Username -// providerConfig.Connection.Authentication.Password = config.Password -// f5osLogger.Info("[AddVsphereProvider]", "Config::", hclog.Fmt("%+v", providerConfig)) -// respData, err := p.PostDeviceProvider(providerConfig) -// if err != nil { -// return nil, err -// } -// f5osLogger.Info("[AddVsphereProvider]", "Response::", hclog.Fmt("%+v", string(respData))) -// return respData, nil -//} - // https://10.145.75.237/api/device/v1/providers/vsphere/85bc71c3-0bfc-4b28-bb86-13f7e1c1d7af // Create function to delete device provider using provider id func (p *BigipNextCM) DeleteDeviceProvider(providerId, providerType string) ([]byte, error) { @@ -2236,6 +2479,15 @@ type CMReqRseriesProperties struct { // Hostname string `json:"hostname"` } +type CMReqVelosProperties struct { + TenantImageName string `json:"tenant_image_name"` + TenantDeploymentFile string `json:"tenant_deployment_file"` + VlanIds []int `json:"vlan_ids"` + SlotIds []int `json:"slot_ids"` + DiskSize int `json:"disk_size"` + CpuCores int `json:"cpu_cores"` +} + type CMReqDeviceInstance struct { TemplateName string `json:"template_name,omitempty"` Parameters struct { @@ -2243,6 +2495,7 @@ type CMReqDeviceInstance struct { VSphereProperties []CMReqVsphereProperties `json:"vSphere_properties,omitempty"` VsphereNetworkAdapterSettings []CMReqVsphereNetworkAdapterSettings `json:"vsphere_network_adapter_settings,omitempty"` RseriesProperties []CMReqRseriesProperties `json:"rseries_properties,omitempty"` + VelosProperties []CMReqVelosProperties `json:"velos_properties,omitempty"` DnsServers []string `json:"dns_servers,omitempty"` NtpServers []string `json:"ntp_servers,omitempty"` ManagementAddress string `json:"management_address,omitempty"` @@ -2353,8 +2606,8 @@ func (p *BigipNextCM) GetDeviceInstanceTaskStatus(taskID string, timeOut int) (m taskData := make(map[string]interface{}) instanceUrl := fmt.Sprintf("%s%s", "/device/v1/instances/tasks/", taskID) f5osLogger.Debug("[GetDeviceInstanceTaskStatus]", "URI Path", instanceUrl) - var timeout time.Duration - timeout = time.Duration(timeOut) * time.Second + // var timeout time.Duration + timeout := time.Duration(timeOut) * time.Second endtime := time.Now().Add(timeout) for time.Now().Before(endtime) { respData, err := p.GetCMRequest(instanceUrl) @@ -2375,13 +2628,13 @@ func (p *BigipNextCM) GetDeviceInstanceTaskStatus(taskID string, timeOut int) (m inVal := timeOut / 10 time.Sleep(time.Duration(inVal) * time.Second) } - return nil, fmt.Errorf("Task Status is still in :%+v within timeout period of:%+v", taskData["status"], timeout) + return nil, fmt.Errorf("task Status is still in :%+v within timeout period of:%+v", taskData["status"], timeout) } -// convert a string to byte array -func stringToByteArray(str string) []byte { - return []byte(str) -} +// // convert a string to byte array +// func stringToByteArray(str string) []byte { +// return []byte(str) +// } func (p *BigipNextCM) GetDeviceProviderIDByHostname(hostname string) (interface{}, error) { uriProviders := "/device/v1/providers" @@ -2400,7 +2653,7 @@ func (p *BigipNextCM) GetDeviceProviderIDByHostname(hostname string) (interface{ if len(providerResp) == 1 && providerResp[0].(map[string]interface{})["provider_name"].(string) == hostname { return providerResp[0].(map[string]interface{})["provider_id"].(string), nil } - return nil, fmt.Errorf("Failed to get ID for provider: %+v", hostname) + return nil, fmt.Errorf("failed to get ID for provider: %+v", hostname) } // https://10.145.75.237/api/llm/license/a2064013-659d-4de0-8c22-773d21414885/status