From 71555a65698bfc2a830b46fd4b5492b6ac405d75 Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Thu, 1 Dec 2022 11:52:49 +0800 Subject: [PATCH 01/35] temp --- internal/clients/client.go | 3 + internal/provider/services.go | 2 + .../extendedlocation/client/client.go | 19 + .../extended_location_custom_locations.go | 325 ++++++++++++++++++ ...extended_location_custom_locations_test.go | 105 ++++++ .../services/extendedlocation/registration.go | 25 ++ 6 files changed, 479 insertions(+) create mode 100644 internal/services/extendedlocation/client/client.go create mode 100644 internal/services/extendedlocation/extended_location_custom_locations.go create mode 100644 internal/services/extendedlocation/extended_location_custom_locations_test.go create mode 100644 internal/services/extendedlocation/registration.go diff --git a/internal/clients/client.go b/internal/clients/client.go index 32d90814c388..b70a4957032c 100644 --- a/internal/clients/client.go +++ b/internal/clients/client.go @@ -73,6 +73,7 @@ import ( elasticsan "github.com/hashicorp/terraform-provider-azurerm/internal/services/elasticsan/client" eventgrid "github.com/hashicorp/terraform-provider-azurerm/internal/services/eventgrid/client" eventhub "github.com/hashicorp/terraform-provider-azurerm/internal/services/eventhub/client" + extendedlocation "github.com/hashicorp/terraform-provider-azurerm/internal/services/extendedlocation/client" fluidrelay "github.com/hashicorp/terraform-provider-azurerm/internal/services/fluidrelay/client" frontdoor "github.com/hashicorp/terraform-provider-azurerm/internal/services/frontdoor/client" graph "github.com/hashicorp/terraform-provider-azurerm/internal/services/graphservices/client" @@ -210,6 +211,7 @@ type Client struct { ElasticSan *elasticsan.Client EventGrid *eventgrid_v2022_06_15.Client Eventhub *eventhub.Client + ExtendedLocation *extendedlocation.Client FluidRelay *fluidrelay_2022_05_26.Client Frontdoor *frontdoor.Client Graph *graph.Client @@ -447,6 +449,7 @@ func (client *Client) Build(ctx context.Context, o *common.ClientOptions) error if client.Eventhub, err = eventhub.NewClient(o); err != nil { return fmt.Errorf("building clients for Eventhub: %+v", err) } + client.ExtendedLocation = extendedlocation.NewClient(o) if client.FluidRelay, err = fluidrelay.NewClient(o); err != nil { return fmt.Errorf("building clients for FluidRelay: %+v", err) } diff --git a/internal/provider/services.go b/internal/provider/services.go index 30fb0e987a0f..5832aafdc39d 100644 --- a/internal/provider/services.go +++ b/internal/provider/services.go @@ -53,6 +53,7 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/services/elasticsan" "github.com/hashicorp/terraform-provider-azurerm/internal/services/eventgrid" "github.com/hashicorp/terraform-provider-azurerm/internal/services/eventhub" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/extendedlocation" "github.com/hashicorp/terraform-provider-azurerm/internal/services/firewall" "github.com/hashicorp/terraform-provider-azurerm/internal/services/fluidrelay" "github.com/hashicorp/terraform-provider-azurerm/internal/services/frontdoor" @@ -171,6 +172,7 @@ func SupportedTypedServices() []sdk.TypedServiceRegistration { domainservices.Registration{}, elasticsan.Registration{}, eventhub.Registration{}, + extendedlocation.Registration{}, fluidrelay.Registration{}, graphservices.Registration{}, storagecache.Registration{}, diff --git a/internal/services/extendedlocation/client/client.go b/internal/services/extendedlocation/client/client.go new file mode 100644 index 000000000000..d84259825c70 --- /dev/null +++ b/internal/services/extendedlocation/client/client.go @@ -0,0 +1,19 @@ +package client + +import ( + "github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations" + "github.com/hashicorp/terraform-provider-azurerm/internal/common" +) + +type Client struct { + CustomLocationsClient *customlocations.CustomLocationsClient +} + +func NewClient(o *common.ClientOptions) *Client { + customLocationsClient := customlocations.NewCustomLocationsClientWithBaseURI(o.ResourceManagerEndpoint) + o.ConfigureClient(&customLocationsClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + CustomLocationsClient: &customLocationsClient, + } +} diff --git a/internal/services/extendedlocation/extended_location_custom_locations.go b/internal/services/extendedlocation/extended_location_custom_locations.go new file mode 100644 index 000000000000..fff63c03add0 --- /dev/null +++ b/internal/services/extendedlocation/extended_location_custom_locations.go @@ -0,0 +1,325 @@ +package extendedlocation + +import ( + "context" + "fmt" + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" + "github.com/hashicorp/terraform-provider-azurerm/utils" + "time" +) + +type CustomLocationResource struct{} + +type CustomLocationResourceModel struct { + Name string `tfschema:"name"` + ResourceGroupName string `tfschema:"resource_group_name"` + Location string `tfschema:"location"` + AuthenticationType string `tfschema:"authentication_type"` + AuthenticationValue string `tfschema:"authentication_value"` + ClusterExtensionIds []string `tfschema:"cluster_extension_ids"` + DisplayName string `tfschema:"display_name"` + HostResourceId string `tfschema:"host_resource_id"` + HostType string `tfschema:"host_type"` + Namespace string `tfschema:"namespace"` +} + +func (r CustomLocationResource) Arguments() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "resource_group_name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "location": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "cluster_extension_ids": { + Type: pluginsdk.TypeList, + Required: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + + "host_resource_id": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "authentication_type": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "authentication_value": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "display_name": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "host_type": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + string(customlocations.HostTypeKubernetes), + }, false), + }, + + "namespace": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + } +} + +func (r CustomLocationResource) Attributes() map[string]*schema.Schema { + return map[string]*schema.Schema{} +} + +func (r CustomLocationResource) ModelObject() interface{} { + return &CustomLocationResourceModel{} +} + +func (r CustomLocationResource) ResourceType() string { + return "azurerm_extended_custom_locations" +} + +func (r CustomLocationResource) Create() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + var model CustomLocationResourceModel + if err := metadata.Decode(&model); err != nil { + return err + } + + subscriptionId := metadata.Client.Account.SubscriptionId + client := metadata.Client.ExtendedLocation.CustomLocationsClient + + id := customlocations.NewCustomLocationID(subscriptionId, model.ResourceGroupName, model.Name) + existing, err := client.Get(ctx, id) + if err != nil && !response.WasNotFound(existing.HttpResponse) { + return fmt.Errorf("checking for presence of existing %s: %+v", id, err) + } + + if !response.WasNotFound(existing.HttpResponse) { + return metadata.ResourceRequiresImport(r.ResourceType(), id) + } + + customLocationProps := customlocations.CustomLocationProperties{} + + if model.AuthenticationValue != "" && model.AuthenticationType != "" { + customLocationProps.Authentication = &customlocations.CustomLocationPropertiesAuthentication{ + Type: &model.AuthenticationType, + Value: &model.AuthenticationValue, + } + } + + if model.ClusterExtensionIds != nil { + customLocationProps.ClusterExtensionIds = &model.ClusterExtensionIds + } + + if model.DisplayName != "" { + customLocationProps.DisplayName = &model.DisplayName + } + + if model.HostResourceId != "" { + customLocationProps.HostResourceId = &model.HostResourceId + } + + if model.HostType != "" { + hostType := customlocations.HostType(model.HostType) + customLocationProps.HostType = &hostType + } + + if model.Namespace != "" { + customLocationProps.Namespace = &model.Namespace + } + + props := customlocations.CustomLocation{ + Id: utils.String(id.ID()), + Location: model.Location, + Name: utils.String(model.Name), + Properties: &customLocationProps, + } + + if err := client.CreateOrUpdateThenPoll(ctx, id, props); err != nil { + return fmt.Errorf("creating %s: %+v", id, err) + } + + metadata.SetID(id) + return nil + }, + } +} + +func (r CustomLocationResource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.ExtendedLocation.CustomLocationsClient + id, err := customlocations.ParseCustomLocationID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + resp, err := client.Get(ctx, *id) + if err != nil { + if response.WasNotFound(resp.HttpResponse) { + return metadata.MarkAsGone(id) + } + return fmt.Errorf("reading %s: %+v", *id, err) + } + + if model := resp.Model; model != nil { + props := model.Properties + + state := CustomLocationResourceModel{ + Name: id.ResourceName, + ResourceGroupName: id.ResourceGroupName, + Location: model.Location, + } + + if props.Authentication != nil && props.Authentication.Type != nil && props.Authentication.Value != nil { + state.AuthenticationType = *props.Authentication.Type + state.AuthenticationValue = *props.Authentication.Value + } + + if props.ClusterExtensionIds != nil { + state.ClusterExtensionIds = *props.ClusterExtensionIds + } + + if props.DisplayName != nil { + state.DisplayName = *props.DisplayName + } + + if props.HostResourceId != nil { + state.HostResourceId = *props.HostResourceId + } + + if props.HostType != nil { + state.HostType = string(*props.HostType) + } + + if props.Namespace != nil { + state.Namespace = *props.Namespace + } + + return metadata.Encode(&state) + } + return nil + }, + } +} + +func (r CustomLocationResource) Delete() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.ExtendedLocation.CustomLocationsClient + id, err := customlocations.ParseCustomLocationID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + metadata.Logger.Infof("deleting %s", *id) + + if resp, err := client.Delete(ctx, *id); err != nil { + if !response.WasNotFound(resp.HttpResponse) { + return fmt.Errorf("deleting %s: %+v", *id, err) + } + } + + return nil + }, + } +} + +func (r CustomLocationResource) Update() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.ExtendedLocation.CustomLocationsClient + id, err := customlocations.ParseCustomLocationID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + var state CustomLocationResourceModel + if err := metadata.Decode(&state); err != nil { + return fmt.Errorf("decoding %+v", err) + } + + customLocationProps := customlocations.CustomLocationProperties{} + d := metadata.ResourceData + + if d.HasChanges("authentication_type", "authentication_value") { + customLocationProps.Authentication = &customlocations.CustomLocationPropertiesAuthentication{ + Type: &state.AuthenticationType, + Value: &state.AuthenticationValue, + } + } + + if d.HasChange("cluster_extension_ids") { + customLocationProps.ClusterExtensionIds = &state.ClusterExtensionIds + } + + if d.HasChange("display_name") { + customLocationProps.DisplayName = &state.DisplayName + } + + if d.HasChange("host_resource_id") { + customLocationProps.HostResourceId = &state.HostResourceId + } + + if d.HasChange("host_type") { + hostType := customlocations.HostType(state.HostType) + customLocationProps.HostType = &hostType + } + + if d.HasChange("namespace") { + customLocationProps.Namespace = &state.Namespace + } + + props := customlocations.PatchableCustomLocations{ + Properties: &customLocationProps, + } + + if _, err := client.Update(ctx, *id, props); err != nil { + return fmt.Errorf("updating %s: %+v", *id, err) + } + return nil + }, + } +} + +func (r CustomLocationResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return customlocations.ValidateCustomLocationID +} diff --git a/internal/services/extendedlocation/extended_location_custom_locations_test.go b/internal/services/extendedlocation/extended_location_custom_locations_test.go new file mode 100644 index 000000000000..3fc79c6a061a --- /dev/null +++ b/internal/services/extendedlocation/extended_location_custom_locations_test.go @@ -0,0 +1,105 @@ +package extendedlocation_test + +import ( + "context" + "fmt" + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/utils" + "testing" +) + +type CustomLocationResource struct{} + +func (r CustomLocationResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { + id, err := customlocations.ParseCustomLocationID(state.ID) + if err != nil { + return nil, err + } + + resp, err := client.ExtendedLocation.CustomLocationsClient.Get(ctx, *id) + if err != nil { + if response.WasNotFound(resp.HttpResponse) { + return utils.Bool(false), nil + } + return nil, fmt.Errorf("retrieving %s: %+v", *id, err) + } + return utils.Bool(true), nil +} + +func TestAccExtendedLocationCustomLocations_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_extended_custom_locations", "test") + r := CustomLocationResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func (r CustomLocationResource) basic(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_extended_custom_locations" "test" { + name = "acctestcustomlocation%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + cluster_extension_ids = [ + "${azurerm_kubernetes_cluster.test.id}/providers/Microsoft.KubernetesConfiguration/extensions/foo" + ] + display_name = "customlocation%[2]d" + namespace = "namespace%[2]d" + host_resource_id = azurerm_kubernetes_cluster.test.id +} +`, template, data.RandomInteger) +} + +func (r CustomLocationResource) template(data acceptance.TestData) string { + data.Locations.Primary = "westus" + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%[1]d" + location = "%[2]s" +} + +data "azurerm_extended_locations" "test" { + location = azurerm_resource_group.test.location +} + +resource "azurerm_kubernetes_cluster" "test" { + name = "acctestaks%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + dns_prefix = "acctestaks%[1]d" + kubernetes_version = "1.24.3" + run_command_enabled = true + + default_node_pool { + name = "default" + node_count = 1 + vm_size = "Standard_ds2_v2" + } + identity { + type = "SystemAssigned" + } + tags = { + ENV = "Test1" + } +} +`, data.RandomInteger, data.Locations.Primary) +} diff --git a/internal/services/extendedlocation/registration.go b/internal/services/extendedlocation/registration.go new file mode 100644 index 000000000000..237e286ca983 --- /dev/null +++ b/internal/services/extendedlocation/registration.go @@ -0,0 +1,25 @@ +package extendedlocation + +import "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" + +type Registration struct{} + +var _ sdk.TypedServiceRegistration = Registration{} + +func (r Registration) WebsiteCategories() []string { + return []string{} +} + +func (r Registration) DataSources() []sdk.DataSource { + return []sdk.DataSource{} +} + +func (r Registration) Resources() []sdk.Resource { + return []sdk.Resource{ + CustomLocationResource{}, + } +} + +func (r Registration) Name() string { + return "ExtendedLocation" +} From 099f399303556e969aaebcf8a64ffd264e97dc89 Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Thu, 8 Dec 2022 10:38:39 +0800 Subject: [PATCH 02/35] acc test --- .../extended_location_custom_locations_test.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/internal/services/extendedlocation/extended_location_custom_locations_test.go b/internal/services/extendedlocation/extended_location_custom_locations_test.go index 3fc79c6a061a..2bf5fb9a35a9 100644 --- a/internal/services/extendedlocation/extended_location_custom_locations_test.go +++ b/internal/services/extendedlocation/extended_location_custom_locations_test.go @@ -51,6 +51,12 @@ func (r CustomLocationResource) basic(data acceptance.TestData) string { return fmt.Sprintf(` %s +resource "azurerm_role_assignment" "admin" { + scope = azurerm_kubernetes_cluster.test.id + role_definition_name = "Azure Kubernetes Service RBAC Cluster Admin" + principal_id = "51dfe1e8-70c6-4de5-a08e-e18aff23d815" +} + resource "azurerm_extended_custom_locations" "test" { name = "acctestcustomlocation%d" resource_group_name = azurerm_resource_group.test.name @@ -66,7 +72,7 @@ resource "azurerm_extended_custom_locations" "test" { } func (r CustomLocationResource) template(data acceptance.TestData) string { - data.Locations.Primary = "westus" + data.Locations.Primary = "westus2" return fmt.Sprintf(` provider "azurerm" { features {} From cb30a8fd202c0316712482d214833c8fefd89679 Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Wed, 14 Jun 2023 14:12:00 +0800 Subject: [PATCH 03/35] extended location temp --- ...extended_location_custom_locations_test.go | 229 ++++++++++++++-- .../testdata/install_agent.py | 248 ++++++++++++++++++ .../testdata/install_agent.sh.tftpl | 38 +++ .../extendedlocation/testdata/kind.yaml | 20 ++ 4 files changed, 507 insertions(+), 28 deletions(-) create mode 100644 internal/services/extendedlocation/testdata/install_agent.py create mode 100644 internal/services/extendedlocation/testdata/install_agent.sh.tftpl create mode 100644 internal/services/extendedlocation/testdata/kind.yaml diff --git a/internal/services/extendedlocation/extended_location_custom_locations_test.go b/internal/services/extendedlocation/extended_location_custom_locations_test.go index 2bf5fb9a35a9..5532b3cfa908 100644 --- a/internal/services/extendedlocation/extended_location_custom_locations_test.go +++ b/internal/services/extendedlocation/extended_location_custom_locations_test.go @@ -2,6 +2,11 @@ package extendedlocation_test import ( "context" + cryptoRand "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/base64" + "encoding/pem" "fmt" "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations" @@ -10,6 +15,8 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" + "math/rand" + "os" "testing" ) @@ -34,10 +41,15 @@ func (r CustomLocationResource) Exists(ctx context.Context, client *clients.Clie func TestAccExtendedLocationCustomLocations_basic(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_extended_custom_locations", "test") r := CustomLocationResource{} + credential := fmt.Sprintf("P@$$w0rd%d!", rand.Intn(10000)) + privateKey, publicKey, err := CustomLocationResource{}.generateKey() + if err != nil { + t.Fatalf("failed to generate key: %+v", err) + } data.ResourceTest(t, r, []acceptance.TestStep{ { - Config: r.basic(data), + Config: r.basic(data, credential, privateKey, publicKey), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), @@ -46,36 +58,40 @@ func TestAccExtendedLocationCustomLocations_basic(t *testing.T) { }) } -func (r CustomLocationResource) basic(data acceptance.TestData) string { - template := r.template(data) +func (r CustomLocationResource) basic(data acceptance.TestData, credential string, privateKey string, publicKey string) string { + template := r.template(data, credential, privateKey, publicKey) return fmt.Sprintf(` %s -resource "azurerm_role_assignment" "admin" { - scope = azurerm_kubernetes_cluster.test.id - role_definition_name = "Azure Kubernetes Service RBAC Cluster Admin" - principal_id = "51dfe1e8-70c6-4de5-a08e-e18aff23d815" -} +//resource "azurerm_role_assignment" "admin" { +// scope = azurerm_kubernetes_cluster.test.id +// role_definition_name = "Azure Kubernetes Service RBAC Cluster Admin" +// principal_id = "51dfe1e8-70c6-4de5-a08e-e18aff23d815" +//} resource "azurerm_extended_custom_locations" "test" { name = "acctestcustomlocation%d" resource_group_name = azurerm_resource_group.test.name location = azurerm_resource_group.test.location cluster_extension_ids = [ - "${azurerm_kubernetes_cluster.test.id}/providers/Microsoft.KubernetesConfiguration/extensions/foo" + "${azurerm_arc_kubernetes_cluster_extension.test.id}" ] display_name = "customlocation%[2]d" namespace = "namespace%[2]d" - host_resource_id = azurerm_kubernetes_cluster.test.id + host_resource_id = azurerm_arc_kubernetes_cluster.test.id } `, template, data.RandomInteger) } -func (r CustomLocationResource) template(data acceptance.TestData) string { - data.Locations.Primary = "westus2" +func (r CustomLocationResource) template(data acceptance.TestData, credential string, privateKey string, publicKey string) string { + data.Locations.Primary = "eastus" return fmt.Sprintf(` provider "azurerm" { - features {} + features { + resource_group { + prevent_deletion_if_contains_resources = false + } + } } resource "azurerm_resource_group" "test" { @@ -83,29 +99,186 @@ resource "azurerm_resource_group" "test" { location = "%[2]s" } -data "azurerm_extended_locations" "test" { - location = azurerm_resource_group.test.location +resource "azurerm_virtual_network" "test" { + name = "acctestnw-%[1]d" + address_space = ["10.0.0.0/16"] + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name } -resource "azurerm_kubernetes_cluster" "test" { - name = "acctestaks%[1]d" +resource "azurerm_subnet" "test" { + name = "internal" + resource_group_name = azurerm_resource_group.test.name + virtual_network_name = azurerm_virtual_network.test.name + address_prefixes = ["10.0.2.0/24"] +} + +resource "azurerm_public_ip" "test" { + name = "acctestpip-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + allocation_method = "Static" +} + +resource "azurerm_network_interface" "test" { + name = "acctestnic-%[1]d" location = azurerm_resource_group.test.location resource_group_name = azurerm_resource_group.test.name - dns_prefix = "acctestaks%[1]d" - kubernetes_version = "1.24.3" - run_command_enabled = true - - default_node_pool { - name = "default" - node_count = 1 - vm_size = "Standard_ds2_v2" + ip_configuration { + name = "internal" + subnet_id = azurerm_subnet.test.id + private_ip_address_allocation = "Dynamic" + public_ip_address_id = azurerm_public_ip.test.id } +} + +resource "azurerm_network_security_group" "my_terraform_nsg" { + name = "myNetworkSecurityGroup" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + security_rule { + name = "SSH" + priority = 1001 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "22" + source_address_prefix = "*" + destination_address_prefix = "*" + } +} + +resource "azurerm_network_interface_security_group_association" "example" { + network_interface_id = azurerm_network_interface.test.id + network_security_group_id = azurerm_network_security_group.my_terraform_nsg.id +} + +resource "azurerm_linux_virtual_machine" "test" { + name = "acctestVM-%[1]d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + size = "Standard_F2" + admin_username = "adminuser" + admin_password = "%[3]s" + provision_vm_agent = false + allow_extension_operations = false + disable_password_authentication = false + network_interface_ids = [ + azurerm_network_interface.test.id, + ] + os_disk { + caching = "ReadWrite" + storage_account_type = "Standard_LRS" + } + source_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "18.04-LTS" + version = "latest" + } +} + +data "azurerm_extended_locations" "test" { + location = azurerm_resource_group.test.location +} + +resource "azurerm_arc_kubernetes_cluster" "test" { + name = "acctest-akcc-%[1]d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + agent_public_key_certificate = "%[4]s" identity { type = "SystemAssigned" } - tags = { - ENV = "Test1" + + %[5]s + + depends_on = [ + azurerm_linux_virtual_machine.test + ] +} + +resource "azurerm_arc_kubernetes_cluster_extension" "test" { + name = "foo" + cluster_id = azurerm_arc_kubernetes_cluster.test.id + extension_type = "microsoft.flux" + + identity { + type = "SystemAssigned" } + + depends_on = [ + azurerm_linux_virtual_machine.test + ] +} +`, data.RandomInteger, data.Locations.Primary, credential, publicKey, r.provisionTemplate(data, credential, privateKey)) +} + +func (r CustomLocationResource) generateKey() (string, string, error) { + privateKey, err := rsa.GenerateKey(cryptoRand.Reader, 4096) + if err != nil { + return "", "", fmt.Errorf("failed to generate RSA key") + } + + privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey) + privateKeyBlock := &pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: privateKeyBytes, + } + + privatePem := pem.EncodeToMemory(privateKeyBlock) + if privatePem == nil { + return "", "", fmt.Errorf("failed to encode pem") + } + + return string(privatePem), base64.StdEncoding.EncodeToString(x509.MarshalPKCS1PublicKey(&privateKey.PublicKey)), nil +} + +func (r CustomLocationResource) provisionTemplate(data acceptance.TestData, credential string, privateKey string) string { + return fmt.Sprintf(` +connection { + type = "ssh" + host = azurerm_public_ip.test.ip_address + user = "adminuser" + password = "%[1]s" +} + +provisioner "file" { + content = templatefile("testdata/install_agent.sh.tftpl", { + subscription_id = "%[4]s" + resource_group_name = azurerm_resource_group.test.name + cluster_name = "acctest-akcc-%[2]d" + location = azurerm_resource_group.test.location + tenant_id = "%[5]s" + working_dir = "%[3]s" + }) + destination = "%[3]s/install_agent.sh" +} + +provisioner "file" { + source = "testdata/install_agent.py" + destination = "%[3]s/install_agent.py" +} + +provisioner "file" { + source = "testdata/kind.yaml" + destination = "%[3]s/kind.yaml" +} + +provisioner "file" { + content = < %[3]s/agent_log", + ] } -`, data.RandomInteger, data.Locations.Primary) +`, credential, data.RandomInteger, "/home/adminuser", os.Getenv("ARM_SUBSCRIPTION_ID"), os.Getenv("ARM_TENANT_ID"), privateKey) } diff --git a/internal/services/extendedlocation/testdata/install_agent.py b/internal/services/extendedlocation/testdata/install_agent.py new file mode 100644 index 000000000000..d39bccfab4f2 --- /dev/null +++ b/internal/services/extendedlocation/testdata/install_agent.py @@ -0,0 +1,248 @@ +import argparse +import json +import logging as logger +import os +import platform +import shutil +import stat +import subprocess +import time +import urllib +from subprocess import PIPE, Popen +from urllib import request + +HELM_VERSION = 'v3.6.3' +HELM_STORAGE_URL = "https://k8connecthelm.azureedge.net" +Pre_Onboarding_Helm_Charts_Folder_Name = 'PreOnboardingChecksCharts' + + +def get_helm_registry(config_dp_endpoint): + # Setting uri + get_chart_location_url = "{}/{}/GetLatestHelmPackagePath?api-version=2019-11-01-preview".format( + config_dp_endpoint, 'azure-arc-k8sagents') + + try: + response = urllib.request.urlopen( + request.Request(get_chart_location_url, method="POST")) + except Exception as e: + raise Exception("Failed to get helm registry." + str(e)) + + try: + return json.load(response).get('repositoryPath') + except Exception as e: + raise Exception( + "Error while fetching helm chart registry path from JSON response: " + str(e)) + + +def pull_helm_chart(registry_path, kube_config, kube_context, helm_client_location, chart_name='azure-arc-k8sagents', retry_count=5, retry_delay=3): + cmd_helm_chart_pull = [helm_client_location, + "chart", "pull", registry_path] + if kube_config: + cmd_helm_chart_pull.extend(["--kubeconfig", kube_config]) + if kube_context: + cmd_helm_chart_pull.extend(["--kube-context", kube_context]) + for i in range(retry_count): + response_helm_chart_pull = subprocess.Popen( + cmd_helm_chart_pull, stdout=PIPE, stderr=PIPE) + _, error_helm_chart_pull = response_helm_chart_pull.communicate() + if response_helm_chart_pull.returncode != 0: + if i == retry_count - 1: + raise Exception("Unable to pull {} helm chart from the registry '{}': ".format( + chart_name, registry_path) + error_helm_chart_pull.decode("ascii")) + time.sleep(retry_delay) + else: + break + + +def export_helm_chart(registry_path, chart_export_path, kube_config, kube_context, helm_client_location, chart_name='azure-arc-k8sagents'): + cmd_helm_chart_export = [helm_client_location, "chart", + "export", registry_path, "--destination", chart_export_path] + if kube_config: + cmd_helm_chart_export.extend(["--kubeconfig", kube_config]) + if kube_context: + cmd_helm_chart_export.extend(["--kube-context", kube_context]) + response_helm_chart_export = subprocess.Popen( + cmd_helm_chart_export, stdout=PIPE, stderr=PIPE) + _, error_helm_chart_export = response_helm_chart_export.communicate() + if response_helm_chart_export.returncode != 0: + raise Exception("Unable to export {} helm chart from the registry '{}': ".format( + chart_name, registry_path) + error_helm_chart_export.decode("ascii")) + + +def get_chart_path(registry_path, kube_config, kube_context, helm_client_location, chart_folder_name='AzureArcCharts', chart_name='azure-arc-k8sagents'): + # Pulling helm chart from registry + os.environ['HELM_EXPERIMENTAL_OCI'] = '1' + pull_helm_chart(registry_path, kube_config, kube_context, + helm_client_location, chart_name) + + # Exporting helm chart after cleanup + chart_export_path = os.path.join( + os.path.expanduser('~'), '.azure', chart_folder_name) + try: + if os.path.isdir(chart_export_path): + shutil.rmtree(chart_export_path) + except: + logger.warning("Unable to cleanup the {} already present on the machine. In case of failure, please cleanup the directory '{}' and try again.".format( + chart_folder_name, chart_export_path)) + + export_helm_chart(registry_path, chart_export_path, kube_config, + kube_context, helm_client_location, chart_name) + + # Returning helm chart path + helm_chart_path = os.path.join(chart_export_path, chart_name) + if chart_folder_name == Pre_Onboarding_Helm_Charts_Folder_Name: + chart_path = helm_chart_path + else: + chart_path = os.getenv('HELMCHART') if os.getenv( + 'HELMCHART') else helm_chart_path + + return chart_path + + +def install_helm_client(): + # Fetch system related info + operating_system = platform.system().lower() + platform.machine() + + # Set helm binary download & install locations + if (operating_system == 'windows'): + download_location_string = f'.azure\\helm\\{HELM_VERSION}\\helm-{HELM_VERSION}-{operating_system}-amd64.zip' + install_location_string = f'.azure\\helm\\{HELM_VERSION}\\{operating_system}-amd64\\helm.exe' + requestUri = f'{HELM_STORAGE_URL}/helm/helm-{HELM_VERSION}-{operating_system}-amd64.zip' + elif (operating_system == 'linux' or operating_system == 'darwin'): + download_location_string = f'.azure/helm/{HELM_VERSION}/helm-{HELM_VERSION}-{operating_system}-amd64.tar.gz' + install_location_string = f'.azure/helm/{HELM_VERSION}/{operating_system}-amd64/helm' + requestUri = f'{HELM_STORAGE_URL}/helm/helm-{HELM_VERSION}-{operating_system}-amd64.tar.gz' + else: + raise Exception( + f'The {operating_system} platform is not currently supported for installing helm client.') + + download_location = os.path.expanduser( + os.path.join('~', download_location_string)) + download_dir = os.path.dirname(download_location) + install_location = os.path.expanduser( + os.path.join('~', install_location_string)) + + # Download compressed halm binary if not already present + if not os.path.isfile(download_location): + # Creating the helm folder if it doesnt exist + if not os.path.exists(download_dir): + try: + os.makedirs(download_dir) + except Exception as e: + raise Exception("Failed to create helm directory." + str(e)) + + # Downloading compressed helm client executable + logger.warning( + "Downloading helm client for first time. This can take few minutes...") + try: + response = urllib.request.urlopen(requestUri) + except Exception as e: + raise Exception("Failed to download helm client." + str(e)) + + responseContent = response.read() + response.close() + + # Creating the compressed helm binaries + try: + with open(download_location, 'wb') as f: + f.write(responseContent) + except Exception as e: + raise Exception("Failed to create helm executable." + str(e)) + + # Extract compressed helm binary + if not os.path.isfile(install_location): + try: + shutil.unpack_archive(download_location, download_dir) + os.chmod(install_location, os.stat( + install_location).st_mode | stat.S_IXUSR) + except Exception as e: + raise Exception("Failed to extract helm executable." + str(e)) + + return install_location + + +def helm_install_release(chart_path, subscription_id, kubernetes_distro, kubernetes_infra, resource_group_name, cluster_name, + location, onboarding_tenant_id, private_key_pem, + no_wait, cloud_name, helm_client_location, onboarding_timeout="600"): + cmd_helm_install = [helm_client_location, "upgrade", "--install", "azure-arc", chart_path, + "--set", "global.subscriptionId={}".format( + subscription_id), + "--set", "global.kubernetesDistro={}".format( + kubernetes_distro), + "--set", "global.kubernetesInfra={}".format( + kubernetes_infra), + "--set", "global.resourceGroupName={}".format( + resource_group_name), + "--set", "global.resourceName={}".format(cluster_name), + "--set", "global.location={}".format(location), + "--set", "global.tenantId={}".format( + onboarding_tenant_id), + "--set", "global.onboardingPrivateKey={}".format( + private_key_pem), + "--set", "systemDefaultValues.spnOnboarding=false", + "--set", "global.azureEnvironment={}".format( + cloud_name), + "--set", "systemDefaultValues.clusterconnect-agent.enabled=true", + "--namespace", "{}".format("azure-arc-release"), + "--create-namespace", + "--output", "json"] + + if not no_wait: + # Change --timeout format for helm client to understand + onboarding_timeout = onboarding_timeout + "s" + cmd_helm_install.extend( + ["--wait", "--timeout", "{}".format(onboarding_timeout)]) + response_helm_install = Popen(cmd_helm_install, stdout=PIPE, stderr=PIPE) + _, error_helm_install = response_helm_install.communicate() + if response_helm_install.returncode != 0: + raise Exception("Unable to install helm release" + error_helm_install.decode("ascii")) + + +def install_agent(): + parser = argparse.ArgumentParser( + description='Install Connected Cluster Agent') + parser.add_argument('--subscriptionId', type=str, required=True) + parser.add_argument('--resourceGroupName', type=str, required=True) + parser.add_argument('--clusterName', type=str, required=True) + parser.add_argument('--location', type=str, required=True) + parser.add_argument('--tenantId', type=str, required=True) + parser.add_argument('--privatePem', type=str, required=True) + + try: + args = parser.parse_args() + except Exception as e: + raise Exception("Failed to parse arguments." + str(e)) + + try: + with open(args.privatePem, "r") as f: + privateKey = f.read() + except Exception as e: + raise Exception("Failed to get private key." + str(e)) + + # Install helm client + helm_client_location = install_helm_client() + + # Retrieving Helm chart OCI Artifact location + registry_path = get_helm_registry("https://westeurope.dp.kubernetesconfiguration.azure.com") + + # Get helm chart path + chart_path = get_chart_path( + registry_path, None, None, helm_client_location) + + helm_install_release(chart_path, + args.subscriptionId, + "generic", + "generic", + args.resourceGroupName, + args.clusterName, + args.location, + args.tenantId, + privateKey, + False, + "AZUREPUBLICCLOUD", + helm_client_location) + + +if __name__ == "__main__": + install_agent() diff --git a/internal/services/extendedlocation/testdata/install_agent.sh.tftpl b/internal/services/extendedlocation/testdata/install_agent.sh.tftpl new file mode 100644 index 000000000000..9bb2cbcbd0bf --- /dev/null +++ b/internal/services/extendedlocation/testdata/install_agent.sh.tftpl @@ -0,0 +1,38 @@ +#!/bin/bash + +# install docker +sudo apt-get update +sudo apt-get -y install ca-certificates curl gnupg lsb-release +sudo mkdir -m 0755 -p /etc/apt/keyrings +curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg +echo \ + "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ + $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null +sudo chmod a+r /etc/apt/keyrings/docker.gpg +sudo apt-get update +sudo apt-get -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin + +#Manage Docker as a non-root user +sudo groupadd docker || true +sudo usermod -aG docker $USER +newgrp docker << END + +#install golang and kind +sudo snap install go --classic +sudo go install sigs.k8s.io/kind@latest + +#create a new cluster +export PATH="$HOME/go/bin:$PATH" +export KUBECONFIG="${working_dir}/kind-config" +kind create cluster --name arc-kind --config kind.yaml --kubeconfig kind-config + +#install agent +python3 "${working_dir}/install_agent.py" \ +--subscriptionId "${subscription_id}" \ +--resourceGroupName "${resource_group_name}" \ +--clusterName "${cluster_name}" \ +--location "${location}" \ +--tenantId "${tenant_id}" \ +--privatePem "${working_dir}/private.pem" + +END \ No newline at end of file diff --git a/internal/services/extendedlocation/testdata/kind.yaml b/internal/services/extendedlocation/testdata/kind.yaml new file mode 100644 index 000000000000..9f5717060033 --- /dev/null +++ b/internal/services/extendedlocation/testdata/kind.yaml @@ -0,0 +1,20 @@ +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: +- role: control-plane + kubeadmConfigPatches: + - | + kind: InitConfiguration + nodeRegistration: + kubeletExtraArgs: + node-labels: "ingress-ready=true" + # port forward 80 on the host to 80 on this node + extraPortMappings: + - containerPort: 81 + hostPort: 81 + listenAddress: "127.0.0.1" + protocol: TCP + - containerPort: 443 + hostPort: 443 + listenAddress: "127.0.0.1" + protocol: TCP From 081944e0e03e17cc52e675c9ba75b03f209fbfed Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Mon, 26 Jun 2023 17:01:38 +0800 Subject: [PATCH 04/35] Fix test --- ...extended_location_custom_locations_test.go | 121 ++++++++---------- 1 file changed, 54 insertions(+), 67 deletions(-) diff --git a/internal/services/extendedlocation/extended_location_custom_locations_test.go b/internal/services/extendedlocation/extended_location_custom_locations_test.go index 5532b3cfa908..640a372253c6 100644 --- a/internal/services/extendedlocation/extended_location_custom_locations_test.go +++ b/internal/services/extendedlocation/extended_location_custom_locations_test.go @@ -16,7 +16,6 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" "math/rand" - "os" "testing" ) @@ -42,14 +41,14 @@ func TestAccExtendedLocationCustomLocations_basic(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_extended_custom_locations", "test") r := CustomLocationResource{} credential := fmt.Sprintf("P@$$w0rd%d!", rand.Intn(10000)) - privateKey, publicKey, err := CustomLocationResource{}.generateKey() + _, publicKey, err := CustomLocationResource{}.generateKey() if err != nil { t.Fatalf("failed to generate key: %+v", err) } data.ResourceTest(t, r, []acceptance.TestStep{ { - Config: r.basic(data, credential, privateKey, publicKey), + Config: r.basic(data, credential, publicKey), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), @@ -58,17 +57,11 @@ func TestAccExtendedLocationCustomLocations_basic(t *testing.T) { }) } -func (r CustomLocationResource) basic(data acceptance.TestData, credential string, privateKey string, publicKey string) string { - template := r.template(data, credential, privateKey, publicKey) +func (r CustomLocationResource) basic(data acceptance.TestData, credential string, publicKey string) string { + template := r.template(data, credential, publicKey) return fmt.Sprintf(` %s -//resource "azurerm_role_assignment" "admin" { -// scope = azurerm_kubernetes_cluster.test.id -// role_definition_name = "Azure Kubernetes Service RBAC Cluster Admin" -// principal_id = "51dfe1e8-70c6-4de5-a08e-e18aff23d815" -//} - resource "azurerm_extended_custom_locations" "test" { name = "acctestcustomlocation%d" resource_group_name = azurerm_resource_group.test.name @@ -83,7 +76,7 @@ resource "azurerm_extended_custom_locations" "test" { `, template, data.RandomInteger) } -func (r CustomLocationResource) template(data acceptance.TestData, credential string, privateKey string, publicKey string) string { +func (r CustomLocationResource) template(data acceptance.TestData, credential string, publicKey string) string { data.Locations.Primary = "eastus" return fmt.Sprintf(` provider "azurerm" { @@ -179,10 +172,6 @@ resource "azurerm_linux_virtual_machine" "test" { } } -data "azurerm_extended_locations" "test" { - location = azurerm_resource_group.test.location -} - resource "azurerm_arc_kubernetes_cluster" "test" { name = "acctest-akcc-%[1]d" resource_group_name = azurerm_resource_group.test.name @@ -192,8 +181,6 @@ resource "azurerm_arc_kubernetes_cluster" "test" { type = "SystemAssigned" } - %[5]s - depends_on = [ azurerm_linux_virtual_machine.test ] @@ -202,7 +189,7 @@ resource "azurerm_arc_kubernetes_cluster" "test" { resource "azurerm_arc_kubernetes_cluster_extension" "test" { name = "foo" cluster_id = azurerm_arc_kubernetes_cluster.test.id - extension_type = "microsoft.flux" + extension_type = "microsoft.azuredefender.kubernetes" identity { type = "SystemAssigned" @@ -212,7 +199,7 @@ resource "azurerm_arc_kubernetes_cluster_extension" "test" { azurerm_linux_virtual_machine.test ] } -`, data.RandomInteger, data.Locations.Primary, credential, publicKey, r.provisionTemplate(data, credential, privateKey)) +`, data.RandomInteger, data.Locations.Primary, credential, publicKey) } func (r CustomLocationResource) generateKey() (string, string, error) { @@ -235,50 +222,50 @@ func (r CustomLocationResource) generateKey() (string, string, error) { return string(privatePem), base64.StdEncoding.EncodeToString(x509.MarshalPKCS1PublicKey(&privateKey.PublicKey)), nil } -func (r CustomLocationResource) provisionTemplate(data acceptance.TestData, credential string, privateKey string) string { - return fmt.Sprintf(` -connection { - type = "ssh" - host = azurerm_public_ip.test.ip_address - user = "adminuser" - password = "%[1]s" -} - -provisioner "file" { - content = templatefile("testdata/install_agent.sh.tftpl", { - subscription_id = "%[4]s" - resource_group_name = azurerm_resource_group.test.name - cluster_name = "acctest-akcc-%[2]d" - location = azurerm_resource_group.test.location - tenant_id = "%[5]s" - working_dir = "%[3]s" - }) - destination = "%[3]s/install_agent.sh" -} - -provisioner "file" { - source = "testdata/install_agent.py" - destination = "%[3]s/install_agent.py" -} - -provisioner "file" { - source = "testdata/kind.yaml" - destination = "%[3]s/kind.yaml" -} - -provisioner "file" { - content = < %[3]s/agent_log", - ] -} -`, credential, data.RandomInteger, "/home/adminuser", os.Getenv("ARM_SUBSCRIPTION_ID"), os.Getenv("ARM_TENANT_ID"), privateKey) -} +//func (r CustomLocationResource) provisionTemplate(data acceptance.TestData, credential string, privateKey string) string { +// return fmt.Sprintf(` +//connection { +// type = "ssh" +// host = azurerm_public_ip.test.ip_address +// user = "adminuser" +// password = "%[1]s" +//} +// +//provisioner "file" { +// content = templatefile("testdata/install_agent.sh.tftpl", { +// subscription_id = "%[4]s" +// resource_group_name = azurerm_resource_group.test.name +// cluster_name = "acctest-akcc-%[2]d" +// location = azurerm_resource_group.test.location +// tenant_id = "%[5]s" +// working_dir = "%[3]s" +// }) +// destination = "%[3]s/install_agent.sh" +//} +// +//provisioner "file" { +// source = "testdata/install_agent.py" +// destination = "%[3]s/install_agent.py" +//} +// +//provisioner "file" { +// source = "testdata/kind.yaml" +// destination = "%[3]s/kind.yaml" +//} +// +//provisioner "file" { +// content = < %[3]s/agent_log", +// ] +//} +//`, credential, data.RandomInteger, "/home/adminuser", os.Getenv("ARM_SUBSCRIPTION_ID"), os.Getenv("ARM_TENANT_ID"), privateKey) +//} From e3c05c444782b76e674042763b1611c01a45ad98 Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Thu, 19 Oct 2023 10:35:40 +0800 Subject: [PATCH 05/35] Update acc test --- ...extended_location_custom_locations_test.go | 148 ++++++++++-------- 1 file changed, 87 insertions(+), 61 deletions(-) diff --git a/internal/services/extendedlocation/extended_location_custom_locations_test.go b/internal/services/extendedlocation/extended_location_custom_locations_test.go index 640a372253c6..3364c093966b 100644 --- a/internal/services/extendedlocation/extended_location_custom_locations_test.go +++ b/internal/services/extendedlocation/extended_location_custom_locations_test.go @@ -10,12 +10,14 @@ import ( "fmt" "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" "math/rand" + "os" "testing" ) @@ -40,15 +42,11 @@ func (r CustomLocationResource) Exists(ctx context.Context, client *clients.Clie func TestAccExtendedLocationCustomLocations_basic(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_extended_custom_locations", "test") r := CustomLocationResource{} - credential := fmt.Sprintf("P@$$w0rd%d!", rand.Intn(10000)) - _, publicKey, err := CustomLocationResource{}.generateKey() - if err != nil { - t.Fatalf("failed to generate key: %+v", err) - } + credential, privateKey, publicKey := r.getCredentials(t) data.ResourceTest(t, r, []acceptance.TestStep{ { - Config: r.basic(data, credential, publicKey), + Config: r.basic(data, credential, privateKey, publicKey), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), @@ -57,8 +55,8 @@ func TestAccExtendedLocationCustomLocations_basic(t *testing.T) { }) } -func (r CustomLocationResource) basic(data acceptance.TestData, credential string, publicKey string) string { - template := r.template(data, credential, publicKey) +func (r CustomLocationResource) basic(data acceptance.TestData, credential string, privateKey string, publicKey string) string { + template := r.template(data, credential, publicKey, privateKey) return fmt.Sprintf(` %s @@ -76,8 +74,9 @@ resource "azurerm_extended_custom_locations" "test" { `, template, data.RandomInteger) } -func (r CustomLocationResource) template(data acceptance.TestData, credential string, publicKey string) string { +func (r CustomLocationResource) template(data acceptance.TestData, credential string, publicKey string, privateKey string) string { data.Locations.Primary = "eastus" + provisionTemplate := r.provisionTemplate(data, credential, privateKey) return fmt.Sprintf(` provider "azurerm" { features { @@ -181,25 +180,37 @@ resource "azurerm_arc_kubernetes_cluster" "test" { type = "SystemAssigned" } + %[5]s + depends_on = [ azurerm_linux_virtual_machine.test ] } resource "azurerm_arc_kubernetes_cluster_extension" "test" { - name = "foo" + name = "acctest-kce-%[1]d" cluster_id = azurerm_arc_kubernetes_cluster.test.id - extension_type = "microsoft.azuredefender.kubernetes" + extension_type = "microsoft.flux" + version = "1.6.3" + release_namespace = "flux-system" + + configuration_protected_settings = { + "omsagent.secret.key" = "secretKeyValue2" + } + + configuration_settings = { + "omsagent.env.clusterName" = "clusterName2" + } identity { - type = "SystemAssigned" + type = "SystemAssigned" } depends_on = [ - azurerm_linux_virtual_machine.test + azurerm_linux_virtual_machine.test ] } -`, data.RandomInteger, data.Locations.Primary, credential, publicKey) +`, data.RandomInteger, data.Locations.Primary, credential, publicKey, provisionTemplate) } func (r CustomLocationResource) generateKey() (string, string, error) { @@ -222,50 +233,65 @@ func (r CustomLocationResource) generateKey() (string, string, error) { return string(privatePem), base64.StdEncoding.EncodeToString(x509.MarshalPKCS1PublicKey(&privateKey.PublicKey)), nil } -//func (r CustomLocationResource) provisionTemplate(data acceptance.TestData, credential string, privateKey string) string { -// return fmt.Sprintf(` -//connection { -// type = "ssh" -// host = azurerm_public_ip.test.ip_address -// user = "adminuser" -// password = "%[1]s" -//} -// -//provisioner "file" { -// content = templatefile("testdata/install_agent.sh.tftpl", { -// subscription_id = "%[4]s" -// resource_group_name = azurerm_resource_group.test.name -// cluster_name = "acctest-akcc-%[2]d" -// location = azurerm_resource_group.test.location -// tenant_id = "%[5]s" -// working_dir = "%[3]s" -// }) -// destination = "%[3]s/install_agent.sh" -//} -// -//provisioner "file" { -// source = "testdata/install_agent.py" -// destination = "%[3]s/install_agent.py" -//} -// -//provisioner "file" { -// source = "testdata/kind.yaml" -// destination = "%[3]s/kind.yaml" -//} -// -//provisioner "file" { -// content = < %[3]s/agent_log", -// ] -//} -//`, credential, data.RandomInteger, "/home/adminuser", os.Getenv("ARM_SUBSCRIPTION_ID"), os.Getenv("ARM_TENANT_ID"), privateKey) -//} +func (r CustomLocationResource) getCredentials(t *testing.T) (credential, privateKey, publicKey string) { + // generateKey() is a time-consuming operation, we only run this test if an env var is set. + if os.Getenv(resource.EnvTfAcc) == "" { + t.Skipf("Acceptance tests skipped unless env '%s' set", resource.EnvTfAcc) + } + + credential = fmt.Sprintf("P@$$w0rd%d!", rand.Intn(10000)) + privateKey, publicKey, err := r.generateKey() + if err != nil { + t.Fatalf("failed to generate key: %+v", err) + } + + return +} + +func (r CustomLocationResource) provisionTemplate(data acceptance.TestData, credential string, privateKey string) string { + return fmt.Sprintf(` +connection { + type = "ssh" + host = azurerm_public_ip.test.ip_address + user = "adminuser" + password = "%[1]s" +} + +provisioner "file" { + content = templatefile("testdata/install_agent.sh.tftpl", { + subscription_id = "%[4]s" + resource_group_name = azurerm_resource_group.test.name + cluster_name = "acctest-akcc-%[2]d" + location = azurerm_resource_group.test.location + tenant_id = "%[5]s" + working_dir = "%[3]s" + }) + destination = "%[3]s/install_agent.sh" +} + +provisioner "file" { + source = "testdata/install_agent.py" + destination = "%[3]s/install_agent.py" +} + +provisioner "file" { + source = "testdata/kind.yaml" + destination = "%[3]s/kind.yaml" +} + +provisioner "file" { + content = < %[3]s/agent_log", + ] +} +`, credential, data.RandomInteger, "/home/adminuser", os.Getenv("ARM_SUBSCRIPTION_ID"), os.Getenv("ARM_TENANT_ID"), privateKey) +} From a8f79d9ab06e8daef88a34ef84211fbe98e0085c Mon Sep 17 00:00:00 2001 From: jiawei Date: Fri, 20 Oct 2023 07:47:06 +0000 Subject: [PATCH 06/35] Update extension type --- .../extended_location_custom_locations_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/services/extendedlocation/extended_location_custom_locations_test.go b/internal/services/extendedlocation/extended_location_custom_locations_test.go index 3364c093966b..9c02bd1b5508 100644 --- a/internal/services/extendedlocation/extended_location_custom_locations_test.go +++ b/internal/services/extendedlocation/extended_location_custom_locations_test.go @@ -190,9 +190,7 @@ resource "azurerm_arc_kubernetes_cluster" "test" { resource "azurerm_arc_kubernetes_cluster_extension" "test" { name = "acctest-kce-%[1]d" cluster_id = azurerm_arc_kubernetes_cluster.test.id - extension_type = "microsoft.flux" - version = "1.6.3" - release_namespace = "flux-system" + extension_type = "Microsoft.Web.Appservice" configuration_protected_settings = { "omsagent.secret.key" = "secretKeyValue2" From 9df4dc257a5df2f741e95899d06f705b9c5d68e3 Mon Sep 17 00:00:00 2001 From: jiawei Date: Fri, 15 Dec 2023 03:57:32 +0000 Subject: [PATCH 07/35] update test ext --- .../extended_location_custom_locations_test.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/internal/services/extendedlocation/extended_location_custom_locations_test.go b/internal/services/extendedlocation/extended_location_custom_locations_test.go index 9c02bd1b5508..08475ec4dfd8 100644 --- a/internal/services/extendedlocation/extended_location_custom_locations_test.go +++ b/internal/services/extendedlocation/extended_location_custom_locations_test.go @@ -190,14 +190,12 @@ resource "azurerm_arc_kubernetes_cluster" "test" { resource "azurerm_arc_kubernetes_cluster_extension" "test" { name = "acctest-kce-%[1]d" cluster_id = azurerm_arc_kubernetes_cluster.test.id - extension_type = "Microsoft.Web.Appservice" - - configuration_protected_settings = { - "omsagent.secret.key" = "secretKeyValue2" - } + extension_type = "microsoft.contoso.clusters" + target_namespace = "tf-ns4" + version = "1.2.0" configuration_settings = { - "omsagent.env.clusterName" = "clusterName2" + "Microsoft.CustomLocation.ServiceAccount" = "tf-operator" } identity { From 8d705c3ac9f0e76684e88f2f7d4b6b832feb8aa8 Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Mon, 18 Dec 2023 16:58:38 +0800 Subject: [PATCH 08/35] New Resource: azurerm_extended_location_custom_location --- .github/labeler-issue-triage.yml | 3 + .github/labeler-pull-request-triage.yml | 3 + .teamcity/components/generated/services.kt | 1 + internal/clients/client.go | 4 +- .../extendedlocation/client/client.go | 15 ++- ...o => extended_location_custom_location.go} | 112 +++++++++++------- ...extended_location_custom_location_test.go} | 96 +++++++++++---- .../services/extendedlocation/registration.go | 4 + .../testdata/install_agent.py | 6 +- ...ded_location_custom_location.html.markdown | 105 ++++++++++++++++ 10 files changed, 278 insertions(+), 71 deletions(-) rename internal/services/extendedlocation/{extended_location_custom_locations.go => extended_location_custom_location.go} (77%) rename internal/services/extendedlocation/{extended_location_custom_locations_test.go => extended_location_custom_location_test.go} (79%) create mode 100644 website/docs/r/extended_location_custom_location.html.markdown diff --git a/.github/labeler-issue-triage.yml b/.github/labeler-issue-triage.yml index 49706a2acac5..eb94d9644ad4 100644 --- a/.github/labeler-issue-triage.yml +++ b/.github/labeler-issue-triage.yml @@ -141,6 +141,9 @@ service/event-grid: service/event-hubs: - '### (|New or )Affected Resource\(s\)\/Data Source\(s\)((.|\n)*)azurerm_eventhub((.|\n)*)###' +service/extended-locations: + - '### (|New or )Affected Resource\(s\)\/Data Source\(s\)((.|\n)*)azurerm_extended_location_((.|\n)*)###' + service/firewall: - '### (|New or )Affected Resource\(s\)\/Data Source\(s\)((.|\n)*)azurerm_firewall((.|\n)*)###' diff --git a/.github/labeler-pull-request-triage.yml b/.github/labeler-pull-request-triage.yml index 1f21c88b7000..4fb69b3952be 100644 --- a/.github/labeler-pull-request-triage.yml +++ b/.github/labeler-pull-request-triage.yml @@ -239,6 +239,9 @@ service/event-hubs: - any-glob-to-any-file: - internal/services/eventhub/**/* +service/extended-location: + - internal/services/extendedlocation/**/* + service/firewall: - changed-files: - any-glob-to-any-file: diff --git a/.teamcity/components/generated/services.kt b/.teamcity/components/generated/services.kt index 78c055e88b34..7ccb89121910 100644 --- a/.teamcity/components/generated/services.kt +++ b/.teamcity/components/generated/services.kt @@ -53,6 +53,7 @@ var services = mapOf( "elasticsan" to "ElasticSan", "eventgrid" to "EventGrid", "eventhub" to "EventHub", + "extendedlocation" to "ExtendedLocation", "firewall" to "Firewall", "fluidrelay" to "Fluid Relay", "frontdoor" to "FrontDoor", diff --git a/internal/clients/client.go b/internal/clients/client.go index b70a4957032c..598a87227ab1 100644 --- a/internal/clients/client.go +++ b/internal/clients/client.go @@ -449,7 +449,9 @@ func (client *Client) Build(ctx context.Context, o *common.ClientOptions) error if client.Eventhub, err = eventhub.NewClient(o); err != nil { return fmt.Errorf("building clients for Eventhub: %+v", err) } - client.ExtendedLocation = extendedlocation.NewClient(o) + if client.ExtendedLocation, err = extendedlocation.NewClient(o); err != nil { + return fmt.Errorf("building clients for ExtendedLocation: %+v", err) + } if client.FluidRelay, err = fluidrelay.NewClient(o); err != nil { return fmt.Errorf("building clients for FluidRelay: %+v", err) } diff --git a/internal/services/extendedlocation/client/client.go b/internal/services/extendedlocation/client/client.go index d84259825c70..e55ac242b790 100644 --- a/internal/services/extendedlocation/client/client.go +++ b/internal/services/extendedlocation/client/client.go @@ -1,6 +1,8 @@ package client import ( + "fmt" + "github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations" "github.com/hashicorp/terraform-provider-azurerm/internal/common" ) @@ -9,11 +11,14 @@ type Client struct { CustomLocationsClient *customlocations.CustomLocationsClient } -func NewClient(o *common.ClientOptions) *Client { - customLocationsClient := customlocations.NewCustomLocationsClientWithBaseURI(o.ResourceManagerEndpoint) - o.ConfigureClient(&customLocationsClient.Client, o.ResourceManagerAuthorizer) +func NewClient(o *common.ClientOptions) (*Client, error) { + customLocationsClient, err := customlocations.NewCustomLocationsClientWithBaseURI(o.Environment.ResourceManager) + if err != nil { + return nil, fmt.Errorf("building CustomLocations client: %+v", err) + } + o.Configure(customLocationsClient.Client, o.Authorizers.ResourceManager) return &Client{ - CustomLocationsClient: &customLocationsClient, - } + CustomLocationsClient: customLocationsClient, + }, nil } diff --git a/internal/services/extendedlocation/extended_location_custom_locations.go b/internal/services/extendedlocation/extended_location_custom_location.go similarity index 77% rename from internal/services/extendedlocation/extended_location_custom_locations.go rename to internal/services/extendedlocation/extended_location_custom_location.go index fff63c03add0..6c0ab5e4db95 100644 --- a/internal/services/extendedlocation/extended_location_custom_locations.go +++ b/internal/services/extendedlocation/extended_location_custom_location.go @@ -3,33 +3,38 @@ package extendedlocation import ( "context" "fmt" + "time" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/utils" - "time" ) type CustomLocationResource struct{} type CustomLocationResourceModel struct { - Name string `tfschema:"name"` - ResourceGroupName string `tfschema:"resource_group_name"` - Location string `tfschema:"location"` - AuthenticationType string `tfschema:"authentication_type"` - AuthenticationValue string `tfschema:"authentication_value"` - ClusterExtensionIds []string `tfschema:"cluster_extension_ids"` - DisplayName string `tfschema:"display_name"` - HostResourceId string `tfschema:"host_resource_id"` - HostType string `tfschema:"host_type"` - Namespace string `tfschema:"namespace"` + Name string `tfschema:"name"` + ResourceGroupName string `tfschema:"resource_group_name"` + Location string `tfschema:"location"` + Authentication []AuthModel `tfschema:"authentication"` + ClusterExtensionIds []string `tfschema:"cluster_extension_ids"` + DisplayName string `tfschema:"display_name"` + HostResourceId string `tfschema:"host_resource_id"` + HostType string `tfschema:"host_type"` + Namespace string `tfschema:"namespace"` +} + +type AuthModel struct { + Type string `tfschema:"type"` + Value string `tfschema:"value"` } -func (r CustomLocationResource) Arguments() map[string]*schema.Schema { - return map[string]*schema.Schema{ +func (r CustomLocationResource) Arguments() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{ "name": { Type: pluginsdk.TypeString, Required: true, @@ -51,6 +56,13 @@ func (r CustomLocationResource) Arguments() map[string]*schema.Schema { ValidateFunc: validation.StringIsNotEmpty, }, + "namespace": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + "cluster_extension_ids": { Type: pluginsdk.TypeList, Required: true, @@ -65,16 +77,24 @@ func (r CustomLocationResource) Arguments() map[string]*schema.Schema { ValidateFunc: validation.StringIsNotEmpty, }, - "authentication_type": { - Type: pluginsdk.TypeString, - Optional: true, - ValidateFunc: validation.StringIsNotEmpty, - }, - - "authentication_value": { - Type: pluginsdk.TypeString, - Optional: true, - ValidateFunc: validation.StringIsNotEmpty, + "authentication": { + Type: pluginsdk.TypeList, + Optional: true, + Elem: &pluginsdk.Resource{ + Schema: map[string]*pluginsdk.Schema{ + "type": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "value": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + }, + }, }, "display_name": { @@ -90,17 +110,11 @@ func (r CustomLocationResource) Arguments() map[string]*schema.Schema { string(customlocations.HostTypeKubernetes), }, false), }, - - "namespace": { - Type: pluginsdk.TypeString, - Optional: true, - ValidateFunc: validation.StringIsNotEmpty, - }, } } -func (r CustomLocationResource) Attributes() map[string]*schema.Schema { - return map[string]*schema.Schema{} +func (r CustomLocationResource) Attributes() map[string]*pluginsdk.Schema { + return map[string]*pluginsdk.Schema{} } func (r CustomLocationResource) ModelObject() interface{} { @@ -108,7 +122,7 @@ func (r CustomLocationResource) ModelObject() interface{} { } func (r CustomLocationResource) ResourceType() string { - return "azurerm_extended_custom_locations" + return "azurerm_extended_custom_location" } func (r CustomLocationResource) Create() sdk.ResourceFunc { @@ -135,10 +149,11 @@ func (r CustomLocationResource) Create() sdk.ResourceFunc { customLocationProps := customlocations.CustomLocationProperties{} - if model.AuthenticationValue != "" && model.AuthenticationType != "" { + if model.Authentication != nil { + auth := model.Authentication[0] customLocationProps.Authentication = &customlocations.CustomLocationPropertiesAuthentication{ - Type: &model.AuthenticationType, - Value: &model.AuthenticationValue, + Type: &auth.Type, + Value: &auth.Value, } } @@ -202,14 +217,20 @@ func (r CustomLocationResource) Read() sdk.ResourceFunc { props := model.Properties state := CustomLocationResourceModel{ - Name: id.ResourceName, + Name: id.CustomLocationName, ResourceGroupName: id.ResourceGroupName, Location: model.Location, } - if props.Authentication != nil && props.Authentication.Type != nil && props.Authentication.Value != nil { - state.AuthenticationType = *props.Authentication.Type - state.AuthenticationValue = *props.Authentication.Value + if props != nil && props.Authentication != nil { + authType := pointer.From(props.Authentication.Type) + authValue := pointer.From(props.Authentication.Value) + state.Authentication = []AuthModel{ + { + Type: authType, + Value: authValue, + }, + } } if props.ClusterExtensionIds != nil { @@ -280,10 +301,13 @@ func (r CustomLocationResource) Update() sdk.ResourceFunc { customLocationProps := customlocations.CustomLocationProperties{} d := metadata.ResourceData - if d.HasChanges("authentication_type", "authentication_value") { - customLocationProps.Authentication = &customlocations.CustomLocationPropertiesAuthentication{ - Type: &state.AuthenticationType, - Value: &state.AuthenticationValue, + if d.HasChanges("authentication") { + if state.Authentication != nil { + auth := state.Authentication[0] + customLocationProps.Authentication = &customlocations.CustomLocationPropertiesAuthentication{ + Type: &auth.Type, + Value: &auth.Value, + } } } diff --git a/internal/services/extendedlocation/extended_location_custom_locations_test.go b/internal/services/extendedlocation/extended_location_custom_location_test.go similarity index 79% rename from internal/services/extendedlocation/extended_location_custom_locations_test.go rename to internal/services/extendedlocation/extended_location_custom_location_test.go index 08475ec4dfd8..ea356f6c8957 100644 --- a/internal/services/extendedlocation/extended_location_custom_locations_test.go +++ b/internal/services/extendedlocation/extended_location_custom_location_test.go @@ -8,6 +8,10 @@ import ( "encoding/base64" "encoding/pem" "fmt" + "math/rand" + "os" + "testing" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations" "github.com/hashicorp/terraform-plugin-testing/helper/resource" @@ -16,9 +20,6 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" - "math/rand" - "os" - "testing" ) type CustomLocationResource struct{} @@ -40,7 +41,7 @@ func (r CustomLocationResource) Exists(ctx context.Context, client *clients.Clie } func TestAccExtendedLocationCustomLocations_basic(t *testing.T) { - data := acceptance.BuildTestData(t, "azurerm_extended_custom_locations", "test") + data := acceptance.BuildTestData(t, "azurerm_extended_custom_location", "test") r := CustomLocationResource{} credential, privateKey, publicKey := r.getCredentials(t) @@ -55,20 +56,63 @@ func TestAccExtendedLocationCustomLocations_basic(t *testing.T) { }) } +func TestAccExtendedLocationCustomLocations_update(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_extended_custom_location", "test") + r := CustomLocationResource{} + credential, privateKey, publicKey := r.getCredentials(t) + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data, credential, privateKey, publicKey), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.update(data, credential, privateKey, publicKey), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + func (r CustomLocationResource) basic(data acceptance.TestData, credential string, privateKey string, publicKey string) string { template := r.template(data, credential, publicKey, privateKey) return fmt.Sprintf(` %s -resource "azurerm_extended_custom_locations" "test" { - name = "acctestcustomlocation%d" +resource "azurerm_extended_custom_location" "test" { + name = "acctestcustomlocation%d" resource_group_name = azurerm_resource_group.test.name - location = azurerm_resource_group.test.location + location = azurerm_resource_group.test.location cluster_extension_ids = [ - "${azurerm_arc_kubernetes_cluster_extension.test.id}" + "${azurerm_arc_kubernetes_cluster_extension.test.id}" ] - display_name = "customlocation%[2]d" - namespace = "namespace%[2]d" + display_name = "customlocation%[2]d" + namespace = "namespace%[2]d" + host_resource_id = azurerm_arc_kubernetes_cluster.test.id +} +`, template, data.RandomInteger) +} + +func (r CustomLocationResource) update(data acceptance.TestData, credential string, privateKey string, publicKey string) string { + template := r.template(data, credential, publicKey, privateKey) + return fmt.Sprintf(` +%s + +resource "azurerm_extended_custom_location" "test" { + name = "acctestcustomlocation%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + cluster_extension_ids = [ + "${azurerm_arc_kubernetes_cluster_extension.test.id}", + ] + + display_name = "customlocationupdate%[2]d" + namespace = "namespace%[2]d" host_resource_id = azurerm_arc_kubernetes_cluster.test.id } `, template, data.RandomInteger) @@ -80,14 +124,14 @@ func (r CustomLocationResource) template(data acceptance.TestData, credential st return fmt.Sprintf(` provider "azurerm" { features { - resource_group { - prevent_deletion_if_contains_resources = false - } + resource_group { + prevent_deletion_if_contains_resources = false + } } } resource "azurerm_resource_group" "test" { - name = "acctestRG-%[1]d" + name = "acctestRG-%[1]d" location = "%[2]s" } @@ -139,6 +183,12 @@ resource "azurerm_network_security_group" "my_terraform_nsg" { source_address_prefix = "*" destination_address_prefix = "*" } + + lifecycle { + ignore_changes = [ + security_rule, + ] + } } resource "azurerm_network_interface_security_group_association" "example" { @@ -169,6 +219,13 @@ resource "azurerm_linux_virtual_machine" "test" { sku = "18.04-LTS" version = "latest" } + + lifecycle { + ignore_changes = [ + identity, + tags, + ] + } } resource "azurerm_arc_kubernetes_cluster" "test" { @@ -188,14 +245,13 @@ resource "azurerm_arc_kubernetes_cluster" "test" { } resource "azurerm_arc_kubernetes_cluster_extension" "test" { - name = "acctest-kce-%[1]d" - cluster_id = azurerm_arc_kubernetes_cluster.test.id - extension_type = "microsoft.contoso.clusters" - target_namespace = "tf-ns4" - version = "1.2.0" + name = "extension4" + cluster_id = azurerm_arc_kubernetes_cluster.test.id + extension_type = "microsoft.vmware" + release_namespace = "vmware-extension" configuration_settings = { - "Microsoft.CustomLocation.ServiceAccount" = "tf-operator" + "Microsoft.CustomLocation.ServiceAccount" = "vmware-operator" } identity { diff --git a/internal/services/extendedlocation/registration.go b/internal/services/extendedlocation/registration.go index 237e286ca983..796878b30058 100644 --- a/internal/services/extendedlocation/registration.go +++ b/internal/services/extendedlocation/registration.go @@ -6,6 +6,10 @@ type Registration struct{} var _ sdk.TypedServiceRegistration = Registration{} +func (r Registration) AssociatedGitHubLabel() string { + return "service/extended-location" +} + func (r Registration) WebsiteCategories() []string { return []string{} } diff --git a/internal/services/extendedlocation/testdata/install_agent.py b/internal/services/extendedlocation/testdata/install_agent.py index d39bccfab4f2..2513e9aa7cbb 100644 --- a/internal/services/extendedlocation/testdata/install_agent.py +++ b/internal/services/extendedlocation/testdata/install_agent.py @@ -184,6 +184,10 @@ def helm_install_release(chart_path, subscription_id, kubernetes_distro, kuberne "--set", "global.azureEnvironment={}".format( cloud_name), "--set", "systemDefaultValues.clusterconnect-agent.enabled=true", + "--set", "systemDefaultValues.customLocations.enabled=true", + # 51dfe1e8-70c6-4de5-a08e-e18aff23d815 is from: az ad sp show --id bc313c14-388c-4e7d-a58e-70017303ee3b --query id -o tsv + # refs: https://learn.microsoft.com/en-us/azure/azure-arc/kubernetes/custom-locations#enable-custom-locations-on-your-cluster + "--set", "systemDefaultValues.customLocations.oid={}".format("51dfe1e8-70c6-4de5-a08e-e18aff23d815"), "--namespace", "{}".format("azure-arc-release"), "--create-namespace", "--output", "json"] @@ -225,7 +229,7 @@ def install_agent(): # Retrieving Helm chart OCI Artifact location registry_path = get_helm_registry("https://westeurope.dp.kubernetesconfiguration.azure.com") - + # Get helm chart path chart_path = get_chart_path( registry_path, None, None, helm_client_location) diff --git a/website/docs/r/extended_location_custom_location.html.markdown b/website/docs/r/extended_location_custom_location.html.markdown new file mode 100644 index 000000000000..b80df9484a67 --- /dev/null +++ b/website/docs/r/extended_location_custom_location.html.markdown @@ -0,0 +1,105 @@ +--- +subcategory: "Extended Location" +layout: "azurerm" +page_title: "Azure Resource Manager: azurerm_extended_location_custom_location" +description: |- + Manages a Custom Location within an Extended Location. +--- + +# azurerm_extended_location_custom_location + +Manages a Custom Location within an Extended Location. + +## Example Usage + +```hcl +resource "azurerm_resource_group" "example" { + name = "example-resources" + location = "West Europe" +} + +resource "azurerm_arc_kubernetes_cluster" "example" { + name = "example-akcc" + resource_group_name = azurerm_resource_group.example.name + location = "West Europe" + agent_public_key_certificate = filebase64("testdata/public.cer") + + identity { + type = "SystemAssigned" + } + + tags = { + ENV = "Test" + } +} + +resource "azurerm_arc_kubernetes_cluster_extension" "example" { + name = "example-ext" + cluster_id = azurerm_arc_kubernetes_cluster.example.id + extension_type = "microsoft.flux" +} + +resource "azurerm_extended_location_custom_location" "example" { + name = "example-custom-location" + resource_group_name = azurerm_resource_group.example.name + location = "West Europe" + cluster_extension_ids = [ + "${azurerm_arc_kubernetes_cluster_extension.test.id}" + ] + display_name = "example-custom-location" + namespace = "example-namespace" + host_resource_id = azurerm_arc_kubernetes_cluster.example.id +} +``` + +## Arguments Reference + +The following arguments are supported: + +* `name` - (Required) Specifies the name which should be used for this Custom Location. Changing this forces a new Custom Location to be created. + +* `resource_group_name` - (Required) Specifies the name of the Resource Group where the Custom Location should exist. Changing this forces a new Custom Location to be created. + +* `location` - (Required) Specifies the Azure location where the Custom Location should exist. Changing this forces a new Custom Location to be created. + +* `namespace` - (Required) Specifies the namespace of the Custom Location.Changing this forces a new Custom Location to be created. + +* `cluster_extension_ids` - (Required) Specifies the list of Cluster Extension IDs. + +* `host_resource_id` - (Required) Specifies the host resource ID. + +* `authentication` - (Optional) An `authentication` block as defined below. + +* `display_name` - (Optional) Specifies the display name of the Custom Location. + +* `host_type` - (Optional) Specifies the host type of the Custom Location. The only possible values is `KubernetesCluster`. + +--- + +An `authentication` block supports the following: + +* `type` - (Required) Specifies the type of authentication. + +* `value` - (Required) Specifies the value of authentication. + +## Attributes Reference + +* `id` - The ID of the Custom Location. + +## Timeouts + +The `timeouts` block allows you to specify [timeouts](https://www.terraform.io/language/resources/syntax#operation-timeouts) for certain actions: + +* `create` - (Defaults to 30 minutes) Used when creating the Custom Location. +* `read` - (Defaults to 5 minutes) Used when retrieving the Custom Location. +* `update` - (Defaults to 30 minutes) Used when updating the Custom Location. +* `delete` - (Defaults to 30 minutes) Used when deleting the Custom Location. + +## Import + +Custom Locations can be imported using the resource id, e.g. + +```shell +terraform import azurerm_extended_location_custom_location.example /subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/example-resources/providers/Microsoft.ExtendedLocation/customLocations/example-custom-location +``` + From d62767da81e476701fbcb4682ed999118b5d9c43 Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Tue, 19 Dec 2023 14:12:25 +0800 Subject: [PATCH 09/35] update allowed cats --- .github/labeler-issue-triage.yml | 4 ++-- internal/services/extendedlocation/client/client.go | 3 +++ .../extendedlocation/extended_location_custom_location.go | 3 +++ .../extended_location_custom_location_test.go | 3 +++ internal/services/extendedlocation/registration.go | 7 ++++++- website/allowed-subcategories | 1 + 6 files changed, 18 insertions(+), 3 deletions(-) diff --git a/.github/labeler-issue-triage.yml b/.github/labeler-issue-triage.yml index eb94d9644ad4..305c541db4b8 100644 --- a/.github/labeler-issue-triage.yml +++ b/.github/labeler-issue-triage.yml @@ -141,8 +141,8 @@ service/event-grid: service/event-hubs: - '### (|New or )Affected Resource\(s\)\/Data Source\(s\)((.|\n)*)azurerm_eventhub((.|\n)*)###' -service/extended-locations: - - '### (|New or )Affected Resource\(s\)\/Data Source\(s\)((.|\n)*)azurerm_extended_location_((.|\n)*)###' +service/extended-location: + - '### (|New or )Affected Resource\(s\)\/Data Source\(s\)((.|\n)*)azurerm_extended_custom_location((.|\n)*)###' service/firewall: - '### (|New or )Affected Resource\(s\)\/Data Source\(s\)((.|\n)*)azurerm_firewall((.|\n)*)###' diff --git a/internal/services/extendedlocation/client/client.go b/internal/services/extendedlocation/client/client.go index e55ac242b790..a6ecdda41e33 100644 --- a/internal/services/extendedlocation/client/client.go +++ b/internal/services/extendedlocation/client/client.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package client import ( diff --git a/internal/services/extendedlocation/extended_location_custom_location.go b/internal/services/extendedlocation/extended_location_custom_location.go index 6c0ab5e4db95..83d53c535484 100644 --- a/internal/services/extendedlocation/extended_location_custom_location.go +++ b/internal/services/extendedlocation/extended_location_custom_location.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package extendedlocation import ( diff --git a/internal/services/extendedlocation/extended_location_custom_location_test.go b/internal/services/extendedlocation/extended_location_custom_location_test.go index ea356f6c8957..a4ae20e543e4 100644 --- a/internal/services/extendedlocation/extended_location_custom_location_test.go +++ b/internal/services/extendedlocation/extended_location_custom_location_test.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package extendedlocation_test import ( diff --git a/internal/services/extendedlocation/registration.go b/internal/services/extendedlocation/registration.go index 796878b30058..a0e8b63dab4b 100644 --- a/internal/services/extendedlocation/registration.go +++ b/internal/services/extendedlocation/registration.go @@ -1,3 +1,6 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 + package extendedlocation import "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" @@ -11,7 +14,9 @@ func (r Registration) AssociatedGitHubLabel() string { } func (r Registration) WebsiteCategories() []string { - return []string{} + return []string{ + "Extended Location", + } } func (r Registration) DataSources() []sdk.DataSource { diff --git a/website/allowed-subcategories b/website/allowed-subcategories index 481255cd9868..bc4c66a96283 100644 --- a/website/allowed-subcategories +++ b/website/allowed-subcategories @@ -51,6 +51,7 @@ Digital Twins Disks Elastic Elastic SAN +Extended Location Fluid Relay Graph Services HDInsight From bfafe2f9cd6784664e0bb9f25704e8615474abd3 Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Mon, 8 Jan 2024 15:27:47 +0800 Subject: [PATCH 10/35] fix gencheck issue --- .github/labeler-pull-request-triage.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/labeler-pull-request-triage.yml b/.github/labeler-pull-request-triage.yml index 4fb69b3952be..6f18bc1c2f61 100644 --- a/.github/labeler-pull-request-triage.yml +++ b/.github/labeler-pull-request-triage.yml @@ -240,7 +240,9 @@ service/event-hubs: - internal/services/eventhub/**/* service/extended-location: - - internal/services/extendedlocation/**/* +- changed-files: + - any-glob-to-any-file: + - internal/services/extendedlocation/**/* service/firewall: - changed-files: From 3ae8222f6bb1ab479a944a8215b6afed930e3b14 Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Tue, 9 Jan 2024 10:22:03 +0800 Subject: [PATCH 11/35] Update to use commonschema --- .../extendedlocation/extended_location_custom_location.go | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/internal/services/extendedlocation/extended_location_custom_location.go b/internal/services/extendedlocation/extended_location_custom_location.go index 83d53c535484..9c5df69721fb 100644 --- a/internal/services/extendedlocation/extended_location_custom_location.go +++ b/internal/services/extendedlocation/extended_location_custom_location.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema" "github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations" "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" @@ -45,12 +46,7 @@ func (r CustomLocationResource) Arguments() map[string]*pluginsdk.Schema { ValidateFunc: validation.StringIsNotEmpty, }, - "resource_group_name": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringIsNotEmpty, - }, + "resource_group_name": commonschema.ResourceGroupName(), "location": { Type: pluginsdk.TypeString, From 1a47f5d113c5b5a95cb82d5f0b4ba6271dcca9f2 Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Wed, 10 Jan 2024 14:34:32 +0800 Subject: [PATCH 12/35] address some comments --- .../extended_location_custom_location.go | 86 +++++++------------ .../extended_location_custom_location_test.go | 27 +++--- 2 files changed, 45 insertions(+), 68 deletions(-) diff --git a/internal/services/extendedlocation/extended_location_custom_location.go b/internal/services/extendedlocation/extended_location_custom_location.go index 9c5df69721fb..aadf2e90719f 100644 --- a/internal/services/extendedlocation/extended_location_custom_location.go +++ b/internal/services/extendedlocation/extended_location_custom_location.go @@ -15,7 +15,6 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" - "github.com/hashicorp/terraform-provider-azurerm/utils" ) type CustomLocationResource struct{} @@ -48,12 +47,7 @@ func (r CustomLocationResource) Arguments() map[string]*pluginsdk.Schema { "resource_group_name": commonschema.ResourceGroupName(), - "location": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringIsNotEmpty, - }, + "location": commonschema.Location(), "namespace": { Type: pluginsdk.TypeString, @@ -79,6 +73,7 @@ func (r CustomLocationResource) Arguments() map[string]*pluginsdk.Schema { "authentication": { Type: pluginsdk.TypeList, Optional: true, + MaxItems: 1, Elem: &pluginsdk.Resource{ Schema: map[string]*pluginsdk.Schema{ "type": { @@ -148,40 +143,40 @@ func (r CustomLocationResource) Create() sdk.ResourceFunc { customLocationProps := customlocations.CustomLocationProperties{} - if model.Authentication != nil { + if model.Authentication != nil && len(model.Authentication) > 0 { auth := model.Authentication[0] customLocationProps.Authentication = &customlocations.CustomLocationPropertiesAuthentication{ - Type: &auth.Type, - Value: &auth.Value, + Type: pointer.To(auth.Type), + Value: pointer.To(auth.Value), } } if model.ClusterExtensionIds != nil { - customLocationProps.ClusterExtensionIds = &model.ClusterExtensionIds + customLocationProps.ClusterExtensionIds = pointer.To(model.ClusterExtensionIds) } if model.DisplayName != "" { - customLocationProps.DisplayName = &model.DisplayName + customLocationProps.DisplayName = pointer.To(model.DisplayName) } if model.HostResourceId != "" { - customLocationProps.HostResourceId = &model.HostResourceId + customLocationProps.HostResourceId = pointer.To(model.HostResourceId) } if model.HostType != "" { hostType := customlocations.HostType(model.HostType) - customLocationProps.HostType = &hostType + customLocationProps.HostType = pointer.To(hostType) } if model.Namespace != "" { - customLocationProps.Namespace = &model.Namespace + customLocationProps.Namespace = pointer.To(model.Namespace) } props := customlocations.CustomLocation{ - Id: utils.String(id.ID()), + Id: pointer.To(id.ID()), Location: model.Location, - Name: utils.String(model.Name), - Properties: &customLocationProps, + Name: pointer.To(model.Name), + Properties: pointer.To(customLocationProps), } if err := client.CreateOrUpdateThenPoll(ctx, id, props); err != nil { @@ -216,42 +211,25 @@ func (r CustomLocationResource) Read() sdk.ResourceFunc { props := model.Properties state := CustomLocationResourceModel{ - Name: id.CustomLocationName, - ResourceGroupName: id.ResourceGroupName, - Location: model.Location, + Name: id.CustomLocationName, + ResourceGroupName: id.ResourceGroupName, + Location: model.Location, + ClusterExtensionIds: pointer.From(props.ClusterExtensionIds), + DisplayName: pointer.From(props.DisplayName), + HostResourceId: pointer.From(props.HostResourceId), + HostType: string(pointer.From(props.HostType)), + Namespace: pointer.From(props.Namespace), } if props != nil && props.Authentication != nil { - authType := pointer.From(props.Authentication.Type) - authValue := pointer.From(props.Authentication.Value) state.Authentication = []AuthModel{ { - Type: authType, - Value: authValue, + Type: pointer.From(props.Authentication.Type), + Value: pointer.From(props.Authentication.Value), }, } } - if props.ClusterExtensionIds != nil { - state.ClusterExtensionIds = *props.ClusterExtensionIds - } - - if props.DisplayName != nil { - state.DisplayName = *props.DisplayName - } - - if props.HostResourceId != nil { - state.HostResourceId = *props.HostResourceId - } - - if props.HostType != nil { - state.HostType = string(*props.HostType) - } - - if props.Namespace != nil { - state.Namespace = *props.Namespace - } - return metadata.Encode(&state) } return nil @@ -301,38 +279,38 @@ func (r CustomLocationResource) Update() sdk.ResourceFunc { d := metadata.ResourceData if d.HasChanges("authentication") { - if state.Authentication != nil { + if state.Authentication != nil && len(state.Authentication) > 0 { auth := state.Authentication[0] customLocationProps.Authentication = &customlocations.CustomLocationPropertiesAuthentication{ - Type: &auth.Type, - Value: &auth.Value, + Type: pointer.To(auth.Type), + Value: pointer.To(auth.Value), } } } if d.HasChange("cluster_extension_ids") { - customLocationProps.ClusterExtensionIds = &state.ClusterExtensionIds + customLocationProps.ClusterExtensionIds = pointer.To(state.ClusterExtensionIds) } if d.HasChange("display_name") { - customLocationProps.DisplayName = &state.DisplayName + customLocationProps.DisplayName = pointer.To(state.DisplayName) } if d.HasChange("host_resource_id") { - customLocationProps.HostResourceId = &state.HostResourceId + customLocationProps.HostResourceId = pointer.To(state.HostResourceId) } if d.HasChange("host_type") { hostType := customlocations.HostType(state.HostType) - customLocationProps.HostType = &hostType + customLocationProps.HostType = pointer.To(hostType) } if d.HasChange("namespace") { - customLocationProps.Namespace = &state.Namespace + customLocationProps.Namespace = pointer.To(state.Namespace) } props := customlocations.PatchableCustomLocations{ - Properties: &customLocationProps, + Properties: pointer.To(customLocationProps), } if _, err := client.Update(ctx, *id, props); err != nil { diff --git a/internal/services/extendedlocation/extended_location_custom_location_test.go b/internal/services/extendedlocation/extended_location_custom_location_test.go index a4ae20e543e4..d080b97fc70d 100644 --- a/internal/services/extendedlocation/extended_location_custom_location_test.go +++ b/internal/services/extendedlocation/extended_location_custom_location_test.go @@ -79,6 +79,13 @@ func TestAccExtendedLocationCustomLocations_update(t *testing.T) { ), }, data.ImportStep(), + { + Config: r.basic(data, credential, privateKey, publicKey), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), }) } @@ -88,13 +95,12 @@ func (r CustomLocationResource) basic(data acceptance.TestData, credential strin %s resource "azurerm_extended_custom_location" "test" { - name = "acctestcustomlocation%d" + name = "acctestcustomlocation%[2]d" resource_group_name = azurerm_resource_group.test.name location = azurerm_resource_group.test.location cluster_extension_ids = [ - "${azurerm_arc_kubernetes_cluster_extension.test.id}" + azurerm_arc_kubernetes_cluster_extension.test.id ] - display_name = "customlocation%[2]d" namespace = "namespace%[2]d" host_resource_id = azurerm_arc_kubernetes_cluster.test.id } @@ -107,11 +113,11 @@ func (r CustomLocationResource) update(data acceptance.TestData, credential stri %s resource "azurerm_extended_custom_location" "test" { - name = "acctestcustomlocation%d" + name = "acctestcustomlocation%[2]d" resource_group_name = azurerm_resource_group.test.name location = azurerm_resource_group.test.location cluster_extension_ids = [ - "${azurerm_arc_kubernetes_cluster_extension.test.id}", + azurerm_arc_kubernetes_cluster_extension.test.id ] display_name = "customlocationupdate%[2]d" @@ -172,7 +178,7 @@ resource "azurerm_network_interface" "test" { } resource "azurerm_network_security_group" "my_terraform_nsg" { - name = "myNetworkSecurityGroup" + name = "myNetworkSG-%[1]d" location = azurerm_resource_group.test.location resource_group_name = azurerm_resource_group.test.name security_rule { @@ -222,13 +228,6 @@ resource "azurerm_linux_virtual_machine" "test" { sku = "18.04-LTS" version = "latest" } - - lifecycle { - ignore_changes = [ - identity, - tags, - ] - } } resource "azurerm_arc_kubernetes_cluster" "test" { @@ -248,7 +247,7 @@ resource "azurerm_arc_kubernetes_cluster" "test" { } resource "azurerm_arc_kubernetes_cluster_extension" "test" { - name = "extension4" + name = "extension-%[1]d" cluster_id = azurerm_arc_kubernetes_cluster.test.id extension_type = "microsoft.vmware" release_namespace = "vmware-extension" From 8e80eb80fae16b0d0897d63284407d3ebc105ad8 Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Fri, 26 Jan 2024 15:12:01 +0800 Subject: [PATCH 13/35] update docs --- website/docs/r/extended_location_custom_location.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/r/extended_location_custom_location.html.markdown b/website/docs/r/extended_location_custom_location.html.markdown index b80df9484a67..8a78a1420fef 100644 --- a/website/docs/r/extended_location_custom_location.html.markdown +++ b/website/docs/r/extended_location_custom_location.html.markdown @@ -44,7 +44,7 @@ resource "azurerm_extended_location_custom_location" "example" { resource_group_name = azurerm_resource_group.example.name location = "West Europe" cluster_extension_ids = [ - "${azurerm_arc_kubernetes_cluster_extension.test.id}" + azurerm_arc_kubernetes_cluster_extension.example.id ] display_name = "example-custom-location" namespace = "example-namespace" From 4e3466d28cb9833b2d014b6a965d5bf477811478 Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Fri, 26 Jan 2024 17:20:45 +0800 Subject: [PATCH 14/35] pass golint --- .../extended_location_custom_location.go | 35 +++++-------------- 1 file changed, 8 insertions(+), 27 deletions(-) diff --git a/internal/services/extendedlocation/extended_location_custom_location.go b/internal/services/extendedlocation/extended_location_custom_location.go index aadf2e90719f..6e2ec04458e0 100644 --- a/internal/services/extendedlocation/extended_location_custom_location.go +++ b/internal/services/extendedlocation/extended_location_custom_location.go @@ -141,9 +141,15 @@ func (r CustomLocationResource) Create() sdk.ResourceFunc { return metadata.ResourceRequiresImport(r.ResourceType(), id) } - customLocationProps := customlocations.CustomLocationProperties{} + customLocationProps := customlocations.CustomLocationProperties{ + ClusterExtensionIds: pointer.To(model.ClusterExtensionIds), + DisplayName: pointer.To(model.DisplayName), + HostResourceId: pointer.To(model.HostResourceId), + HostType: pointer.To(customlocations.HostType(model.HostType)), + Namespace: pointer.To(model.Namespace), + } - if model.Authentication != nil && len(model.Authentication) > 0 { + if len(model.Authentication) > 0 { auth := model.Authentication[0] customLocationProps.Authentication = &customlocations.CustomLocationPropertiesAuthentication{ Type: pointer.To(auth.Type), @@ -151,27 +157,6 @@ func (r CustomLocationResource) Create() sdk.ResourceFunc { } } - if model.ClusterExtensionIds != nil { - customLocationProps.ClusterExtensionIds = pointer.To(model.ClusterExtensionIds) - } - - if model.DisplayName != "" { - customLocationProps.DisplayName = pointer.To(model.DisplayName) - } - - if model.HostResourceId != "" { - customLocationProps.HostResourceId = pointer.To(model.HostResourceId) - } - - if model.HostType != "" { - hostType := customlocations.HostType(model.HostType) - customLocationProps.HostType = pointer.To(hostType) - } - - if model.Namespace != "" { - customLocationProps.Namespace = pointer.To(model.Namespace) - } - props := customlocations.CustomLocation{ Id: pointer.To(id.ID()), Location: model.Location, @@ -305,10 +290,6 @@ func (r CustomLocationResource) Update() sdk.ResourceFunc { customLocationProps.HostType = pointer.To(hostType) } - if d.HasChange("namespace") { - customLocationProps.Namespace = pointer.To(state.Namespace) - } - props := customlocations.PatchableCustomLocations{ Properties: pointer.To(customLocationProps), } From fdc0f4952593364779cc9cd1cd516f9152a7a784 Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Fri, 26 Jan 2024 17:33:04 +0800 Subject: [PATCH 15/35] update to avoid nil dereference --- .../extended_location_custom_location.go | 29 +++++++++++++------ 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/internal/services/extendedlocation/extended_location_custom_location.go b/internal/services/extendedlocation/extended_location_custom_location.go index 6e2ec04458e0..95f621a963fa 100644 --- a/internal/services/extendedlocation/extended_location_custom_location.go +++ b/internal/services/extendedlocation/extended_location_custom_location.go @@ -196,17 +196,28 @@ func (r CustomLocationResource) Read() sdk.ResourceFunc { props := model.Properties state := CustomLocationResourceModel{ - Name: id.CustomLocationName, - ResourceGroupName: id.ResourceGroupName, - Location: model.Location, - ClusterExtensionIds: pointer.From(props.ClusterExtensionIds), - DisplayName: pointer.From(props.DisplayName), - HostResourceId: pointer.From(props.HostResourceId), - HostType: string(pointer.From(props.HostType)), - Namespace: pointer.From(props.Namespace), + Name: id.CustomLocationName, + ResourceGroupName: id.ResourceGroupName, + Location: model.Location, } - if props != nil && props.Authentication != nil { + if props.ClusterExtensionIds != nil { + state.ClusterExtensionIds = pointer.From(props.ClusterExtensionIds) + } + if props.DisplayName != nil { + state.DisplayName = pointer.From(props.DisplayName) + } + if props.HostResourceId != nil { + state.HostResourceId = pointer.From(props.HostResourceId) + } + if props.HostType != nil { + state.HostType = string(pointer.From(props.HostType)) + } + if props.Namespace != nil { + state.Namespace = pointer.From(props.Namespace) + } + + if props.Authentication != nil { state.Authentication = []AuthModel{ { Type: pointer.From(props.Authentication.Type), From 0309778f3b05df3f12f79dd195ac157f106205d1 Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Thu, 1 Dec 2022 11:52:49 +0800 Subject: [PATCH 16/35] temp --- internal/clients/client.go | 9 +- .../extended_location_custom_locations.go | 326 ++++++++++++++++++ ...extended_location_custom_locations_test.go | 105 ++++++ .../customlocations/id_customlocation.go | 3 +- .../method_createorupdate_autorest.go | 79 +++++ .../customlocations/method_delete_autorest.go | 78 +++++ .../customlocations/method_get_autorest.go | 68 ++++ .../method_listbyresourcegroup_autorest.go | 187 ++++++++++ .../method_listbysubscription_autorest.go | 187 ++++++++++ ...ethod_listenabledresourcetypes_autorest.go | 186 ++++++++++ .../customlocations/method_update_autorest.go | 69 ++++ .../2021-08-15/customlocations/predicates.go | 5 +- 12 files changed, 1294 insertions(+), 8 deletions(-) create mode 100644 internal/services/extendedlocation/extended_location_custom_locations.go create mode 100644 internal/services/extendedlocation/extended_location_custom_locations_test.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_createorupdate_autorest.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_delete_autorest.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_get_autorest.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listbyresourcegroup_autorest.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listbysubscription_autorest.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listenabledresourcetypes_autorest.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_update_autorest.go diff --git a/internal/clients/client.go b/internal/clients/client.go index 598a87227ab1..2949e562c457 100644 --- a/internal/clients/client.go +++ b/internal/clients/client.go @@ -160,9 +160,8 @@ type Client struct { // StopContext is used for propagating control from Terraform Core (e.g. Ctrl/Cmd+C) StopContext context.Context - Account *ResourceManagerAccount - Features features.UserFeatures - + Account *ResourceManagerAccount + Features features.UserFeatures AadB2c *aadb2c_v2021_04_01_preview.Client Advisor *advisor.Client AnalysisServices *analysisservices_v2017_08_01.Client @@ -449,9 +448,13 @@ func (client *Client) Build(ctx context.Context, o *common.ClientOptions) error if client.Eventhub, err = eventhub.NewClient(o); err != nil { return fmt.Errorf("building clients for Eventhub: %+v", err) } +<<<<<<< HEAD if client.ExtendedLocation, err = extendedlocation.NewClient(o); err != nil { return fmt.Errorf("building clients for ExtendedLocation: %+v", err) } +======= + client.ExtendedLocation = extendedlocation.NewClient(o) +>>>>>>> d9fd896b83 (temp) if client.FluidRelay, err = fluidrelay.NewClient(o); err != nil { return fmt.Errorf("building clients for FluidRelay: %+v", err) } diff --git a/internal/services/extendedlocation/extended_location_custom_locations.go b/internal/services/extendedlocation/extended_location_custom_locations.go new file mode 100644 index 000000000000..daae919ef0ae --- /dev/null +++ b/internal/services/extendedlocation/extended_location_custom_locations.go @@ -0,0 +1,326 @@ +package extendedlocation + +import ( + "context" + "fmt" + "time" + + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" + "github.com/hashicorp/terraform-provider-azurerm/utils" +) + +type CustomLocationResource struct{} + +type CustomLocationResourceModel struct { + Name string `tfschema:"name"` + ResourceGroupName string `tfschema:"resource_group_name"` + Location string `tfschema:"location"` + AuthenticationType string `tfschema:"authentication_type"` + AuthenticationValue string `tfschema:"authentication_value"` + ClusterExtensionIds []string `tfschema:"cluster_extension_ids"` + DisplayName string `tfschema:"display_name"` + HostResourceId string `tfschema:"host_resource_id"` + HostType string `tfschema:"host_type"` + Namespace string `tfschema:"namespace"` +} + +func (r CustomLocationResource) Arguments() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "resource_group_name": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "location": { + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "cluster_extension_ids": { + Type: pluginsdk.TypeList, + Required: true, + Elem: &pluginsdk.Schema{ + Type: pluginsdk.TypeString, + }, + }, + + "host_resource_id": { + Type: pluginsdk.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "authentication_type": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "authentication_value": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "display_name": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "host_type": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{ + string(customlocations.HostTypeKubernetes), + }, false), + }, + + "namespace": { + Type: pluginsdk.TypeString, + Optional: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + } +} + +func (r CustomLocationResource) Attributes() map[string]*schema.Schema { + return map[string]*schema.Schema{} +} + +func (r CustomLocationResource) ModelObject() interface{} { + return &CustomLocationResourceModel{} +} + +func (r CustomLocationResource) ResourceType() string { + return "azurerm_extended_custom_locations" +} + +func (r CustomLocationResource) Create() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + var model CustomLocationResourceModel + if err := metadata.Decode(&model); err != nil { + return err + } + + subscriptionId := metadata.Client.Account.SubscriptionId + client := metadata.Client.ExtendedLocation.CustomLocationsClient + + id := customlocations.NewCustomLocationID(subscriptionId, model.ResourceGroupName, model.Name) + existing, err := client.Get(ctx, id) + if err != nil && !response.WasNotFound(existing.HttpResponse) { + return fmt.Errorf("checking for presence of existing %s: %+v", id, err) + } + + if !response.WasNotFound(existing.HttpResponse) { + return metadata.ResourceRequiresImport(r.ResourceType(), id) + } + + customLocationProps := customlocations.CustomLocationProperties{} + + if model.AuthenticationValue != "" && model.AuthenticationType != "" { + customLocationProps.Authentication = &customlocations.CustomLocationPropertiesAuthentication{ + Type: &model.AuthenticationType, + Value: &model.AuthenticationValue, + } + } + + if model.ClusterExtensionIds != nil { + customLocationProps.ClusterExtensionIds = &model.ClusterExtensionIds + } + + if model.DisplayName != "" { + customLocationProps.DisplayName = &model.DisplayName + } + + if model.HostResourceId != "" { + customLocationProps.HostResourceId = &model.HostResourceId + } + + if model.HostType != "" { + hostType := customlocations.HostType(model.HostType) + customLocationProps.HostType = &hostType + } + + if model.Namespace != "" { + customLocationProps.Namespace = &model.Namespace + } + + props := customlocations.CustomLocation{ + Id: utils.String(id.ID()), + Location: model.Location, + Name: utils.String(model.Name), + Properties: &customLocationProps, + } + + if err := client.CreateOrUpdateThenPoll(ctx, id, props); err != nil { + return fmt.Errorf("creating %s: %+v", id, err) + } + + metadata.SetID(id) + return nil + }, + } +} + +func (r CustomLocationResource) Read() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 5 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.ExtendedLocation.CustomLocationsClient + id, err := customlocations.ParseCustomLocationID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + resp, err := client.Get(ctx, *id) + if err != nil { + if response.WasNotFound(resp.HttpResponse) { + return metadata.MarkAsGone(id) + } + return fmt.Errorf("reading %s: %+v", *id, err) + } + + if model := resp.Model; model != nil { + props := model.Properties + + state := CustomLocationResourceModel{ + Name: id.CustomLocationName, + ResourceGroupName: id.ResourceGroupName, + Location: model.Location, + } + + if props.Authentication != nil && props.Authentication.Type != nil && props.Authentication.Value != nil { + state.AuthenticationType = *props.Authentication.Type + state.AuthenticationValue = *props.Authentication.Value + } + + if props.ClusterExtensionIds != nil { + state.ClusterExtensionIds = *props.ClusterExtensionIds + } + + if props.DisplayName != nil { + state.DisplayName = *props.DisplayName + } + + if props.HostResourceId != nil { + state.HostResourceId = *props.HostResourceId + } + + if props.HostType != nil { + state.HostType = string(*props.HostType) + } + + if props.Namespace != nil { + state.Namespace = *props.Namespace + } + + return metadata.Encode(&state) + } + return nil + }, + } +} + +func (r CustomLocationResource) Delete() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.ExtendedLocation.CustomLocationsClient + id, err := customlocations.ParseCustomLocationID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + metadata.Logger.Infof("deleting %s", *id) + + if resp, err := client.Delete(ctx, *id); err != nil { + if !response.WasNotFound(resp.HttpResponse) { + return fmt.Errorf("deleting %s: %+v", *id, err) + } + } + + return nil + }, + } +} + +func (r CustomLocationResource) Update() sdk.ResourceFunc { + return sdk.ResourceFunc{ + Timeout: 30 * time.Minute, + Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { + client := metadata.Client.ExtendedLocation.CustomLocationsClient + id, err := customlocations.ParseCustomLocationID(metadata.ResourceData.Id()) + if err != nil { + return err + } + + var state CustomLocationResourceModel + if err := metadata.Decode(&state); err != nil { + return fmt.Errorf("decoding %+v", err) + } + + customLocationProps := customlocations.CustomLocationProperties{} + d := metadata.ResourceData + + if d.HasChanges("authentication_type", "authentication_value") { + customLocationProps.Authentication = &customlocations.CustomLocationPropertiesAuthentication{ + Type: &state.AuthenticationType, + Value: &state.AuthenticationValue, + } + } + + if d.HasChange("cluster_extension_ids") { + customLocationProps.ClusterExtensionIds = &state.ClusterExtensionIds + } + + if d.HasChange("display_name") { + customLocationProps.DisplayName = &state.DisplayName + } + + if d.HasChange("host_resource_id") { + customLocationProps.HostResourceId = &state.HostResourceId + } + + if d.HasChange("host_type") { + hostType := customlocations.HostType(state.HostType) + customLocationProps.HostType = &hostType + } + + if d.HasChange("namespace") { + customLocationProps.Namespace = &state.Namespace + } + + props := customlocations.PatchableCustomLocations{ + Properties: &customLocationProps, + } + + if _, err := client.Update(ctx, *id, props); err != nil { + return fmt.Errorf("updating %s: %+v", *id, err) + } + return nil + }, + } +} + +func (r CustomLocationResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { + return customlocations.ValidateCustomLocationID +} diff --git a/internal/services/extendedlocation/extended_location_custom_locations_test.go b/internal/services/extendedlocation/extended_location_custom_locations_test.go new file mode 100644 index 000000000000..3fc79c6a061a --- /dev/null +++ b/internal/services/extendedlocation/extended_location_custom_locations_test.go @@ -0,0 +1,105 @@ +package extendedlocation_test + +import ( + "context" + "fmt" + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" + "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" + "github.com/hashicorp/terraform-provider-azurerm/utils" + "testing" +) + +type CustomLocationResource struct{} + +func (r CustomLocationResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { + id, err := customlocations.ParseCustomLocationID(state.ID) + if err != nil { + return nil, err + } + + resp, err := client.ExtendedLocation.CustomLocationsClient.Get(ctx, *id) + if err != nil { + if response.WasNotFound(resp.HttpResponse) { + return utils.Bool(false), nil + } + return nil, fmt.Errorf("retrieving %s: %+v", *id, err) + } + return utils.Bool(true), nil +} + +func TestAccExtendedLocationCustomLocations_basic(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_extended_custom_locations", "test") + r := CustomLocationResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func (r CustomLocationResource) basic(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` +%s + +resource "azurerm_extended_custom_locations" "test" { + name = "acctestcustomlocation%d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + cluster_extension_ids = [ + "${azurerm_kubernetes_cluster.test.id}/providers/Microsoft.KubernetesConfiguration/extensions/foo" + ] + display_name = "customlocation%[2]d" + namespace = "namespace%[2]d" + host_resource_id = azurerm_kubernetes_cluster.test.id +} +`, template, data.RandomInteger) +} + +func (r CustomLocationResource) template(data acceptance.TestData) string { + data.Locations.Primary = "westus" + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +resource "azurerm_resource_group" "test" { + name = "acctestRG-%[1]d" + location = "%[2]s" +} + +data "azurerm_extended_locations" "test" { + location = azurerm_resource_group.test.location +} + +resource "azurerm_kubernetes_cluster" "test" { + name = "acctestaks%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + dns_prefix = "acctestaks%[1]d" + kubernetes_version = "1.24.3" + run_command_enabled = true + + default_node_pool { + name = "default" + node_count = 1 + vm_size = "Standard_ds2_v2" + } + identity { + type = "SystemAssigned" + } + tags = { + ENV = "Test1" + } +} +`, data.RandomInteger, data.Locations.Primary) +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/id_customlocation.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/id_customlocation.go index 0381e8f070d4..e3e83251d840 100644 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/id_customlocation.go +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/id_customlocation.go @@ -57,7 +57,6 @@ func ParseCustomLocationIDInsensitively(input string) (*CustomLocationId, error) if err != nil { return nil, fmt.Errorf("parsing %q: %+v", input, err) } - id := CustomLocationId{} if err := id.FromParseResult(*parsed); err != nil { return nil, err @@ -115,7 +114,7 @@ func (id CustomLocationId) Segments() []resourceids.Segment { resourceids.StaticSegment("staticProviders", "providers", "providers"), resourceids.ResourceProviderSegment("staticMicrosoftExtendedLocation", "Microsoft.ExtendedLocation", "Microsoft.ExtendedLocation"), resourceids.StaticSegment("staticCustomLocations", "customLocations", "customLocations"), - resourceids.UserSpecifiedSegment("customLocationName", "customLocationValue"), + resourceids.UserSpecifiedSegment("resourceName", "resourceValue"), } } diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_createorupdate_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_createorupdate_autorest.go new file mode 100644 index 000000000000..f9b415ae1b04 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_createorupdate_autorest.go @@ -0,0 +1,79 @@ +package customlocations + +import ( + "context" + "fmt" + "net/http" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/hashicorp/go-azure-helpers/polling" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type CreateOrUpdateOperationResponse struct { + Poller polling.LongRunningPoller + HttpResponse *http.Response +} + +// CreateOrUpdate ... +func (c CustomLocationsClient) CreateOrUpdate(ctx context.Context, id CustomLocationId, input CustomLocation) (result CreateOrUpdateOperationResponse, err error) { + req, err := c.preparerForCreateOrUpdate(ctx, id, input) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "CreateOrUpdate", nil, "Failure preparing request") + return + } + + result, err = c.senderForCreateOrUpdate(ctx, req) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "CreateOrUpdate", result.HttpResponse, "Failure sending request") + return + } + + return +} + +// CreateOrUpdateThenPoll performs CreateOrUpdate then polls until it's completed +func (c CustomLocationsClient) CreateOrUpdateThenPoll(ctx context.Context, id CustomLocationId, input CustomLocation) error { + result, err := c.CreateOrUpdate(ctx, id, input) + if err != nil { + return fmt.Errorf("performing CreateOrUpdate: %+v", err) + } + + if err := result.Poller.PollUntilDone(); err != nil { + return fmt.Errorf("polling after CreateOrUpdate: %+v", err) + } + + return nil +} + +// preparerForCreateOrUpdate prepares the CreateOrUpdate request. +func (c CustomLocationsClient) preparerForCreateOrUpdate(ctx context.Context, id CustomLocationId, input CustomLocation) (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": defaultApiVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPut(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(id.ID()), + autorest.WithJSON(input), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// senderForCreateOrUpdate sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (c CustomLocationsClient) senderForCreateOrUpdate(ctx context.Context, req *http.Request) (future CreateOrUpdateOperationResponse, err error) { + var resp *http.Response + resp, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + return + } + + future.Poller, err = polling.NewPollerFromResponse(ctx, resp, c.Client, req.Method) + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_delete_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_delete_autorest.go new file mode 100644 index 000000000000..5f71cda5e35c --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_delete_autorest.go @@ -0,0 +1,78 @@ +package customlocations + +import ( + "context" + "fmt" + "net/http" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/hashicorp/go-azure-helpers/polling" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type DeleteOperationResponse struct { + Poller polling.LongRunningPoller + HttpResponse *http.Response +} + +// Delete ... +func (c CustomLocationsClient) Delete(ctx context.Context, id CustomLocationId) (result DeleteOperationResponse, err error) { + req, err := c.preparerForDelete(ctx, id) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "Delete", nil, "Failure preparing request") + return + } + + result, err = c.senderForDelete(ctx, req) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "Delete", result.HttpResponse, "Failure sending request") + return + } + + return +} + +// DeleteThenPoll performs Delete then polls until it's completed +func (c CustomLocationsClient) DeleteThenPoll(ctx context.Context, id CustomLocationId) error { + result, err := c.Delete(ctx, id) + if err != nil { + return fmt.Errorf("performing Delete: %+v", err) + } + + if err := result.Poller.PollUntilDone(); err != nil { + return fmt.Errorf("polling after Delete: %+v", err) + } + + return nil +} + +// preparerForDelete prepares the Delete request. +func (c CustomLocationsClient) preparerForDelete(ctx context.Context, id CustomLocationId) (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": defaultApiVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsDelete(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(id.ID()), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// senderForDelete sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (c CustomLocationsClient) senderForDelete(ctx context.Context, req *http.Request) (future DeleteOperationResponse, err error) { + var resp *http.Response + resp, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + return + } + + future.Poller, err = polling.NewPollerFromResponse(ctx, resp, c.Client, req.Method) + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_get_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_get_autorest.go new file mode 100644 index 000000000000..475d52753db2 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_get_autorest.go @@ -0,0 +1,68 @@ +package customlocations + +import ( + "context" + "net/http" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type GetOperationResponse struct { + HttpResponse *http.Response + Model *CustomLocation +} + +// Get ... +func (c CustomLocationsClient) Get(ctx context.Context, id CustomLocationId) (result GetOperationResponse, err error) { + req, err := c.preparerForGet(ctx, id) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "Get", nil, "Failure preparing request") + return + } + + result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "Get", result.HttpResponse, "Failure sending request") + return + } + + result, err = c.responderForGet(result.HttpResponse) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "Get", result.HttpResponse, "Failure responding to request") + return + } + + return +} + +// preparerForGet prepares the Get request. +func (c CustomLocationsClient) preparerForGet(ctx context.Context, id CustomLocationId) (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": defaultApiVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsGet(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(id.ID()), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// responderForGet handles the response to the Get request. The method always +// closes the http.Response Body. +func (c CustomLocationsClient) responderForGet(resp *http.Response) (result GetOperationResponse, err error) { + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Model), + autorest.ByClosing()) + result.HttpResponse = resp + + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listbyresourcegroup_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listbyresourcegroup_autorest.go new file mode 100644 index 000000000000..5ed484831cd6 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listbyresourcegroup_autorest.go @@ -0,0 +1,187 @@ +package customlocations + +import ( + "context" + "fmt" + "net/http" + "net/url" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ListByResourceGroupOperationResponse struct { + HttpResponse *http.Response + Model *[]CustomLocation + + nextLink *string + nextPageFunc func(ctx context.Context, nextLink string) (ListByResourceGroupOperationResponse, error) +} + +type ListByResourceGroupCompleteResult struct { + Items []CustomLocation +} + +func (r ListByResourceGroupOperationResponse) HasMore() bool { + return r.nextLink != nil +} + +func (r ListByResourceGroupOperationResponse) LoadMore(ctx context.Context) (resp ListByResourceGroupOperationResponse, err error) { + if !r.HasMore() { + err = fmt.Errorf("no more pages returned") + return + } + return r.nextPageFunc(ctx, *r.nextLink) +} + +// ListByResourceGroup ... +func (c CustomLocationsClient) ListByResourceGroup(ctx context.Context, id commonids.ResourceGroupId) (resp ListByResourceGroupOperationResponse, err error) { + req, err := c.preparerForListByResourceGroup(ctx, id) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListByResourceGroup", nil, "Failure preparing request") + return + } + + resp.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListByResourceGroup", resp.HttpResponse, "Failure sending request") + return + } + + resp, err = c.responderForListByResourceGroup(resp.HttpResponse) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListByResourceGroup", resp.HttpResponse, "Failure responding to request") + return + } + return +} + +// preparerForListByResourceGroup prepares the ListByResourceGroup request. +func (c CustomLocationsClient) preparerForListByResourceGroup(ctx context.Context, id commonids.ResourceGroupId) (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": defaultApiVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsGet(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(fmt.Sprintf("%s/providers/Microsoft.ExtendedLocation/customLocations", id.ID())), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// preparerForListByResourceGroupWithNextLink prepares the ListByResourceGroup request with the given nextLink token. +func (c CustomLocationsClient) preparerForListByResourceGroupWithNextLink(ctx context.Context, nextLink string) (*http.Request, error) { + uri, err := url.Parse(nextLink) + if err != nil { + return nil, fmt.Errorf("parsing nextLink %q: %+v", nextLink, err) + } + queryParameters := map[string]interface{}{} + for k, v := range uri.Query() { + if len(v) == 0 { + continue + } + val := v[0] + val = autorest.Encode("query", val) + queryParameters[k] = val + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsGet(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(uri.Path), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// responderForListByResourceGroup handles the response to the ListByResourceGroup request. The method always +// closes the http.Response Body. +func (c CustomLocationsClient) responderForListByResourceGroup(resp *http.Response) (result ListByResourceGroupOperationResponse, err error) { + type page struct { + Values []CustomLocation `json:"value"` + NextLink *string `json:"nextLink"` + } + var respObj page + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&respObj), + autorest.ByClosing()) + result.HttpResponse = resp + result.Model = &respObj.Values + result.nextLink = respObj.NextLink + if respObj.NextLink != nil { + result.nextPageFunc = func(ctx context.Context, nextLink string) (result ListByResourceGroupOperationResponse, err error) { + req, err := c.preparerForListByResourceGroupWithNextLink(ctx, nextLink) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListByResourceGroup", nil, "Failure preparing request") + return + } + + result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListByResourceGroup", result.HttpResponse, "Failure sending request") + return + } + + result, err = c.responderForListByResourceGroup(result.HttpResponse) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListByResourceGroup", result.HttpResponse, "Failure responding to request") + return + } + + return + } + } + return +} + +// ListByResourceGroupComplete retrieves all of the results into a single object +func (c CustomLocationsClient) ListByResourceGroupComplete(ctx context.Context, id commonids.ResourceGroupId) (ListByResourceGroupCompleteResult, error) { + return c.ListByResourceGroupCompleteMatchingPredicate(ctx, id, CustomLocationOperationPredicate{}) +} + +// ListByResourceGroupCompleteMatchingPredicate retrieves all of the results and then applied the predicate +func (c CustomLocationsClient) ListByResourceGroupCompleteMatchingPredicate(ctx context.Context, id commonids.ResourceGroupId, predicate CustomLocationOperationPredicate) (resp ListByResourceGroupCompleteResult, err error) { + items := make([]CustomLocation, 0) + + page, err := c.ListByResourceGroup(ctx, id) + if err != nil { + err = fmt.Errorf("loading the initial page: %+v", err) + return + } + if page.Model != nil { + for _, v := range *page.Model { + if predicate.Matches(v) { + items = append(items, v) + } + } + } + + for page.HasMore() { + page, err = page.LoadMore(ctx) + if err != nil { + err = fmt.Errorf("loading the next page: %+v", err) + return + } + + if page.Model != nil { + for _, v := range *page.Model { + if predicate.Matches(v) { + items = append(items, v) + } + } + } + } + + out := ListByResourceGroupCompleteResult{ + Items: items, + } + return out, nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listbysubscription_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listbysubscription_autorest.go new file mode 100644 index 000000000000..fed94c9df8be --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listbysubscription_autorest.go @@ -0,0 +1,187 @@ +package customlocations + +import ( + "context" + "fmt" + "net/http" + "net/url" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ListBySubscriptionOperationResponse struct { + HttpResponse *http.Response + Model *[]CustomLocation + + nextLink *string + nextPageFunc func(ctx context.Context, nextLink string) (ListBySubscriptionOperationResponse, error) +} + +type ListBySubscriptionCompleteResult struct { + Items []CustomLocation +} + +func (r ListBySubscriptionOperationResponse) HasMore() bool { + return r.nextLink != nil +} + +func (r ListBySubscriptionOperationResponse) LoadMore(ctx context.Context) (resp ListBySubscriptionOperationResponse, err error) { + if !r.HasMore() { + err = fmt.Errorf("no more pages returned") + return + } + return r.nextPageFunc(ctx, *r.nextLink) +} + +// ListBySubscription ... +func (c CustomLocationsClient) ListBySubscription(ctx context.Context, id commonids.SubscriptionId) (resp ListBySubscriptionOperationResponse, err error) { + req, err := c.preparerForListBySubscription(ctx, id) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListBySubscription", nil, "Failure preparing request") + return + } + + resp.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListBySubscription", resp.HttpResponse, "Failure sending request") + return + } + + resp, err = c.responderForListBySubscription(resp.HttpResponse) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListBySubscription", resp.HttpResponse, "Failure responding to request") + return + } + return +} + +// preparerForListBySubscription prepares the ListBySubscription request. +func (c CustomLocationsClient) preparerForListBySubscription(ctx context.Context, id commonids.SubscriptionId) (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": defaultApiVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsGet(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(fmt.Sprintf("%s/providers/Microsoft.ExtendedLocation/customLocations", id.ID())), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// preparerForListBySubscriptionWithNextLink prepares the ListBySubscription request with the given nextLink token. +func (c CustomLocationsClient) preparerForListBySubscriptionWithNextLink(ctx context.Context, nextLink string) (*http.Request, error) { + uri, err := url.Parse(nextLink) + if err != nil { + return nil, fmt.Errorf("parsing nextLink %q: %+v", nextLink, err) + } + queryParameters := map[string]interface{}{} + for k, v := range uri.Query() { + if len(v) == 0 { + continue + } + val := v[0] + val = autorest.Encode("query", val) + queryParameters[k] = val + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsGet(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(uri.Path), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// responderForListBySubscription handles the response to the ListBySubscription request. The method always +// closes the http.Response Body. +func (c CustomLocationsClient) responderForListBySubscription(resp *http.Response) (result ListBySubscriptionOperationResponse, err error) { + type page struct { + Values []CustomLocation `json:"value"` + NextLink *string `json:"nextLink"` + } + var respObj page + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&respObj), + autorest.ByClosing()) + result.HttpResponse = resp + result.Model = &respObj.Values + result.nextLink = respObj.NextLink + if respObj.NextLink != nil { + result.nextPageFunc = func(ctx context.Context, nextLink string) (result ListBySubscriptionOperationResponse, err error) { + req, err := c.preparerForListBySubscriptionWithNextLink(ctx, nextLink) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListBySubscription", nil, "Failure preparing request") + return + } + + result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListBySubscription", result.HttpResponse, "Failure sending request") + return + } + + result, err = c.responderForListBySubscription(result.HttpResponse) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListBySubscription", result.HttpResponse, "Failure responding to request") + return + } + + return + } + } + return +} + +// ListBySubscriptionComplete retrieves all of the results into a single object +func (c CustomLocationsClient) ListBySubscriptionComplete(ctx context.Context, id commonids.SubscriptionId) (ListBySubscriptionCompleteResult, error) { + return c.ListBySubscriptionCompleteMatchingPredicate(ctx, id, CustomLocationOperationPredicate{}) +} + +// ListBySubscriptionCompleteMatchingPredicate retrieves all of the results and then applied the predicate +func (c CustomLocationsClient) ListBySubscriptionCompleteMatchingPredicate(ctx context.Context, id commonids.SubscriptionId, predicate CustomLocationOperationPredicate) (resp ListBySubscriptionCompleteResult, err error) { + items := make([]CustomLocation, 0) + + page, err := c.ListBySubscription(ctx, id) + if err != nil { + err = fmt.Errorf("loading the initial page: %+v", err) + return + } + if page.Model != nil { + for _, v := range *page.Model { + if predicate.Matches(v) { + items = append(items, v) + } + } + } + + for page.HasMore() { + page, err = page.LoadMore(ctx) + if err != nil { + err = fmt.Errorf("loading the next page: %+v", err) + return + } + + if page.Model != nil { + for _, v := range *page.Model { + if predicate.Matches(v) { + items = append(items, v) + } + } + } + } + + out := ListBySubscriptionCompleteResult{ + Items: items, + } + return out, nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listenabledresourcetypes_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listenabledresourcetypes_autorest.go new file mode 100644 index 000000000000..5febee715d99 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listenabledresourcetypes_autorest.go @@ -0,0 +1,186 @@ +package customlocations + +import ( + "context" + "fmt" + "net/http" + "net/url" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ListEnabledResourceTypesOperationResponse struct { + HttpResponse *http.Response + Model *[]EnabledResourceType + + nextLink *string + nextPageFunc func(ctx context.Context, nextLink string) (ListEnabledResourceTypesOperationResponse, error) +} + +type ListEnabledResourceTypesCompleteResult struct { + Items []EnabledResourceType +} + +func (r ListEnabledResourceTypesOperationResponse) HasMore() bool { + return r.nextLink != nil +} + +func (r ListEnabledResourceTypesOperationResponse) LoadMore(ctx context.Context) (resp ListEnabledResourceTypesOperationResponse, err error) { + if !r.HasMore() { + err = fmt.Errorf("no more pages returned") + return + } + return r.nextPageFunc(ctx, *r.nextLink) +} + +// ListEnabledResourceTypes ... +func (c CustomLocationsClient) ListEnabledResourceTypes(ctx context.Context, id CustomLocationId) (resp ListEnabledResourceTypesOperationResponse, err error) { + req, err := c.preparerForListEnabledResourceTypes(ctx, id) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListEnabledResourceTypes", nil, "Failure preparing request") + return + } + + resp.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListEnabledResourceTypes", resp.HttpResponse, "Failure sending request") + return + } + + resp, err = c.responderForListEnabledResourceTypes(resp.HttpResponse) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListEnabledResourceTypes", resp.HttpResponse, "Failure responding to request") + return + } + return +} + +// preparerForListEnabledResourceTypes prepares the ListEnabledResourceTypes request. +func (c CustomLocationsClient) preparerForListEnabledResourceTypes(ctx context.Context, id CustomLocationId) (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": defaultApiVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsGet(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(fmt.Sprintf("%s/enabledResourceTypes", id.ID())), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// preparerForListEnabledResourceTypesWithNextLink prepares the ListEnabledResourceTypes request with the given nextLink token. +func (c CustomLocationsClient) preparerForListEnabledResourceTypesWithNextLink(ctx context.Context, nextLink string) (*http.Request, error) { + uri, err := url.Parse(nextLink) + if err != nil { + return nil, fmt.Errorf("parsing nextLink %q: %+v", nextLink, err) + } + queryParameters := map[string]interface{}{} + for k, v := range uri.Query() { + if len(v) == 0 { + continue + } + val := v[0] + val = autorest.Encode("query", val) + queryParameters[k] = val + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsGet(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(uri.Path), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// responderForListEnabledResourceTypes handles the response to the ListEnabledResourceTypes request. The method always +// closes the http.Response Body. +func (c CustomLocationsClient) responderForListEnabledResourceTypes(resp *http.Response) (result ListEnabledResourceTypesOperationResponse, err error) { + type page struct { + Values []EnabledResourceType `json:"value"` + NextLink *string `json:"nextLink"` + } + var respObj page + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&respObj), + autorest.ByClosing()) + result.HttpResponse = resp + result.Model = &respObj.Values + result.nextLink = respObj.NextLink + if respObj.NextLink != nil { + result.nextPageFunc = func(ctx context.Context, nextLink string) (result ListEnabledResourceTypesOperationResponse, err error) { + req, err := c.preparerForListEnabledResourceTypesWithNextLink(ctx, nextLink) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListEnabledResourceTypes", nil, "Failure preparing request") + return + } + + result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListEnabledResourceTypes", result.HttpResponse, "Failure sending request") + return + } + + result, err = c.responderForListEnabledResourceTypes(result.HttpResponse) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListEnabledResourceTypes", result.HttpResponse, "Failure responding to request") + return + } + + return + } + } + return +} + +// ListEnabledResourceTypesComplete retrieves all of the results into a single object +func (c CustomLocationsClient) ListEnabledResourceTypesComplete(ctx context.Context, id CustomLocationId) (ListEnabledResourceTypesCompleteResult, error) { + return c.ListEnabledResourceTypesCompleteMatchingPredicate(ctx, id, EnabledResourceTypeOperationPredicate{}) +} + +// ListEnabledResourceTypesCompleteMatchingPredicate retrieves all of the results and then applied the predicate +func (c CustomLocationsClient) ListEnabledResourceTypesCompleteMatchingPredicate(ctx context.Context, id CustomLocationId, predicate EnabledResourceTypeOperationPredicate) (resp ListEnabledResourceTypesCompleteResult, err error) { + items := make([]EnabledResourceType, 0) + + page, err := c.ListEnabledResourceTypes(ctx, id) + if err != nil { + err = fmt.Errorf("loading the initial page: %+v", err) + return + } + if page.Model != nil { + for _, v := range *page.Model { + if predicate.Matches(v) { + items = append(items, v) + } + } + } + + for page.HasMore() { + page, err = page.LoadMore(ctx) + if err != nil { + err = fmt.Errorf("loading the next page: %+v", err) + return + } + + if page.Model != nil { + for _, v := range *page.Model { + if predicate.Matches(v) { + items = append(items, v) + } + } + } + } + + out := ListEnabledResourceTypesCompleteResult{ + Items: items, + } + return out, nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_update_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_update_autorest.go new file mode 100644 index 000000000000..d372dbf546d9 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_update_autorest.go @@ -0,0 +1,69 @@ +package customlocations + +import ( + "context" + "net/http" + + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type UpdateOperationResponse struct { + HttpResponse *http.Response + Model *CustomLocation +} + +// Update ... +func (c CustomLocationsClient) Update(ctx context.Context, id CustomLocationId, input PatchableCustomLocations) (result UpdateOperationResponse, err error) { + req, err := c.preparerForUpdate(ctx, id, input) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "Update", nil, "Failure preparing request") + return + } + + result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "Update", result.HttpResponse, "Failure sending request") + return + } + + result, err = c.responderForUpdate(result.HttpResponse) + if err != nil { + err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "Update", result.HttpResponse, "Failure responding to request") + return + } + + return +} + +// preparerForUpdate prepares the Update request. +func (c CustomLocationsClient) preparerForUpdate(ctx context.Context, id CustomLocationId, input PatchableCustomLocations) (*http.Request, error) { + queryParameters := map[string]interface{}{ + "api-version": defaultApiVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPatch(), + autorest.WithBaseURL(c.baseUri), + autorest.WithPath(id.ID()), + autorest.WithJSON(input), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// responderForUpdate handles the response to the Update request. The method always +// closes the http.Response Body. +func (c CustomLocationsClient) responderForUpdate(resp *http.Response) (result UpdateOperationResponse, err error) { + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result.Model), + autorest.ByClosing()) + result.HttpResponse = resp + + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/predicates.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/predicates.go index f18b5aa943f1..3fcd841ecb94 100644 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/predicates.go +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/predicates.go @@ -11,7 +11,7 @@ type CustomLocationOperationPredicate struct { } func (p CustomLocationOperationPredicate) Matches(input CustomLocation) bool { - + if p.Id != nil && (input.Id == nil || *p.Id != *input.Id) { return false } @@ -19,7 +19,7 @@ func (p CustomLocationOperationPredicate) Matches(input CustomLocation) bool { if p.Location != nil && *p.Location != input.Location { return false } - + if p.Name != nil && (input.Name == nil || *p.Name != *input.Name) { return false } @@ -38,7 +38,6 @@ type EnabledResourceTypeOperationPredicate struct { } func (p EnabledResourceTypeOperationPredicate) Matches(input EnabledResourceType) bool { - if p.Id != nil && (input.Id == nil || *p.Id != *input.Id) { return false } From 46229a4cc206fc42361e25bb7f7f3653928aa0d4 Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Thu, 8 Dec 2022 10:38:39 +0800 Subject: [PATCH 17/35] acc test --- .../extended_location_custom_locations_test.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/internal/services/extendedlocation/extended_location_custom_locations_test.go b/internal/services/extendedlocation/extended_location_custom_locations_test.go index 3fc79c6a061a..2bf5fb9a35a9 100644 --- a/internal/services/extendedlocation/extended_location_custom_locations_test.go +++ b/internal/services/extendedlocation/extended_location_custom_locations_test.go @@ -51,6 +51,12 @@ func (r CustomLocationResource) basic(data acceptance.TestData) string { return fmt.Sprintf(` %s +resource "azurerm_role_assignment" "admin" { + scope = azurerm_kubernetes_cluster.test.id + role_definition_name = "Azure Kubernetes Service RBAC Cluster Admin" + principal_id = "51dfe1e8-70c6-4de5-a08e-e18aff23d815" +} + resource "azurerm_extended_custom_locations" "test" { name = "acctestcustomlocation%d" resource_group_name = azurerm_resource_group.test.name @@ -66,7 +72,7 @@ resource "azurerm_extended_custom_locations" "test" { } func (r CustomLocationResource) template(data acceptance.TestData) string { - data.Locations.Primary = "westus" + data.Locations.Primary = "westus2" return fmt.Sprintf(` provider "azurerm" { features {} From 1432bd6d9f1ded15f7cc6f927b43f28c56845283 Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Wed, 14 Jun 2023 14:12:00 +0800 Subject: [PATCH 18/35] extended location temp --- ...extended_location_custom_locations_test.go | 229 +++++++++++++++--- 1 file changed, 201 insertions(+), 28 deletions(-) diff --git a/internal/services/extendedlocation/extended_location_custom_locations_test.go b/internal/services/extendedlocation/extended_location_custom_locations_test.go index 2bf5fb9a35a9..5532b3cfa908 100644 --- a/internal/services/extendedlocation/extended_location_custom_locations_test.go +++ b/internal/services/extendedlocation/extended_location_custom_locations_test.go @@ -2,6 +2,11 @@ package extendedlocation_test import ( "context" + cryptoRand "crypto/rand" + "crypto/rsa" + "crypto/x509" + "encoding/base64" + "encoding/pem" "fmt" "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations" @@ -10,6 +15,8 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" + "math/rand" + "os" "testing" ) @@ -34,10 +41,15 @@ func (r CustomLocationResource) Exists(ctx context.Context, client *clients.Clie func TestAccExtendedLocationCustomLocations_basic(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_extended_custom_locations", "test") r := CustomLocationResource{} + credential := fmt.Sprintf("P@$$w0rd%d!", rand.Intn(10000)) + privateKey, publicKey, err := CustomLocationResource{}.generateKey() + if err != nil { + t.Fatalf("failed to generate key: %+v", err) + } data.ResourceTest(t, r, []acceptance.TestStep{ { - Config: r.basic(data), + Config: r.basic(data, credential, privateKey, publicKey), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), @@ -46,36 +58,40 @@ func TestAccExtendedLocationCustomLocations_basic(t *testing.T) { }) } -func (r CustomLocationResource) basic(data acceptance.TestData) string { - template := r.template(data) +func (r CustomLocationResource) basic(data acceptance.TestData, credential string, privateKey string, publicKey string) string { + template := r.template(data, credential, privateKey, publicKey) return fmt.Sprintf(` %s -resource "azurerm_role_assignment" "admin" { - scope = azurerm_kubernetes_cluster.test.id - role_definition_name = "Azure Kubernetes Service RBAC Cluster Admin" - principal_id = "51dfe1e8-70c6-4de5-a08e-e18aff23d815" -} +//resource "azurerm_role_assignment" "admin" { +// scope = azurerm_kubernetes_cluster.test.id +// role_definition_name = "Azure Kubernetes Service RBAC Cluster Admin" +// principal_id = "51dfe1e8-70c6-4de5-a08e-e18aff23d815" +//} resource "azurerm_extended_custom_locations" "test" { name = "acctestcustomlocation%d" resource_group_name = azurerm_resource_group.test.name location = azurerm_resource_group.test.location cluster_extension_ids = [ - "${azurerm_kubernetes_cluster.test.id}/providers/Microsoft.KubernetesConfiguration/extensions/foo" + "${azurerm_arc_kubernetes_cluster_extension.test.id}" ] display_name = "customlocation%[2]d" namespace = "namespace%[2]d" - host_resource_id = azurerm_kubernetes_cluster.test.id + host_resource_id = azurerm_arc_kubernetes_cluster.test.id } `, template, data.RandomInteger) } -func (r CustomLocationResource) template(data acceptance.TestData) string { - data.Locations.Primary = "westus2" +func (r CustomLocationResource) template(data acceptance.TestData, credential string, privateKey string, publicKey string) string { + data.Locations.Primary = "eastus" return fmt.Sprintf(` provider "azurerm" { - features {} + features { + resource_group { + prevent_deletion_if_contains_resources = false + } + } } resource "azurerm_resource_group" "test" { @@ -83,29 +99,186 @@ resource "azurerm_resource_group" "test" { location = "%[2]s" } -data "azurerm_extended_locations" "test" { - location = azurerm_resource_group.test.location +resource "azurerm_virtual_network" "test" { + name = "acctestnw-%[1]d" + address_space = ["10.0.0.0/16"] + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name } -resource "azurerm_kubernetes_cluster" "test" { - name = "acctestaks%[1]d" +resource "azurerm_subnet" "test" { + name = "internal" + resource_group_name = azurerm_resource_group.test.name + virtual_network_name = azurerm_virtual_network.test.name + address_prefixes = ["10.0.2.0/24"] +} + +resource "azurerm_public_ip" "test" { + name = "acctestpip-%[1]d" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + allocation_method = "Static" +} + +resource "azurerm_network_interface" "test" { + name = "acctestnic-%[1]d" location = azurerm_resource_group.test.location resource_group_name = azurerm_resource_group.test.name - dns_prefix = "acctestaks%[1]d" - kubernetes_version = "1.24.3" - run_command_enabled = true - - default_node_pool { - name = "default" - node_count = 1 - vm_size = "Standard_ds2_v2" + ip_configuration { + name = "internal" + subnet_id = azurerm_subnet.test.id + private_ip_address_allocation = "Dynamic" + public_ip_address_id = azurerm_public_ip.test.id } +} + +resource "azurerm_network_security_group" "my_terraform_nsg" { + name = "myNetworkSecurityGroup" + location = azurerm_resource_group.test.location + resource_group_name = azurerm_resource_group.test.name + security_rule { + name = "SSH" + priority = 1001 + direction = "Inbound" + access = "Allow" + protocol = "Tcp" + source_port_range = "*" + destination_port_range = "22" + source_address_prefix = "*" + destination_address_prefix = "*" + } +} + +resource "azurerm_network_interface_security_group_association" "example" { + network_interface_id = azurerm_network_interface.test.id + network_security_group_id = azurerm_network_security_group.my_terraform_nsg.id +} + +resource "azurerm_linux_virtual_machine" "test" { + name = "acctestVM-%[1]d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + size = "Standard_F2" + admin_username = "adminuser" + admin_password = "%[3]s" + provision_vm_agent = false + allow_extension_operations = false + disable_password_authentication = false + network_interface_ids = [ + azurerm_network_interface.test.id, + ] + os_disk { + caching = "ReadWrite" + storage_account_type = "Standard_LRS" + } + source_image_reference { + publisher = "Canonical" + offer = "UbuntuServer" + sku = "18.04-LTS" + version = "latest" + } +} + +data "azurerm_extended_locations" "test" { + location = azurerm_resource_group.test.location +} + +resource "azurerm_arc_kubernetes_cluster" "test" { + name = "acctest-akcc-%[1]d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + agent_public_key_certificate = "%[4]s" identity { type = "SystemAssigned" } - tags = { - ENV = "Test1" + + %[5]s + + depends_on = [ + azurerm_linux_virtual_machine.test + ] +} + +resource "azurerm_arc_kubernetes_cluster_extension" "test" { + name = "foo" + cluster_id = azurerm_arc_kubernetes_cluster.test.id + extension_type = "microsoft.flux" + + identity { + type = "SystemAssigned" } + + depends_on = [ + azurerm_linux_virtual_machine.test + ] +} +`, data.RandomInteger, data.Locations.Primary, credential, publicKey, r.provisionTemplate(data, credential, privateKey)) +} + +func (r CustomLocationResource) generateKey() (string, string, error) { + privateKey, err := rsa.GenerateKey(cryptoRand.Reader, 4096) + if err != nil { + return "", "", fmt.Errorf("failed to generate RSA key") + } + + privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey) + privateKeyBlock := &pem.Block{ + Type: "RSA PRIVATE KEY", + Bytes: privateKeyBytes, + } + + privatePem := pem.EncodeToMemory(privateKeyBlock) + if privatePem == nil { + return "", "", fmt.Errorf("failed to encode pem") + } + + return string(privatePem), base64.StdEncoding.EncodeToString(x509.MarshalPKCS1PublicKey(&privateKey.PublicKey)), nil +} + +func (r CustomLocationResource) provisionTemplate(data acceptance.TestData, credential string, privateKey string) string { + return fmt.Sprintf(` +connection { + type = "ssh" + host = azurerm_public_ip.test.ip_address + user = "adminuser" + password = "%[1]s" +} + +provisioner "file" { + content = templatefile("testdata/install_agent.sh.tftpl", { + subscription_id = "%[4]s" + resource_group_name = azurerm_resource_group.test.name + cluster_name = "acctest-akcc-%[2]d" + location = azurerm_resource_group.test.location + tenant_id = "%[5]s" + working_dir = "%[3]s" + }) + destination = "%[3]s/install_agent.sh" +} + +provisioner "file" { + source = "testdata/install_agent.py" + destination = "%[3]s/install_agent.py" +} + +provisioner "file" { + source = "testdata/kind.yaml" + destination = "%[3]s/kind.yaml" +} + +provisioner "file" { + content = < %[3]s/agent_log", + ] } -`, data.RandomInteger, data.Locations.Primary) +`, credential, data.RandomInteger, "/home/adminuser", os.Getenv("ARM_SUBSCRIPTION_ID"), os.Getenv("ARM_TENANT_ID"), privateKey) } From a946e1d12e11a506319ebb14e6ac3451a91071da Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Mon, 26 Jun 2023 17:01:38 +0800 Subject: [PATCH 19/35] Fix test --- ...extended_location_custom_locations_test.go | 121 ++++++++---------- 1 file changed, 54 insertions(+), 67 deletions(-) diff --git a/internal/services/extendedlocation/extended_location_custom_locations_test.go b/internal/services/extendedlocation/extended_location_custom_locations_test.go index 5532b3cfa908..640a372253c6 100644 --- a/internal/services/extendedlocation/extended_location_custom_locations_test.go +++ b/internal/services/extendedlocation/extended_location_custom_locations_test.go @@ -16,7 +16,6 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" "math/rand" - "os" "testing" ) @@ -42,14 +41,14 @@ func TestAccExtendedLocationCustomLocations_basic(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_extended_custom_locations", "test") r := CustomLocationResource{} credential := fmt.Sprintf("P@$$w0rd%d!", rand.Intn(10000)) - privateKey, publicKey, err := CustomLocationResource{}.generateKey() + _, publicKey, err := CustomLocationResource{}.generateKey() if err != nil { t.Fatalf("failed to generate key: %+v", err) } data.ResourceTest(t, r, []acceptance.TestStep{ { - Config: r.basic(data, credential, privateKey, publicKey), + Config: r.basic(data, credential, publicKey), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), @@ -58,17 +57,11 @@ func TestAccExtendedLocationCustomLocations_basic(t *testing.T) { }) } -func (r CustomLocationResource) basic(data acceptance.TestData, credential string, privateKey string, publicKey string) string { - template := r.template(data, credential, privateKey, publicKey) +func (r CustomLocationResource) basic(data acceptance.TestData, credential string, publicKey string) string { + template := r.template(data, credential, publicKey) return fmt.Sprintf(` %s -//resource "azurerm_role_assignment" "admin" { -// scope = azurerm_kubernetes_cluster.test.id -// role_definition_name = "Azure Kubernetes Service RBAC Cluster Admin" -// principal_id = "51dfe1e8-70c6-4de5-a08e-e18aff23d815" -//} - resource "azurerm_extended_custom_locations" "test" { name = "acctestcustomlocation%d" resource_group_name = azurerm_resource_group.test.name @@ -83,7 +76,7 @@ resource "azurerm_extended_custom_locations" "test" { `, template, data.RandomInteger) } -func (r CustomLocationResource) template(data acceptance.TestData, credential string, privateKey string, publicKey string) string { +func (r CustomLocationResource) template(data acceptance.TestData, credential string, publicKey string) string { data.Locations.Primary = "eastus" return fmt.Sprintf(` provider "azurerm" { @@ -179,10 +172,6 @@ resource "azurerm_linux_virtual_machine" "test" { } } -data "azurerm_extended_locations" "test" { - location = azurerm_resource_group.test.location -} - resource "azurerm_arc_kubernetes_cluster" "test" { name = "acctest-akcc-%[1]d" resource_group_name = azurerm_resource_group.test.name @@ -192,8 +181,6 @@ resource "azurerm_arc_kubernetes_cluster" "test" { type = "SystemAssigned" } - %[5]s - depends_on = [ azurerm_linux_virtual_machine.test ] @@ -202,7 +189,7 @@ resource "azurerm_arc_kubernetes_cluster" "test" { resource "azurerm_arc_kubernetes_cluster_extension" "test" { name = "foo" cluster_id = azurerm_arc_kubernetes_cluster.test.id - extension_type = "microsoft.flux" + extension_type = "microsoft.azuredefender.kubernetes" identity { type = "SystemAssigned" @@ -212,7 +199,7 @@ resource "azurerm_arc_kubernetes_cluster_extension" "test" { azurerm_linux_virtual_machine.test ] } -`, data.RandomInteger, data.Locations.Primary, credential, publicKey, r.provisionTemplate(data, credential, privateKey)) +`, data.RandomInteger, data.Locations.Primary, credential, publicKey) } func (r CustomLocationResource) generateKey() (string, string, error) { @@ -235,50 +222,50 @@ func (r CustomLocationResource) generateKey() (string, string, error) { return string(privatePem), base64.StdEncoding.EncodeToString(x509.MarshalPKCS1PublicKey(&privateKey.PublicKey)), nil } -func (r CustomLocationResource) provisionTemplate(data acceptance.TestData, credential string, privateKey string) string { - return fmt.Sprintf(` -connection { - type = "ssh" - host = azurerm_public_ip.test.ip_address - user = "adminuser" - password = "%[1]s" -} - -provisioner "file" { - content = templatefile("testdata/install_agent.sh.tftpl", { - subscription_id = "%[4]s" - resource_group_name = azurerm_resource_group.test.name - cluster_name = "acctest-akcc-%[2]d" - location = azurerm_resource_group.test.location - tenant_id = "%[5]s" - working_dir = "%[3]s" - }) - destination = "%[3]s/install_agent.sh" -} - -provisioner "file" { - source = "testdata/install_agent.py" - destination = "%[3]s/install_agent.py" -} - -provisioner "file" { - source = "testdata/kind.yaml" - destination = "%[3]s/kind.yaml" -} - -provisioner "file" { - content = < %[3]s/agent_log", - ] -} -`, credential, data.RandomInteger, "/home/adminuser", os.Getenv("ARM_SUBSCRIPTION_ID"), os.Getenv("ARM_TENANT_ID"), privateKey) -} +//func (r CustomLocationResource) provisionTemplate(data acceptance.TestData, credential string, privateKey string) string { +// return fmt.Sprintf(` +//connection { +// type = "ssh" +// host = azurerm_public_ip.test.ip_address +// user = "adminuser" +// password = "%[1]s" +//} +// +//provisioner "file" { +// content = templatefile("testdata/install_agent.sh.tftpl", { +// subscription_id = "%[4]s" +// resource_group_name = azurerm_resource_group.test.name +// cluster_name = "acctest-akcc-%[2]d" +// location = azurerm_resource_group.test.location +// tenant_id = "%[5]s" +// working_dir = "%[3]s" +// }) +// destination = "%[3]s/install_agent.sh" +//} +// +//provisioner "file" { +// source = "testdata/install_agent.py" +// destination = "%[3]s/install_agent.py" +//} +// +//provisioner "file" { +// source = "testdata/kind.yaml" +// destination = "%[3]s/kind.yaml" +//} +// +//provisioner "file" { +// content = < %[3]s/agent_log", +// ] +//} +//`, credential, data.RandomInteger, "/home/adminuser", os.Getenv("ARM_SUBSCRIPTION_ID"), os.Getenv("ARM_TENANT_ID"), privateKey) +//} From 01709e62f720a3c76ba438e1a2300552aaa7ac85 Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Thu, 19 Oct 2023 10:35:40 +0800 Subject: [PATCH 20/35] Update acc test --- ...extended_location_custom_locations_test.go | 148 ++++++++++-------- 1 file changed, 87 insertions(+), 61 deletions(-) diff --git a/internal/services/extendedlocation/extended_location_custom_locations_test.go b/internal/services/extendedlocation/extended_location_custom_locations_test.go index 640a372253c6..3364c093966b 100644 --- a/internal/services/extendedlocation/extended_location_custom_locations_test.go +++ b/internal/services/extendedlocation/extended_location_custom_locations_test.go @@ -10,12 +10,14 @@ import ( "fmt" "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" "math/rand" + "os" "testing" ) @@ -40,15 +42,11 @@ func (r CustomLocationResource) Exists(ctx context.Context, client *clients.Clie func TestAccExtendedLocationCustomLocations_basic(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_extended_custom_locations", "test") r := CustomLocationResource{} - credential := fmt.Sprintf("P@$$w0rd%d!", rand.Intn(10000)) - _, publicKey, err := CustomLocationResource{}.generateKey() - if err != nil { - t.Fatalf("failed to generate key: %+v", err) - } + credential, privateKey, publicKey := r.getCredentials(t) data.ResourceTest(t, r, []acceptance.TestStep{ { - Config: r.basic(data, credential, publicKey), + Config: r.basic(data, credential, privateKey, publicKey), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), @@ -57,8 +55,8 @@ func TestAccExtendedLocationCustomLocations_basic(t *testing.T) { }) } -func (r CustomLocationResource) basic(data acceptance.TestData, credential string, publicKey string) string { - template := r.template(data, credential, publicKey) +func (r CustomLocationResource) basic(data acceptance.TestData, credential string, privateKey string, publicKey string) string { + template := r.template(data, credential, publicKey, privateKey) return fmt.Sprintf(` %s @@ -76,8 +74,9 @@ resource "azurerm_extended_custom_locations" "test" { `, template, data.RandomInteger) } -func (r CustomLocationResource) template(data acceptance.TestData, credential string, publicKey string) string { +func (r CustomLocationResource) template(data acceptance.TestData, credential string, publicKey string, privateKey string) string { data.Locations.Primary = "eastus" + provisionTemplate := r.provisionTemplate(data, credential, privateKey) return fmt.Sprintf(` provider "azurerm" { features { @@ -181,25 +180,37 @@ resource "azurerm_arc_kubernetes_cluster" "test" { type = "SystemAssigned" } + %[5]s + depends_on = [ azurerm_linux_virtual_machine.test ] } resource "azurerm_arc_kubernetes_cluster_extension" "test" { - name = "foo" + name = "acctest-kce-%[1]d" cluster_id = azurerm_arc_kubernetes_cluster.test.id - extension_type = "microsoft.azuredefender.kubernetes" + extension_type = "microsoft.flux" + version = "1.6.3" + release_namespace = "flux-system" + + configuration_protected_settings = { + "omsagent.secret.key" = "secretKeyValue2" + } + + configuration_settings = { + "omsagent.env.clusterName" = "clusterName2" + } identity { - type = "SystemAssigned" + type = "SystemAssigned" } depends_on = [ - azurerm_linux_virtual_machine.test + azurerm_linux_virtual_machine.test ] } -`, data.RandomInteger, data.Locations.Primary, credential, publicKey) +`, data.RandomInteger, data.Locations.Primary, credential, publicKey, provisionTemplate) } func (r CustomLocationResource) generateKey() (string, string, error) { @@ -222,50 +233,65 @@ func (r CustomLocationResource) generateKey() (string, string, error) { return string(privatePem), base64.StdEncoding.EncodeToString(x509.MarshalPKCS1PublicKey(&privateKey.PublicKey)), nil } -//func (r CustomLocationResource) provisionTemplate(data acceptance.TestData, credential string, privateKey string) string { -// return fmt.Sprintf(` -//connection { -// type = "ssh" -// host = azurerm_public_ip.test.ip_address -// user = "adminuser" -// password = "%[1]s" -//} -// -//provisioner "file" { -// content = templatefile("testdata/install_agent.sh.tftpl", { -// subscription_id = "%[4]s" -// resource_group_name = azurerm_resource_group.test.name -// cluster_name = "acctest-akcc-%[2]d" -// location = azurerm_resource_group.test.location -// tenant_id = "%[5]s" -// working_dir = "%[3]s" -// }) -// destination = "%[3]s/install_agent.sh" -//} -// -//provisioner "file" { -// source = "testdata/install_agent.py" -// destination = "%[3]s/install_agent.py" -//} -// -//provisioner "file" { -// source = "testdata/kind.yaml" -// destination = "%[3]s/kind.yaml" -//} -// -//provisioner "file" { -// content = < %[3]s/agent_log", -// ] -//} -//`, credential, data.RandomInteger, "/home/adminuser", os.Getenv("ARM_SUBSCRIPTION_ID"), os.Getenv("ARM_TENANT_ID"), privateKey) -//} +func (r CustomLocationResource) getCredentials(t *testing.T) (credential, privateKey, publicKey string) { + // generateKey() is a time-consuming operation, we only run this test if an env var is set. + if os.Getenv(resource.EnvTfAcc) == "" { + t.Skipf("Acceptance tests skipped unless env '%s' set", resource.EnvTfAcc) + } + + credential = fmt.Sprintf("P@$$w0rd%d!", rand.Intn(10000)) + privateKey, publicKey, err := r.generateKey() + if err != nil { + t.Fatalf("failed to generate key: %+v", err) + } + + return +} + +func (r CustomLocationResource) provisionTemplate(data acceptance.TestData, credential string, privateKey string) string { + return fmt.Sprintf(` +connection { + type = "ssh" + host = azurerm_public_ip.test.ip_address + user = "adminuser" + password = "%[1]s" +} + +provisioner "file" { + content = templatefile("testdata/install_agent.sh.tftpl", { + subscription_id = "%[4]s" + resource_group_name = azurerm_resource_group.test.name + cluster_name = "acctest-akcc-%[2]d" + location = azurerm_resource_group.test.location + tenant_id = "%[5]s" + working_dir = "%[3]s" + }) + destination = "%[3]s/install_agent.sh" +} + +provisioner "file" { + source = "testdata/install_agent.py" + destination = "%[3]s/install_agent.py" +} + +provisioner "file" { + source = "testdata/kind.yaml" + destination = "%[3]s/kind.yaml" +} + +provisioner "file" { + content = < %[3]s/agent_log", + ] +} +`, credential, data.RandomInteger, "/home/adminuser", os.Getenv("ARM_SUBSCRIPTION_ID"), os.Getenv("ARM_TENANT_ID"), privateKey) +} From 6fc7e352c7e8fa0b88875598c9c9f44ed05d74bf Mon Sep 17 00:00:00 2001 From: jiawei Date: Fri, 20 Oct 2023 07:47:06 +0000 Subject: [PATCH 21/35] Update extension type --- .../extended_location_custom_locations_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/services/extendedlocation/extended_location_custom_locations_test.go b/internal/services/extendedlocation/extended_location_custom_locations_test.go index 3364c093966b..9c02bd1b5508 100644 --- a/internal/services/extendedlocation/extended_location_custom_locations_test.go +++ b/internal/services/extendedlocation/extended_location_custom_locations_test.go @@ -190,9 +190,7 @@ resource "azurerm_arc_kubernetes_cluster" "test" { resource "azurerm_arc_kubernetes_cluster_extension" "test" { name = "acctest-kce-%[1]d" cluster_id = azurerm_arc_kubernetes_cluster.test.id - extension_type = "microsoft.flux" - version = "1.6.3" - release_namespace = "flux-system" + extension_type = "Microsoft.Web.Appservice" configuration_protected_settings = { "omsagent.secret.key" = "secretKeyValue2" From aeec103c7c007f9603c3d560ccbb0db06223fed1 Mon Sep 17 00:00:00 2001 From: jiawei Date: Fri, 15 Dec 2023 03:57:32 +0000 Subject: [PATCH 22/35] update test ext --- .../extended_location_custom_locations_test.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/internal/services/extendedlocation/extended_location_custom_locations_test.go b/internal/services/extendedlocation/extended_location_custom_locations_test.go index 9c02bd1b5508..08475ec4dfd8 100644 --- a/internal/services/extendedlocation/extended_location_custom_locations_test.go +++ b/internal/services/extendedlocation/extended_location_custom_locations_test.go @@ -190,14 +190,12 @@ resource "azurerm_arc_kubernetes_cluster" "test" { resource "azurerm_arc_kubernetes_cluster_extension" "test" { name = "acctest-kce-%[1]d" cluster_id = azurerm_arc_kubernetes_cluster.test.id - extension_type = "Microsoft.Web.Appservice" - - configuration_protected_settings = { - "omsagent.secret.key" = "secretKeyValue2" - } + extension_type = "microsoft.contoso.clusters" + target_namespace = "tf-ns4" + version = "1.2.0" configuration_settings = { - "omsagent.env.clusterName" = "clusterName2" + "Microsoft.CustomLocation.ServiceAccount" = "tf-operator" } identity { From 7ef1c9dcd51db2e2acaecaa8918ab5e4d5eeab9b Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Mon, 18 Dec 2023 16:58:38 +0800 Subject: [PATCH 23/35] New Resource: azurerm_extended_location_custom_location --- internal/clients/client.go | 4 - .../extended_location_custom_locations.go | 326 ------------------ ...extended_location_custom_locations_test.go | 293 ---------------- .../customlocations/id_customlocation.go | 2 +- .../method_createorupdate_autorest.go | 79 ----- .../customlocations/method_delete_autorest.go | 78 ----- .../customlocations/method_get_autorest.go | 68 ---- .../method_listbyresourcegroup_autorest.go | 187 ---------- .../method_listbysubscription_autorest.go | 187 ---------- ...ethod_listenabledresourcetypes_autorest.go | 186 ---------- .../customlocations/method_update_autorest.go | 69 ---- .../2021-08-15/customlocations/predicates.go | 2 - 12 files changed, 1 insertion(+), 1480 deletions(-) delete mode 100644 internal/services/extendedlocation/extended_location_custom_locations.go delete mode 100644 internal/services/extendedlocation/extended_location_custom_locations_test.go delete mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_createorupdate_autorest.go delete mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_delete_autorest.go delete mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_get_autorest.go delete mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listbyresourcegroup_autorest.go delete mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listbysubscription_autorest.go delete mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listenabledresourcetypes_autorest.go delete mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_update_autorest.go diff --git a/internal/clients/client.go b/internal/clients/client.go index 2949e562c457..67569e66b8e0 100644 --- a/internal/clients/client.go +++ b/internal/clients/client.go @@ -448,13 +448,9 @@ func (client *Client) Build(ctx context.Context, o *common.ClientOptions) error if client.Eventhub, err = eventhub.NewClient(o); err != nil { return fmt.Errorf("building clients for Eventhub: %+v", err) } -<<<<<<< HEAD if client.ExtendedLocation, err = extendedlocation.NewClient(o); err != nil { return fmt.Errorf("building clients for ExtendedLocation: %+v", err) } -======= - client.ExtendedLocation = extendedlocation.NewClient(o) ->>>>>>> d9fd896b83 (temp) if client.FluidRelay, err = fluidrelay.NewClient(o); err != nil { return fmt.Errorf("building clients for FluidRelay: %+v", err) } diff --git a/internal/services/extendedlocation/extended_location_custom_locations.go b/internal/services/extendedlocation/extended_location_custom_locations.go deleted file mode 100644 index daae919ef0ae..000000000000 --- a/internal/services/extendedlocation/extended_location_custom_locations.go +++ /dev/null @@ -1,326 +0,0 @@ -package extendedlocation - -import ( - "context" - "fmt" - "time" - - "github.com/hashicorp/go-azure-helpers/lang/response" - "github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" - "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" - "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" - "github.com/hashicorp/terraform-provider-azurerm/utils" -) - -type CustomLocationResource struct{} - -type CustomLocationResourceModel struct { - Name string `tfschema:"name"` - ResourceGroupName string `tfschema:"resource_group_name"` - Location string `tfschema:"location"` - AuthenticationType string `tfschema:"authentication_type"` - AuthenticationValue string `tfschema:"authentication_value"` - ClusterExtensionIds []string `tfschema:"cluster_extension_ids"` - DisplayName string `tfschema:"display_name"` - HostResourceId string `tfschema:"host_resource_id"` - HostType string `tfschema:"host_type"` - Namespace string `tfschema:"namespace"` -} - -func (r CustomLocationResource) Arguments() map[string]*schema.Schema { - return map[string]*schema.Schema{ - "name": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringIsNotEmpty, - }, - - "resource_group_name": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringIsNotEmpty, - }, - - "location": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringIsNotEmpty, - }, - - "cluster_extension_ids": { - Type: pluginsdk.TypeList, - Required: true, - Elem: &pluginsdk.Schema{ - Type: pluginsdk.TypeString, - }, - }, - - "host_resource_id": { - Type: pluginsdk.TypeString, - Required: true, - ValidateFunc: validation.StringIsNotEmpty, - }, - - "authentication_type": { - Type: pluginsdk.TypeString, - Optional: true, - ValidateFunc: validation.StringIsNotEmpty, - }, - - "authentication_value": { - Type: pluginsdk.TypeString, - Optional: true, - ValidateFunc: validation.StringIsNotEmpty, - }, - - "display_name": { - Type: pluginsdk.TypeString, - Optional: true, - ValidateFunc: validation.StringIsNotEmpty, - }, - - "host_type": { - Type: pluginsdk.TypeString, - Optional: true, - ValidateFunc: validation.StringInSlice([]string{ - string(customlocations.HostTypeKubernetes), - }, false), - }, - - "namespace": { - Type: pluginsdk.TypeString, - Optional: true, - ValidateFunc: validation.StringIsNotEmpty, - }, - } -} - -func (r CustomLocationResource) Attributes() map[string]*schema.Schema { - return map[string]*schema.Schema{} -} - -func (r CustomLocationResource) ModelObject() interface{} { - return &CustomLocationResourceModel{} -} - -func (r CustomLocationResource) ResourceType() string { - return "azurerm_extended_custom_locations" -} - -func (r CustomLocationResource) Create() sdk.ResourceFunc { - return sdk.ResourceFunc{ - Timeout: 30 * time.Minute, - Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { - var model CustomLocationResourceModel - if err := metadata.Decode(&model); err != nil { - return err - } - - subscriptionId := metadata.Client.Account.SubscriptionId - client := metadata.Client.ExtendedLocation.CustomLocationsClient - - id := customlocations.NewCustomLocationID(subscriptionId, model.ResourceGroupName, model.Name) - existing, err := client.Get(ctx, id) - if err != nil && !response.WasNotFound(existing.HttpResponse) { - return fmt.Errorf("checking for presence of existing %s: %+v", id, err) - } - - if !response.WasNotFound(existing.HttpResponse) { - return metadata.ResourceRequiresImport(r.ResourceType(), id) - } - - customLocationProps := customlocations.CustomLocationProperties{} - - if model.AuthenticationValue != "" && model.AuthenticationType != "" { - customLocationProps.Authentication = &customlocations.CustomLocationPropertiesAuthentication{ - Type: &model.AuthenticationType, - Value: &model.AuthenticationValue, - } - } - - if model.ClusterExtensionIds != nil { - customLocationProps.ClusterExtensionIds = &model.ClusterExtensionIds - } - - if model.DisplayName != "" { - customLocationProps.DisplayName = &model.DisplayName - } - - if model.HostResourceId != "" { - customLocationProps.HostResourceId = &model.HostResourceId - } - - if model.HostType != "" { - hostType := customlocations.HostType(model.HostType) - customLocationProps.HostType = &hostType - } - - if model.Namespace != "" { - customLocationProps.Namespace = &model.Namespace - } - - props := customlocations.CustomLocation{ - Id: utils.String(id.ID()), - Location: model.Location, - Name: utils.String(model.Name), - Properties: &customLocationProps, - } - - if err := client.CreateOrUpdateThenPoll(ctx, id, props); err != nil { - return fmt.Errorf("creating %s: %+v", id, err) - } - - metadata.SetID(id) - return nil - }, - } -} - -func (r CustomLocationResource) Read() sdk.ResourceFunc { - return sdk.ResourceFunc{ - Timeout: 5 * time.Minute, - Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { - client := metadata.Client.ExtendedLocation.CustomLocationsClient - id, err := customlocations.ParseCustomLocationID(metadata.ResourceData.Id()) - if err != nil { - return err - } - - resp, err := client.Get(ctx, *id) - if err != nil { - if response.WasNotFound(resp.HttpResponse) { - return metadata.MarkAsGone(id) - } - return fmt.Errorf("reading %s: %+v", *id, err) - } - - if model := resp.Model; model != nil { - props := model.Properties - - state := CustomLocationResourceModel{ - Name: id.CustomLocationName, - ResourceGroupName: id.ResourceGroupName, - Location: model.Location, - } - - if props.Authentication != nil && props.Authentication.Type != nil && props.Authentication.Value != nil { - state.AuthenticationType = *props.Authentication.Type - state.AuthenticationValue = *props.Authentication.Value - } - - if props.ClusterExtensionIds != nil { - state.ClusterExtensionIds = *props.ClusterExtensionIds - } - - if props.DisplayName != nil { - state.DisplayName = *props.DisplayName - } - - if props.HostResourceId != nil { - state.HostResourceId = *props.HostResourceId - } - - if props.HostType != nil { - state.HostType = string(*props.HostType) - } - - if props.Namespace != nil { - state.Namespace = *props.Namespace - } - - return metadata.Encode(&state) - } - return nil - }, - } -} - -func (r CustomLocationResource) Delete() sdk.ResourceFunc { - return sdk.ResourceFunc{ - Timeout: 30 * time.Minute, - Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { - client := metadata.Client.ExtendedLocation.CustomLocationsClient - id, err := customlocations.ParseCustomLocationID(metadata.ResourceData.Id()) - if err != nil { - return err - } - - metadata.Logger.Infof("deleting %s", *id) - - if resp, err := client.Delete(ctx, *id); err != nil { - if !response.WasNotFound(resp.HttpResponse) { - return fmt.Errorf("deleting %s: %+v", *id, err) - } - } - - return nil - }, - } -} - -func (r CustomLocationResource) Update() sdk.ResourceFunc { - return sdk.ResourceFunc{ - Timeout: 30 * time.Minute, - Func: func(ctx context.Context, metadata sdk.ResourceMetaData) error { - client := metadata.Client.ExtendedLocation.CustomLocationsClient - id, err := customlocations.ParseCustomLocationID(metadata.ResourceData.Id()) - if err != nil { - return err - } - - var state CustomLocationResourceModel - if err := metadata.Decode(&state); err != nil { - return fmt.Errorf("decoding %+v", err) - } - - customLocationProps := customlocations.CustomLocationProperties{} - d := metadata.ResourceData - - if d.HasChanges("authentication_type", "authentication_value") { - customLocationProps.Authentication = &customlocations.CustomLocationPropertiesAuthentication{ - Type: &state.AuthenticationType, - Value: &state.AuthenticationValue, - } - } - - if d.HasChange("cluster_extension_ids") { - customLocationProps.ClusterExtensionIds = &state.ClusterExtensionIds - } - - if d.HasChange("display_name") { - customLocationProps.DisplayName = &state.DisplayName - } - - if d.HasChange("host_resource_id") { - customLocationProps.HostResourceId = &state.HostResourceId - } - - if d.HasChange("host_type") { - hostType := customlocations.HostType(state.HostType) - customLocationProps.HostType = &hostType - } - - if d.HasChange("namespace") { - customLocationProps.Namespace = &state.Namespace - } - - props := customlocations.PatchableCustomLocations{ - Properties: &customLocationProps, - } - - if _, err := client.Update(ctx, *id, props); err != nil { - return fmt.Errorf("updating %s: %+v", *id, err) - } - return nil - }, - } -} - -func (r CustomLocationResource) IDValidationFunc() pluginsdk.SchemaValidateFunc { - return customlocations.ValidateCustomLocationID -} diff --git a/internal/services/extendedlocation/extended_location_custom_locations_test.go b/internal/services/extendedlocation/extended_location_custom_locations_test.go deleted file mode 100644 index 08475ec4dfd8..000000000000 --- a/internal/services/extendedlocation/extended_location_custom_locations_test.go +++ /dev/null @@ -1,293 +0,0 @@ -package extendedlocation_test - -import ( - "context" - cryptoRand "crypto/rand" - "crypto/rsa" - "crypto/x509" - "encoding/base64" - "encoding/pem" - "fmt" - "github.com/hashicorp/go-azure-helpers/lang/response" - "github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations" - "github.com/hashicorp/terraform-plugin-testing/helper/resource" - "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" - "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" - "github.com/hashicorp/terraform-provider-azurerm/internal/clients" - "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" - "github.com/hashicorp/terraform-provider-azurerm/utils" - "math/rand" - "os" - "testing" -) - -type CustomLocationResource struct{} - -func (r CustomLocationResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := customlocations.ParseCustomLocationID(state.ID) - if err != nil { - return nil, err - } - - resp, err := client.ExtendedLocation.CustomLocationsClient.Get(ctx, *id) - if err != nil { - if response.WasNotFound(resp.HttpResponse) { - return utils.Bool(false), nil - } - return nil, fmt.Errorf("retrieving %s: %+v", *id, err) - } - return utils.Bool(true), nil -} - -func TestAccExtendedLocationCustomLocations_basic(t *testing.T) { - data := acceptance.BuildTestData(t, "azurerm_extended_custom_locations", "test") - r := CustomLocationResource{} - credential, privateKey, publicKey := r.getCredentials(t) - - data.ResourceTest(t, r, []acceptance.TestStep{ - { - Config: r.basic(data, credential, privateKey, publicKey), - Check: acceptance.ComposeTestCheckFunc( - check.That(data.ResourceName).ExistsInAzure(r), - ), - }, - data.ImportStep(), - }) -} - -func (r CustomLocationResource) basic(data acceptance.TestData, credential string, privateKey string, publicKey string) string { - template := r.template(data, credential, publicKey, privateKey) - return fmt.Sprintf(` -%s - -resource "azurerm_extended_custom_locations" "test" { - name = "acctestcustomlocation%d" - resource_group_name = azurerm_resource_group.test.name - location = azurerm_resource_group.test.location - cluster_extension_ids = [ - "${azurerm_arc_kubernetes_cluster_extension.test.id}" - ] - display_name = "customlocation%[2]d" - namespace = "namespace%[2]d" - host_resource_id = azurerm_arc_kubernetes_cluster.test.id -} -`, template, data.RandomInteger) -} - -func (r CustomLocationResource) template(data acceptance.TestData, credential string, publicKey string, privateKey string) string { - data.Locations.Primary = "eastus" - provisionTemplate := r.provisionTemplate(data, credential, privateKey) - return fmt.Sprintf(` -provider "azurerm" { - features { - resource_group { - prevent_deletion_if_contains_resources = false - } - } -} - -resource "azurerm_resource_group" "test" { - name = "acctestRG-%[1]d" - location = "%[2]s" -} - -resource "azurerm_virtual_network" "test" { - name = "acctestnw-%[1]d" - address_space = ["10.0.0.0/16"] - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name -} - -resource "azurerm_subnet" "test" { - name = "internal" - resource_group_name = azurerm_resource_group.test.name - virtual_network_name = azurerm_virtual_network.test.name - address_prefixes = ["10.0.2.0/24"] -} - -resource "azurerm_public_ip" "test" { - name = "acctestpip-%[1]d" - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name - allocation_method = "Static" -} - -resource "azurerm_network_interface" "test" { - name = "acctestnic-%[1]d" - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name - ip_configuration { - name = "internal" - subnet_id = azurerm_subnet.test.id - private_ip_address_allocation = "Dynamic" - public_ip_address_id = azurerm_public_ip.test.id - } -} - -resource "azurerm_network_security_group" "my_terraform_nsg" { - name = "myNetworkSecurityGroup" - location = azurerm_resource_group.test.location - resource_group_name = azurerm_resource_group.test.name - security_rule { - name = "SSH" - priority = 1001 - direction = "Inbound" - access = "Allow" - protocol = "Tcp" - source_port_range = "*" - destination_port_range = "22" - source_address_prefix = "*" - destination_address_prefix = "*" - } -} - -resource "azurerm_network_interface_security_group_association" "example" { - network_interface_id = azurerm_network_interface.test.id - network_security_group_id = azurerm_network_security_group.my_terraform_nsg.id -} - -resource "azurerm_linux_virtual_machine" "test" { - name = "acctestVM-%[1]d" - resource_group_name = azurerm_resource_group.test.name - location = azurerm_resource_group.test.location - size = "Standard_F2" - admin_username = "adminuser" - admin_password = "%[3]s" - provision_vm_agent = false - allow_extension_operations = false - disable_password_authentication = false - network_interface_ids = [ - azurerm_network_interface.test.id, - ] - os_disk { - caching = "ReadWrite" - storage_account_type = "Standard_LRS" - } - source_image_reference { - publisher = "Canonical" - offer = "UbuntuServer" - sku = "18.04-LTS" - version = "latest" - } -} - -resource "azurerm_arc_kubernetes_cluster" "test" { - name = "acctest-akcc-%[1]d" - resource_group_name = azurerm_resource_group.test.name - location = azurerm_resource_group.test.location - agent_public_key_certificate = "%[4]s" - identity { - type = "SystemAssigned" - } - - %[5]s - - depends_on = [ - azurerm_linux_virtual_machine.test - ] -} - -resource "azurerm_arc_kubernetes_cluster_extension" "test" { - name = "acctest-kce-%[1]d" - cluster_id = azurerm_arc_kubernetes_cluster.test.id - extension_type = "microsoft.contoso.clusters" - target_namespace = "tf-ns4" - version = "1.2.0" - - configuration_settings = { - "Microsoft.CustomLocation.ServiceAccount" = "tf-operator" - } - - identity { - type = "SystemAssigned" - } - - depends_on = [ - azurerm_linux_virtual_machine.test - ] -} -`, data.RandomInteger, data.Locations.Primary, credential, publicKey, provisionTemplate) -} - -func (r CustomLocationResource) generateKey() (string, string, error) { - privateKey, err := rsa.GenerateKey(cryptoRand.Reader, 4096) - if err != nil { - return "", "", fmt.Errorf("failed to generate RSA key") - } - - privateKeyBytes := x509.MarshalPKCS1PrivateKey(privateKey) - privateKeyBlock := &pem.Block{ - Type: "RSA PRIVATE KEY", - Bytes: privateKeyBytes, - } - - privatePem := pem.EncodeToMemory(privateKeyBlock) - if privatePem == nil { - return "", "", fmt.Errorf("failed to encode pem") - } - - return string(privatePem), base64.StdEncoding.EncodeToString(x509.MarshalPKCS1PublicKey(&privateKey.PublicKey)), nil -} - -func (r CustomLocationResource) getCredentials(t *testing.T) (credential, privateKey, publicKey string) { - // generateKey() is a time-consuming operation, we only run this test if an env var is set. - if os.Getenv(resource.EnvTfAcc) == "" { - t.Skipf("Acceptance tests skipped unless env '%s' set", resource.EnvTfAcc) - } - - credential = fmt.Sprintf("P@$$w0rd%d!", rand.Intn(10000)) - privateKey, publicKey, err := r.generateKey() - if err != nil { - t.Fatalf("failed to generate key: %+v", err) - } - - return -} - -func (r CustomLocationResource) provisionTemplate(data acceptance.TestData, credential string, privateKey string) string { - return fmt.Sprintf(` -connection { - type = "ssh" - host = azurerm_public_ip.test.ip_address - user = "adminuser" - password = "%[1]s" -} - -provisioner "file" { - content = templatefile("testdata/install_agent.sh.tftpl", { - subscription_id = "%[4]s" - resource_group_name = azurerm_resource_group.test.name - cluster_name = "acctest-akcc-%[2]d" - location = azurerm_resource_group.test.location - tenant_id = "%[5]s" - working_dir = "%[3]s" - }) - destination = "%[3]s/install_agent.sh" -} - -provisioner "file" { - source = "testdata/install_agent.py" - destination = "%[3]s/install_agent.py" -} - -provisioner "file" { - source = "testdata/kind.yaml" - destination = "%[3]s/kind.yaml" -} - -provisioner "file" { - content = < %[3]s/agent_log", - ] -} -`, credential, data.RandomInteger, "/home/adminuser", os.Getenv("ARM_SUBSCRIPTION_ID"), os.Getenv("ARM_TENANT_ID"), privateKey) -} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/id_customlocation.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/id_customlocation.go index e3e83251d840..cf34ecf941d7 100644 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/id_customlocation.go +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/id_customlocation.go @@ -114,7 +114,7 @@ func (id CustomLocationId) Segments() []resourceids.Segment { resourceids.StaticSegment("staticProviders", "providers", "providers"), resourceids.ResourceProviderSegment("staticMicrosoftExtendedLocation", "Microsoft.ExtendedLocation", "Microsoft.ExtendedLocation"), resourceids.StaticSegment("staticCustomLocations", "customLocations", "customLocations"), - resourceids.UserSpecifiedSegment("resourceName", "resourceValue"), + resourceids.UserSpecifiedSegment("customLocationName", "customLocationValue"), } } diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_createorupdate_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_createorupdate_autorest.go deleted file mode 100644 index f9b415ae1b04..000000000000 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_createorupdate_autorest.go +++ /dev/null @@ -1,79 +0,0 @@ -package customlocations - -import ( - "context" - "fmt" - "net/http" - - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/hashicorp/go-azure-helpers/polling" -) - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See NOTICE.txt in the project root for license information. - -type CreateOrUpdateOperationResponse struct { - Poller polling.LongRunningPoller - HttpResponse *http.Response -} - -// CreateOrUpdate ... -func (c CustomLocationsClient) CreateOrUpdate(ctx context.Context, id CustomLocationId, input CustomLocation) (result CreateOrUpdateOperationResponse, err error) { - req, err := c.preparerForCreateOrUpdate(ctx, id, input) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "CreateOrUpdate", nil, "Failure preparing request") - return - } - - result, err = c.senderForCreateOrUpdate(ctx, req) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "CreateOrUpdate", result.HttpResponse, "Failure sending request") - return - } - - return -} - -// CreateOrUpdateThenPoll performs CreateOrUpdate then polls until it's completed -func (c CustomLocationsClient) CreateOrUpdateThenPoll(ctx context.Context, id CustomLocationId, input CustomLocation) error { - result, err := c.CreateOrUpdate(ctx, id, input) - if err != nil { - return fmt.Errorf("performing CreateOrUpdate: %+v", err) - } - - if err := result.Poller.PollUntilDone(); err != nil { - return fmt.Errorf("polling after CreateOrUpdate: %+v", err) - } - - return nil -} - -// preparerForCreateOrUpdate prepares the CreateOrUpdate request. -func (c CustomLocationsClient) preparerForCreateOrUpdate(ctx context.Context, id CustomLocationId, input CustomLocation) (*http.Request, error) { - queryParameters := map[string]interface{}{ - "api-version": defaultApiVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsPut(), - autorest.WithBaseURL(c.baseUri), - autorest.WithPath(id.ID()), - autorest.WithJSON(input), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// senderForCreateOrUpdate sends the CreateOrUpdate request. The method will close the -// http.Response Body if it receives an error. -func (c CustomLocationsClient) senderForCreateOrUpdate(ctx context.Context, req *http.Request) (future CreateOrUpdateOperationResponse, err error) { - var resp *http.Response - resp, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) - if err != nil { - return - } - - future.Poller, err = polling.NewPollerFromResponse(ctx, resp, c.Client, req.Method) - return -} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_delete_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_delete_autorest.go deleted file mode 100644 index 5f71cda5e35c..000000000000 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_delete_autorest.go +++ /dev/null @@ -1,78 +0,0 @@ -package customlocations - -import ( - "context" - "fmt" - "net/http" - - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/hashicorp/go-azure-helpers/polling" -) - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See NOTICE.txt in the project root for license information. - -type DeleteOperationResponse struct { - Poller polling.LongRunningPoller - HttpResponse *http.Response -} - -// Delete ... -func (c CustomLocationsClient) Delete(ctx context.Context, id CustomLocationId) (result DeleteOperationResponse, err error) { - req, err := c.preparerForDelete(ctx, id) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "Delete", nil, "Failure preparing request") - return - } - - result, err = c.senderForDelete(ctx, req) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "Delete", result.HttpResponse, "Failure sending request") - return - } - - return -} - -// DeleteThenPoll performs Delete then polls until it's completed -func (c CustomLocationsClient) DeleteThenPoll(ctx context.Context, id CustomLocationId) error { - result, err := c.Delete(ctx, id) - if err != nil { - return fmt.Errorf("performing Delete: %+v", err) - } - - if err := result.Poller.PollUntilDone(); err != nil { - return fmt.Errorf("polling after Delete: %+v", err) - } - - return nil -} - -// preparerForDelete prepares the Delete request. -func (c CustomLocationsClient) preparerForDelete(ctx context.Context, id CustomLocationId) (*http.Request, error) { - queryParameters := map[string]interface{}{ - "api-version": defaultApiVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsDelete(), - autorest.WithBaseURL(c.baseUri), - autorest.WithPath(id.ID()), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// senderForDelete sends the Delete request. The method will close the -// http.Response Body if it receives an error. -func (c CustomLocationsClient) senderForDelete(ctx context.Context, req *http.Request) (future DeleteOperationResponse, err error) { - var resp *http.Response - resp, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) - if err != nil { - return - } - - future.Poller, err = polling.NewPollerFromResponse(ctx, resp, c.Client, req.Method) - return -} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_get_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_get_autorest.go deleted file mode 100644 index 475d52753db2..000000000000 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_get_autorest.go +++ /dev/null @@ -1,68 +0,0 @@ -package customlocations - -import ( - "context" - "net/http" - - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" -) - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See NOTICE.txt in the project root for license information. - -type GetOperationResponse struct { - HttpResponse *http.Response - Model *CustomLocation -} - -// Get ... -func (c CustomLocationsClient) Get(ctx context.Context, id CustomLocationId) (result GetOperationResponse, err error) { - req, err := c.preparerForGet(ctx, id) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "Get", nil, "Failure preparing request") - return - } - - result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "Get", result.HttpResponse, "Failure sending request") - return - } - - result, err = c.responderForGet(result.HttpResponse) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "Get", result.HttpResponse, "Failure responding to request") - return - } - - return -} - -// preparerForGet prepares the Get request. -func (c CustomLocationsClient) preparerForGet(ctx context.Context, id CustomLocationId) (*http.Request, error) { - queryParameters := map[string]interface{}{ - "api-version": defaultApiVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(c.baseUri), - autorest.WithPath(id.ID()), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// responderForGet handles the response to the Get request. The method always -// closes the http.Response Body. -func (c CustomLocationsClient) responderForGet(resp *http.Response) (result GetOperationResponse, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result.Model), - autorest.ByClosing()) - result.HttpResponse = resp - - return -} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listbyresourcegroup_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listbyresourcegroup_autorest.go deleted file mode 100644 index 5ed484831cd6..000000000000 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listbyresourcegroup_autorest.go +++ /dev/null @@ -1,187 +0,0 @@ -package customlocations - -import ( - "context" - "fmt" - "net/http" - "net/url" - - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" -) - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See NOTICE.txt in the project root for license information. - -type ListByResourceGroupOperationResponse struct { - HttpResponse *http.Response - Model *[]CustomLocation - - nextLink *string - nextPageFunc func(ctx context.Context, nextLink string) (ListByResourceGroupOperationResponse, error) -} - -type ListByResourceGroupCompleteResult struct { - Items []CustomLocation -} - -func (r ListByResourceGroupOperationResponse) HasMore() bool { - return r.nextLink != nil -} - -func (r ListByResourceGroupOperationResponse) LoadMore(ctx context.Context) (resp ListByResourceGroupOperationResponse, err error) { - if !r.HasMore() { - err = fmt.Errorf("no more pages returned") - return - } - return r.nextPageFunc(ctx, *r.nextLink) -} - -// ListByResourceGroup ... -func (c CustomLocationsClient) ListByResourceGroup(ctx context.Context, id commonids.ResourceGroupId) (resp ListByResourceGroupOperationResponse, err error) { - req, err := c.preparerForListByResourceGroup(ctx, id) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListByResourceGroup", nil, "Failure preparing request") - return - } - - resp.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListByResourceGroup", resp.HttpResponse, "Failure sending request") - return - } - - resp, err = c.responderForListByResourceGroup(resp.HttpResponse) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListByResourceGroup", resp.HttpResponse, "Failure responding to request") - return - } - return -} - -// preparerForListByResourceGroup prepares the ListByResourceGroup request. -func (c CustomLocationsClient) preparerForListByResourceGroup(ctx context.Context, id commonids.ResourceGroupId) (*http.Request, error) { - queryParameters := map[string]interface{}{ - "api-version": defaultApiVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(c.baseUri), - autorest.WithPath(fmt.Sprintf("%s/providers/Microsoft.ExtendedLocation/customLocations", id.ID())), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// preparerForListByResourceGroupWithNextLink prepares the ListByResourceGroup request with the given nextLink token. -func (c CustomLocationsClient) preparerForListByResourceGroupWithNextLink(ctx context.Context, nextLink string) (*http.Request, error) { - uri, err := url.Parse(nextLink) - if err != nil { - return nil, fmt.Errorf("parsing nextLink %q: %+v", nextLink, err) - } - queryParameters := map[string]interface{}{} - for k, v := range uri.Query() { - if len(v) == 0 { - continue - } - val := v[0] - val = autorest.Encode("query", val) - queryParameters[k] = val - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(c.baseUri), - autorest.WithPath(uri.Path), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// responderForListByResourceGroup handles the response to the ListByResourceGroup request. The method always -// closes the http.Response Body. -func (c CustomLocationsClient) responderForListByResourceGroup(resp *http.Response) (result ListByResourceGroupOperationResponse, err error) { - type page struct { - Values []CustomLocation `json:"value"` - NextLink *string `json:"nextLink"` - } - var respObj page - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&respObj), - autorest.ByClosing()) - result.HttpResponse = resp - result.Model = &respObj.Values - result.nextLink = respObj.NextLink - if respObj.NextLink != nil { - result.nextPageFunc = func(ctx context.Context, nextLink string) (result ListByResourceGroupOperationResponse, err error) { - req, err := c.preparerForListByResourceGroupWithNextLink(ctx, nextLink) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListByResourceGroup", nil, "Failure preparing request") - return - } - - result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListByResourceGroup", result.HttpResponse, "Failure sending request") - return - } - - result, err = c.responderForListByResourceGroup(result.HttpResponse) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListByResourceGroup", result.HttpResponse, "Failure responding to request") - return - } - - return - } - } - return -} - -// ListByResourceGroupComplete retrieves all of the results into a single object -func (c CustomLocationsClient) ListByResourceGroupComplete(ctx context.Context, id commonids.ResourceGroupId) (ListByResourceGroupCompleteResult, error) { - return c.ListByResourceGroupCompleteMatchingPredicate(ctx, id, CustomLocationOperationPredicate{}) -} - -// ListByResourceGroupCompleteMatchingPredicate retrieves all of the results and then applied the predicate -func (c CustomLocationsClient) ListByResourceGroupCompleteMatchingPredicate(ctx context.Context, id commonids.ResourceGroupId, predicate CustomLocationOperationPredicate) (resp ListByResourceGroupCompleteResult, err error) { - items := make([]CustomLocation, 0) - - page, err := c.ListByResourceGroup(ctx, id) - if err != nil { - err = fmt.Errorf("loading the initial page: %+v", err) - return - } - if page.Model != nil { - for _, v := range *page.Model { - if predicate.Matches(v) { - items = append(items, v) - } - } - } - - for page.HasMore() { - page, err = page.LoadMore(ctx) - if err != nil { - err = fmt.Errorf("loading the next page: %+v", err) - return - } - - if page.Model != nil { - for _, v := range *page.Model { - if predicate.Matches(v) { - items = append(items, v) - } - } - } - } - - out := ListByResourceGroupCompleteResult{ - Items: items, - } - return out, nil -} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listbysubscription_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listbysubscription_autorest.go deleted file mode 100644 index fed94c9df8be..000000000000 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listbysubscription_autorest.go +++ /dev/null @@ -1,187 +0,0 @@ -package customlocations - -import ( - "context" - "fmt" - "net/http" - "net/url" - - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" - "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" -) - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See NOTICE.txt in the project root for license information. - -type ListBySubscriptionOperationResponse struct { - HttpResponse *http.Response - Model *[]CustomLocation - - nextLink *string - nextPageFunc func(ctx context.Context, nextLink string) (ListBySubscriptionOperationResponse, error) -} - -type ListBySubscriptionCompleteResult struct { - Items []CustomLocation -} - -func (r ListBySubscriptionOperationResponse) HasMore() bool { - return r.nextLink != nil -} - -func (r ListBySubscriptionOperationResponse) LoadMore(ctx context.Context) (resp ListBySubscriptionOperationResponse, err error) { - if !r.HasMore() { - err = fmt.Errorf("no more pages returned") - return - } - return r.nextPageFunc(ctx, *r.nextLink) -} - -// ListBySubscription ... -func (c CustomLocationsClient) ListBySubscription(ctx context.Context, id commonids.SubscriptionId) (resp ListBySubscriptionOperationResponse, err error) { - req, err := c.preparerForListBySubscription(ctx, id) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListBySubscription", nil, "Failure preparing request") - return - } - - resp.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListBySubscription", resp.HttpResponse, "Failure sending request") - return - } - - resp, err = c.responderForListBySubscription(resp.HttpResponse) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListBySubscription", resp.HttpResponse, "Failure responding to request") - return - } - return -} - -// preparerForListBySubscription prepares the ListBySubscription request. -func (c CustomLocationsClient) preparerForListBySubscription(ctx context.Context, id commonids.SubscriptionId) (*http.Request, error) { - queryParameters := map[string]interface{}{ - "api-version": defaultApiVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(c.baseUri), - autorest.WithPath(fmt.Sprintf("%s/providers/Microsoft.ExtendedLocation/customLocations", id.ID())), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// preparerForListBySubscriptionWithNextLink prepares the ListBySubscription request with the given nextLink token. -func (c CustomLocationsClient) preparerForListBySubscriptionWithNextLink(ctx context.Context, nextLink string) (*http.Request, error) { - uri, err := url.Parse(nextLink) - if err != nil { - return nil, fmt.Errorf("parsing nextLink %q: %+v", nextLink, err) - } - queryParameters := map[string]interface{}{} - for k, v := range uri.Query() { - if len(v) == 0 { - continue - } - val := v[0] - val = autorest.Encode("query", val) - queryParameters[k] = val - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(c.baseUri), - autorest.WithPath(uri.Path), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// responderForListBySubscription handles the response to the ListBySubscription request. The method always -// closes the http.Response Body. -func (c CustomLocationsClient) responderForListBySubscription(resp *http.Response) (result ListBySubscriptionOperationResponse, err error) { - type page struct { - Values []CustomLocation `json:"value"` - NextLink *string `json:"nextLink"` - } - var respObj page - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&respObj), - autorest.ByClosing()) - result.HttpResponse = resp - result.Model = &respObj.Values - result.nextLink = respObj.NextLink - if respObj.NextLink != nil { - result.nextPageFunc = func(ctx context.Context, nextLink string) (result ListBySubscriptionOperationResponse, err error) { - req, err := c.preparerForListBySubscriptionWithNextLink(ctx, nextLink) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListBySubscription", nil, "Failure preparing request") - return - } - - result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListBySubscription", result.HttpResponse, "Failure sending request") - return - } - - result, err = c.responderForListBySubscription(result.HttpResponse) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListBySubscription", result.HttpResponse, "Failure responding to request") - return - } - - return - } - } - return -} - -// ListBySubscriptionComplete retrieves all of the results into a single object -func (c CustomLocationsClient) ListBySubscriptionComplete(ctx context.Context, id commonids.SubscriptionId) (ListBySubscriptionCompleteResult, error) { - return c.ListBySubscriptionCompleteMatchingPredicate(ctx, id, CustomLocationOperationPredicate{}) -} - -// ListBySubscriptionCompleteMatchingPredicate retrieves all of the results and then applied the predicate -func (c CustomLocationsClient) ListBySubscriptionCompleteMatchingPredicate(ctx context.Context, id commonids.SubscriptionId, predicate CustomLocationOperationPredicate) (resp ListBySubscriptionCompleteResult, err error) { - items := make([]CustomLocation, 0) - - page, err := c.ListBySubscription(ctx, id) - if err != nil { - err = fmt.Errorf("loading the initial page: %+v", err) - return - } - if page.Model != nil { - for _, v := range *page.Model { - if predicate.Matches(v) { - items = append(items, v) - } - } - } - - for page.HasMore() { - page, err = page.LoadMore(ctx) - if err != nil { - err = fmt.Errorf("loading the next page: %+v", err) - return - } - - if page.Model != nil { - for _, v := range *page.Model { - if predicate.Matches(v) { - items = append(items, v) - } - } - } - } - - out := ListBySubscriptionCompleteResult{ - Items: items, - } - return out, nil -} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listenabledresourcetypes_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listenabledresourcetypes_autorest.go deleted file mode 100644 index 5febee715d99..000000000000 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_listenabledresourcetypes_autorest.go +++ /dev/null @@ -1,186 +0,0 @@ -package customlocations - -import ( - "context" - "fmt" - "net/http" - "net/url" - - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" -) - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See NOTICE.txt in the project root for license information. - -type ListEnabledResourceTypesOperationResponse struct { - HttpResponse *http.Response - Model *[]EnabledResourceType - - nextLink *string - nextPageFunc func(ctx context.Context, nextLink string) (ListEnabledResourceTypesOperationResponse, error) -} - -type ListEnabledResourceTypesCompleteResult struct { - Items []EnabledResourceType -} - -func (r ListEnabledResourceTypesOperationResponse) HasMore() bool { - return r.nextLink != nil -} - -func (r ListEnabledResourceTypesOperationResponse) LoadMore(ctx context.Context) (resp ListEnabledResourceTypesOperationResponse, err error) { - if !r.HasMore() { - err = fmt.Errorf("no more pages returned") - return - } - return r.nextPageFunc(ctx, *r.nextLink) -} - -// ListEnabledResourceTypes ... -func (c CustomLocationsClient) ListEnabledResourceTypes(ctx context.Context, id CustomLocationId) (resp ListEnabledResourceTypesOperationResponse, err error) { - req, err := c.preparerForListEnabledResourceTypes(ctx, id) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListEnabledResourceTypes", nil, "Failure preparing request") - return - } - - resp.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListEnabledResourceTypes", resp.HttpResponse, "Failure sending request") - return - } - - resp, err = c.responderForListEnabledResourceTypes(resp.HttpResponse) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListEnabledResourceTypes", resp.HttpResponse, "Failure responding to request") - return - } - return -} - -// preparerForListEnabledResourceTypes prepares the ListEnabledResourceTypes request. -func (c CustomLocationsClient) preparerForListEnabledResourceTypes(ctx context.Context, id CustomLocationId) (*http.Request, error) { - queryParameters := map[string]interface{}{ - "api-version": defaultApiVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(c.baseUri), - autorest.WithPath(fmt.Sprintf("%s/enabledResourceTypes", id.ID())), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// preparerForListEnabledResourceTypesWithNextLink prepares the ListEnabledResourceTypes request with the given nextLink token. -func (c CustomLocationsClient) preparerForListEnabledResourceTypesWithNextLink(ctx context.Context, nextLink string) (*http.Request, error) { - uri, err := url.Parse(nextLink) - if err != nil { - return nil, fmt.Errorf("parsing nextLink %q: %+v", nextLink, err) - } - queryParameters := map[string]interface{}{} - for k, v := range uri.Query() { - if len(v) == 0 { - continue - } - val := v[0] - val = autorest.Encode("query", val) - queryParameters[k] = val - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsGet(), - autorest.WithBaseURL(c.baseUri), - autorest.WithPath(uri.Path), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// responderForListEnabledResourceTypes handles the response to the ListEnabledResourceTypes request. The method always -// closes the http.Response Body. -func (c CustomLocationsClient) responderForListEnabledResourceTypes(resp *http.Response) (result ListEnabledResourceTypesOperationResponse, err error) { - type page struct { - Values []EnabledResourceType `json:"value"` - NextLink *string `json:"nextLink"` - } - var respObj page - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&respObj), - autorest.ByClosing()) - result.HttpResponse = resp - result.Model = &respObj.Values - result.nextLink = respObj.NextLink - if respObj.NextLink != nil { - result.nextPageFunc = func(ctx context.Context, nextLink string) (result ListEnabledResourceTypesOperationResponse, err error) { - req, err := c.preparerForListEnabledResourceTypesWithNextLink(ctx, nextLink) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListEnabledResourceTypes", nil, "Failure preparing request") - return - } - - result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListEnabledResourceTypes", result.HttpResponse, "Failure sending request") - return - } - - result, err = c.responderForListEnabledResourceTypes(result.HttpResponse) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "ListEnabledResourceTypes", result.HttpResponse, "Failure responding to request") - return - } - - return - } - } - return -} - -// ListEnabledResourceTypesComplete retrieves all of the results into a single object -func (c CustomLocationsClient) ListEnabledResourceTypesComplete(ctx context.Context, id CustomLocationId) (ListEnabledResourceTypesCompleteResult, error) { - return c.ListEnabledResourceTypesCompleteMatchingPredicate(ctx, id, EnabledResourceTypeOperationPredicate{}) -} - -// ListEnabledResourceTypesCompleteMatchingPredicate retrieves all of the results and then applied the predicate -func (c CustomLocationsClient) ListEnabledResourceTypesCompleteMatchingPredicate(ctx context.Context, id CustomLocationId, predicate EnabledResourceTypeOperationPredicate) (resp ListEnabledResourceTypesCompleteResult, err error) { - items := make([]EnabledResourceType, 0) - - page, err := c.ListEnabledResourceTypes(ctx, id) - if err != nil { - err = fmt.Errorf("loading the initial page: %+v", err) - return - } - if page.Model != nil { - for _, v := range *page.Model { - if predicate.Matches(v) { - items = append(items, v) - } - } - } - - for page.HasMore() { - page, err = page.LoadMore(ctx) - if err != nil { - err = fmt.Errorf("loading the next page: %+v", err) - return - } - - if page.Model != nil { - for _, v := range *page.Model { - if predicate.Matches(v) { - items = append(items, v) - } - } - } - } - - out := ListEnabledResourceTypesCompleteResult{ - Items: items, - } - return out, nil -} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_update_autorest.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_update_autorest.go deleted file mode 100644 index d372dbf546d9..000000000000 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/method_update_autorest.go +++ /dev/null @@ -1,69 +0,0 @@ -package customlocations - -import ( - "context" - "net/http" - - "github.com/Azure/go-autorest/autorest" - "github.com/Azure/go-autorest/autorest/azure" -) - -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. See NOTICE.txt in the project root for license information. - -type UpdateOperationResponse struct { - HttpResponse *http.Response - Model *CustomLocation -} - -// Update ... -func (c CustomLocationsClient) Update(ctx context.Context, id CustomLocationId, input PatchableCustomLocations) (result UpdateOperationResponse, err error) { - req, err := c.preparerForUpdate(ctx, id, input) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "Update", nil, "Failure preparing request") - return - } - - result.HttpResponse, err = c.Client.Send(req, azure.DoRetryWithRegistration(c.Client)) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "Update", result.HttpResponse, "Failure sending request") - return - } - - result, err = c.responderForUpdate(result.HttpResponse) - if err != nil { - err = autorest.NewErrorWithError(err, "customlocations.CustomLocationsClient", "Update", result.HttpResponse, "Failure responding to request") - return - } - - return -} - -// preparerForUpdate prepares the Update request. -func (c CustomLocationsClient) preparerForUpdate(ctx context.Context, id CustomLocationId, input PatchableCustomLocations) (*http.Request, error) { - queryParameters := map[string]interface{}{ - "api-version": defaultApiVersion, - } - - preparer := autorest.CreatePreparer( - autorest.AsContentType("application/json; charset=utf-8"), - autorest.AsPatch(), - autorest.WithBaseURL(c.baseUri), - autorest.WithPath(id.ID()), - autorest.WithJSON(input), - autorest.WithQueryParameters(queryParameters)) - return preparer.Prepare((&http.Request{}).WithContext(ctx)) -} - -// responderForUpdate handles the response to the Update request. The method always -// closes the http.Response Body. -func (c CustomLocationsClient) responderForUpdate(resp *http.Response) (result UpdateOperationResponse, err error) { - err = autorest.Respond( - resp, - azure.WithErrorUnlessStatusCode(http.StatusOK), - autorest.ByUnmarshallingJSON(&result.Model), - autorest.ByClosing()) - result.HttpResponse = resp - - return -} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/predicates.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/predicates.go index 3fcd841ecb94..5c5136abf900 100644 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/predicates.go +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/predicates.go @@ -11,7 +11,6 @@ type CustomLocationOperationPredicate struct { } func (p CustomLocationOperationPredicate) Matches(input CustomLocation) bool { - if p.Id != nil && (input.Id == nil || *p.Id != *input.Id) { return false } @@ -19,7 +18,6 @@ func (p CustomLocationOperationPredicate) Matches(input CustomLocation) bool { if p.Location != nil && *p.Location != input.Location { return false } - if p.Name != nil && (input.Name == nil || *p.Name != *input.Name) { return false } From 3f0719db73b3d8c1366b744d738d574140252ee1 Mon Sep 17 00:00:00 2001 From: "Elena Xin (Centific Technologies Inc)" Date: Mon, 11 Mar 2024 14:47:40 +0800 Subject: [PATCH 24/35] fix conflict --- .../2021-08-15/customlocations/id_customlocation.go | 1 + .../extendedlocation/2021-08-15/customlocations/predicates.go | 3 +++ 2 files changed, 4 insertions(+) diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/id_customlocation.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/id_customlocation.go index cf34ecf941d7..0381e8f070d4 100644 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/id_customlocation.go +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/id_customlocation.go @@ -57,6 +57,7 @@ func ParseCustomLocationIDInsensitively(input string) (*CustomLocationId, error) if err != nil { return nil, fmt.Errorf("parsing %q: %+v", input, err) } + id := CustomLocationId{} if err := id.FromParseResult(*parsed); err != nil { return nil, err diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/predicates.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/predicates.go index 5c5136abf900..f18b5aa943f1 100644 --- a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/predicates.go +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations/predicates.go @@ -11,6 +11,7 @@ type CustomLocationOperationPredicate struct { } func (p CustomLocationOperationPredicate) Matches(input CustomLocation) bool { + if p.Id != nil && (input.Id == nil || *p.Id != *input.Id) { return false } @@ -18,6 +19,7 @@ func (p CustomLocationOperationPredicate) Matches(input CustomLocation) bool { if p.Location != nil && *p.Location != input.Location { return false } + if p.Name != nil && (input.Name == nil || *p.Name != *input.Name) { return false } @@ -36,6 +38,7 @@ type EnabledResourceTypeOperationPredicate struct { } func (p EnabledResourceTypeOperationPredicate) Matches(input EnabledResourceType) bool { + if p.Id != nil && (input.Id == nil || *p.Id != *input.Id) { return false } From 3495b7338e7e85b6ca215b9ee625269686d777cb Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Thu, 16 May 2024 14:45:56 +0800 Subject: [PATCH 25/35] Added validation func, more acc test, updated script and docs --- .../extended_location_custom_location.go | 38 +++++++----- .../extended_location_custom_location_test.go | 61 +++++++++++++------ .../testdata/install_agent.py | 4 +- .../testdata/install_agent.sh.tftpl | 2 +- ...ded_location_custom_location.html.markdown | 4 +- 5 files changed, 70 insertions(+), 39 deletions(-) diff --git a/internal/services/extendedlocation/extended_location_custom_location.go b/internal/services/extendedlocation/extended_location_custom_location.go index 95f621a963fa..e5233c4dfc46 100644 --- a/internal/services/extendedlocation/extended_location_custom_location.go +++ b/internal/services/extendedlocation/extended_location_custom_location.go @@ -6,12 +6,14 @@ package extendedlocation import ( "context" "fmt" + "regexp" "time" "github.com/hashicorp/go-azure-helpers/lang/pointer" "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema" "github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations" + arckubernetes "github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters" "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" @@ -50,10 +52,13 @@ func (r CustomLocationResource) Arguments() map[string]*pluginsdk.Schema { "location": commonschema.Location(), "namespace": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringIsNotEmpty, + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringMatch( + regexp.MustCompile("^[a-zA-Z0-9][a-zA-Z0-9-.]{0,252}$"), + "namespace must be between 1 and 253 characters in length and may contain only letters, numbers, periods (.), hyphens (-), and must begin with a letter or number.", + ), }, "cluster_extension_ids": { @@ -67,7 +72,16 @@ func (r CustomLocationResource) Arguments() map[string]*pluginsdk.Schema { "host_resource_id": { Type: pluginsdk.TypeString, Required: true, - ValidateFunc: validation.StringIsNotEmpty, + ValidateFunc: arckubernetes.ValidateConnectedClusterID, + }, + + "host_type": { + Type: pluginsdk.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringInSlice([]string{ + string(customlocations.HostTypeKubernetes), + }, false), }, "authentication": { @@ -78,7 +92,7 @@ func (r CustomLocationResource) Arguments() map[string]*pluginsdk.Schema { Schema: map[string]*pluginsdk.Schema{ "type": { Type: pluginsdk.TypeString, - Required: true, + Optional: true, ValidateFunc: validation.StringIsNotEmpty, }, @@ -96,14 +110,6 @@ func (r CustomLocationResource) Arguments() map[string]*pluginsdk.Schema { Optional: true, ValidateFunc: validation.StringIsNotEmpty, }, - - "host_type": { - Type: pluginsdk.TypeString, - Optional: true, - ValidateFunc: validation.StringInSlice([]string{ - string(customlocations.HostTypeKubernetes), - }, false), - }, } } @@ -217,7 +223,7 @@ func (r CustomLocationResource) Read() sdk.ResourceFunc { state.Namespace = pointer.From(props.Namespace) } - if props.Authentication != nil { + if props.Authentication != nil && props.Authentication.Type != nil && props.Authentication.Value != nil { state.Authentication = []AuthModel{ { Type: pointer.From(props.Authentication.Type), @@ -275,7 +281,7 @@ func (r CustomLocationResource) Update() sdk.ResourceFunc { d := metadata.ResourceData if d.HasChanges("authentication") { - if state.Authentication != nil && len(state.Authentication) > 0 { + if len(state.Authentication) > 0 { auth := state.Authentication[0] customLocationProps.Authentication = &customlocations.CustomLocationPropertiesAuthentication{ Type: pointer.To(auth.Type), diff --git a/internal/services/extendedlocation/extended_location_custom_location_test.go b/internal/services/extendedlocation/extended_location_custom_location_test.go index d080b97fc70d..c5451e2a3560 100644 --- a/internal/services/extendedlocation/extended_location_custom_location_test.go +++ b/internal/services/extendedlocation/extended_location_custom_location_test.go @@ -59,28 +59,37 @@ func TestAccExtendedLocationCustomLocations_basic(t *testing.T) { }) } -func TestAccExtendedLocationCustomLocations_update(t *testing.T) { +func TestAccExtendedLocationCustomLocaitons_complete(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_extended_custom_location", "test") r := CustomLocationResource{} credential, privateKey, publicKey := r.getCredentials(t) data.ResourceTest(t, r, []acceptance.TestStep{ { - Config: r.basic(data, credential, privateKey, publicKey), + Config: r.complete(data, credential, privateKey, publicKey), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), }, data.ImportStep(), + }) +} + +func TestAccExtendedLocationCustomLocations_update(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_extended_custom_location", "test") + r := CustomLocationResource{} + credential, privateKey, publicKey := r.getCredentials(t) + + data.ResourceTest(t, r, []acceptance.TestStep{ { - Config: r.update(data, credential, privateKey, publicKey), + Config: r.basic(data, credential, privateKey, publicKey), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), }, data.ImportStep(), { - Config: r.basic(data, credential, privateKey, publicKey), + Config: r.update(data, credential, privateKey, publicKey), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), ), @@ -127,18 +136,36 @@ resource "azurerm_extended_custom_location" "test" { `, template, data.RandomInteger) } +func (r CustomLocationResource) complete(data acceptance.TestData, credential string, privateKey string, publicKey string) string { + template := r.template(data, credential, publicKey, privateKey) + return fmt.Sprintf(` +%s + +resource "azurerm_extended_custom_location" "test" { + name = "acctestcustomlocation%[2]d" + resource_group_name = azurerm_resource_group.test.name + location = azurerm_resource_group.test.location + host_type = "Kubernetes" + cluster_extension_ids = [ + azurerm_arc_kubernetes_cluster_extension.test.id + ] + display_name = "customlocationcomplete%[2]d" + namespace = "namespace%[2]d" + host_resource_id = azurerm_arc_kubernetes_cluster.test.id +} +`, template, data.RandomInteger) +} + func (r CustomLocationResource) template(data acceptance.TestData, credential string, publicKey string, privateKey string) string { data.Locations.Primary = "eastus" provisionTemplate := r.provisionTemplate(data, credential, privateKey) return fmt.Sprintf(` provider "azurerm" { - features { - resource_group { - prevent_deletion_if_contains_resources = false - } - } + features {} } +data "azurerm_client_config" "current" {} + resource "azurerm_resource_group" "test" { name = "acctestRG-%[1]d" location = "%[2]s" @@ -224,8 +251,8 @@ resource "azurerm_linux_virtual_machine" "test" { } source_image_reference { publisher = "Canonical" - offer = "UbuntuServer" - sku = "18.04-LTS" + offer = "0001-com-ubuntu-server-jammy" + sku = "22_04-lts" version = "latest" } } @@ -259,10 +286,6 @@ resource "azurerm_arc_kubernetes_cluster_extension" "test" { identity { type = "SystemAssigned" } - - depends_on = [ - azurerm_linux_virtual_machine.test - ] } `, data.RandomInteger, data.Locations.Primary, credential, publicKey, provisionTemplate) } @@ -313,11 +336,11 @@ connection { provisioner "file" { content = templatefile("testdata/install_agent.sh.tftpl", { - subscription_id = "%[4]s" + subscription_id = data.azurerm_client_config.current.subscription_id resource_group_name = azurerm_resource_group.test.name cluster_name = "acctest-akcc-%[2]d" location = azurerm_resource_group.test.location - tenant_id = "%[5]s" + tenant_id = data.azurerm_client_config.current.tenant_id working_dir = "%[3]s" }) destination = "%[3]s/install_agent.sh" @@ -335,7 +358,7 @@ provisioner "file" { provisioner "file" { content = < %[3]s/agent_log", ] } -`, credential, data.RandomInteger, "/home/adminuser", os.Getenv("ARM_SUBSCRIPTION_ID"), os.Getenv("ARM_TENANT_ID"), privateKey) +`, credential, data.RandomInteger, "/home/adminuser", privateKey) } diff --git a/internal/services/extendedlocation/testdata/install_agent.py b/internal/services/extendedlocation/testdata/install_agent.py index 2513e9aa7cbb..66a70c3ffa97 100644 --- a/internal/services/extendedlocation/testdata/install_agent.py +++ b/internal/services/extendedlocation/testdata/install_agent.py @@ -185,9 +185,9 @@ def helm_install_release(chart_path, subscription_id, kubernetes_distro, kuberne cloud_name), "--set", "systemDefaultValues.clusterconnect-agent.enabled=true", "--set", "systemDefaultValues.customLocations.enabled=true", - # 51dfe1e8-70c6-4de5-a08e-e18aff23d815 is from: az ad sp show --id bc313c14-388c-4e7d-a58e-70017303ee3b --query id -o tsv + # feb5d117-1f5e-486d-8aa7-0606b8056bda is from: az ad sp show --id bc313c14-388c-4e7d-a58e-70017303ee3b --query id -o tsv # refs: https://learn.microsoft.com/en-us/azure/azure-arc/kubernetes/custom-locations#enable-custom-locations-on-your-cluster - "--set", "systemDefaultValues.customLocations.oid={}".format("51dfe1e8-70c6-4de5-a08e-e18aff23d815"), + "--set", "systemDefaultValues.customLocations.oid={}".format("feb5d117-1f5e-486d-8aa7-0606b8056bda"), "--namespace", "{}".format("azure-arc-release"), "--create-namespace", "--output", "json"] diff --git a/internal/services/extendedlocation/testdata/install_agent.sh.tftpl b/internal/services/extendedlocation/testdata/install_agent.sh.tftpl index 9bb2cbcbd0bf..29377367079f 100644 --- a/internal/services/extendedlocation/testdata/install_agent.sh.tftpl +++ b/internal/services/extendedlocation/testdata/install_agent.sh.tftpl @@ -19,7 +19,7 @@ newgrp docker << END #install golang and kind sudo snap install go --classic -sudo go install sigs.k8s.io/kind@latest +go install sigs.k8s.io/kind@latest #create a new cluster export PATH="$HOME/go/bin:$PATH" diff --git a/website/docs/r/extended_location_custom_location.html.markdown b/website/docs/r/extended_location_custom_location.html.markdown index 8a78a1420fef..0fdc1e1f53f2 100644 --- a/website/docs/r/extended_location_custom_location.html.markdown +++ b/website/docs/r/extended_location_custom_location.html.markdown @@ -10,6 +10,8 @@ description: |- Manages a Custom Location within an Extended Location. +-> **Note:** Installing and configuring the Azure Arc Agent on your Kubernetes Cluster to establish connectivity is outside the scope of this document. For more details refer to [Deploy agents to your cluster](https://learn.microsoft.com/en-us/azure/azure-arc/kubernetes/conceptual-agent-overview#deploy-agents-to-your-cluster) and [Connect an existing Kubernetes Cluster](https://learn.microsoft.com/en-us/azure/azure-arc/kubernetes/quickstart-connect-cluster?tabs=azure-cli#connect-an-existing-kubernetes-cluster). If you encounter issues connecting your Kubernetes Cluster to Azure Arc, we'd recommend opening a ticket with Microsoft Support. + ## Example Usage ```hcl @@ -62,7 +64,7 @@ The following arguments are supported: * `location` - (Required) Specifies the Azure location where the Custom Location should exist. Changing this forces a new Custom Location to be created. -* `namespace` - (Required) Specifies the namespace of the Custom Location.Changing this forces a new Custom Location to be created. +* `namespace` - (Required) Specifies the namespace of the Custom Location. Changing this forces a new Custom Location to be created. * `cluster_extension_ids` - (Required) Specifies the list of Cluster Extension IDs. From 044c2be1f0c5fa1cb22a064b8dc45dd2f0defc4d Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Wed, 26 Jun 2024 11:17:06 +0800 Subject: [PATCH 26/35] change name validation func --- .../extended_location_custom_location.go | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/internal/services/extendedlocation/extended_location_custom_location.go b/internal/services/extendedlocation/extended_location_custom_location.go index e5233c4dfc46..20f51bc0b24a 100644 --- a/internal/services/extendedlocation/extended_location_custom_location.go +++ b/internal/services/extendedlocation/extended_location_custom_location.go @@ -41,10 +41,13 @@ type AuthModel struct { func (r CustomLocationResource) Arguments() map[string]*pluginsdk.Schema { return map[string]*pluginsdk.Schema{ "name": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringIsNotEmpty, + Type: pluginsdk.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.StringMatch( + regexp.MustCompile(`^[A-Za-z\d.\-_]*[A-Za-z\d]$`), + "supported alphanumeric characters and periods, underscores, hyphens. Name should end with an alphanumeric character.", + ), }, "resource_group_name": commonschema.ResourceGroupName(), From a2b8eb358186172ff452cd510b024430318a33e2 Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Wed, 3 Jul 2024 11:00:38 +0800 Subject: [PATCH 27/35] remove location overrride in acc tests --- .../extendedlocation/extended_location_custom_location_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/services/extendedlocation/extended_location_custom_location_test.go b/internal/services/extendedlocation/extended_location_custom_location_test.go index c5451e2a3560..65347d737566 100644 --- a/internal/services/extendedlocation/extended_location_custom_location_test.go +++ b/internal/services/extendedlocation/extended_location_custom_location_test.go @@ -157,7 +157,6 @@ resource "azurerm_extended_custom_location" "test" { } func (r CustomLocationResource) template(data acceptance.TestData, credential string, publicKey string, privateKey string) string { - data.Locations.Primary = "eastus" provisionTemplate := r.provisionTemplate(data, credential, privateKey) return fmt.Sprintf(` provider "azurerm" { From c1979cce830c8d2429f65f1a877940f0a26f9a3a Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Wed, 3 Jul 2024 17:13:48 +0800 Subject: [PATCH 28/35] Address comments, remove unused location overrides, add examples in doc --- .../testdata/install_agent.py | 2 ++ ...ded_location_custom_location.html.markdown | 33 ++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/internal/services/extendedlocation/testdata/install_agent.py b/internal/services/extendedlocation/testdata/install_agent.py index 66a70c3ffa97..8838009373f5 100644 --- a/internal/services/extendedlocation/testdata/install_agent.py +++ b/internal/services/extendedlocation/testdata/install_agent.py @@ -1,3 +1,5 @@ +# This python script is used to install a Helm client on the cluster. + import argparse import json import logging as logger diff --git a/website/docs/r/extended_location_custom_location.html.markdown b/website/docs/r/extended_location_custom_location.html.markdown index 0fdc1e1f53f2..caabca074c0a 100644 --- a/website/docs/r/extended_location_custom_location.html.markdown +++ b/website/docs/r/extended_location_custom_location.html.markdown @@ -20,6 +20,8 @@ resource "azurerm_resource_group" "example" { location = "West Europe" } +data "azurerm_client_config" "current" {} + resource "azurerm_arc_kubernetes_cluster" "example" { name = "example-akcc" resource_group_name = azurerm_resource_group.example.name @@ -35,6 +37,32 @@ resource "azurerm_arc_kubernetes_cluster" "example" { } } +resource "local_file" "example" { + depends_on = [ + azurerm_kubernetes_cluster.example, + ] + content = azurerm_kubernetes_cluster.example.kube_config_raw + filename = "${path.module}/kubeconfig-example" +} + +resource "null_resource" "example1" { + depends_on = [ + azurerm_kubernetes_cluster.example, + ] + provisioner "local-exec" { + command = "set KUBECONFIG=${path.module}/kubeconfig-example" + } +} + +resource "null_resource" "example2" { + depends_on = [ + null_resource.example1, + ] + provisioner "local-exec" { + command = "az connectedk8s connect --name example-akcc --resource-group ${azurerm_resource_group.example.name} --subscription ${data.azurerm_client_config.current.subscription_id} --location ${azurerm_resource_group.example.location} --kube-config=${path.module}/kubeconfig-example --kube-context example" + } +} + resource "azurerm_arc_kubernetes_cluster_extension" "example" { name = "example-ext" cluster_id = azurerm_arc_kubernetes_cluster.example.id @@ -51,6 +79,9 @@ resource "azurerm_extended_location_custom_location" "example" { display_name = "example-custom-location" namespace = "example-namespace" host_resource_id = azurerm_arc_kubernetes_cluster.example.id + authentication { + value = base64encode(azurerm_kubernetes_cluster.example.kube_config_raw) + } } ``` @@ -80,7 +111,7 @@ The following arguments are supported: An `authentication` block supports the following: -* `type` - (Required) Specifies the type of authentication. +* `type` - (Optional) Specifies the type of authentication. * `value` - (Required) Specifies the value of authentication. From 5027d6c2292b553c84c8a0f14530ee78ea14e61e Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Fri, 5 Jul 2024 14:42:42 +0800 Subject: [PATCH 29/35] Fix indent in client list --- internal/clients/client.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/clients/client.go b/internal/clients/client.go index 67569e66b8e0..598a87227ab1 100644 --- a/internal/clients/client.go +++ b/internal/clients/client.go @@ -160,8 +160,9 @@ type Client struct { // StopContext is used for propagating control from Terraform Core (e.g. Ctrl/Cmd+C) StopContext context.Context - Account *ResourceManagerAccount - Features features.UserFeatures + Account *ResourceManagerAccount + Features features.UserFeatures + AadB2c *aadb2c_v2021_04_01_preview.Client Advisor *advisor.Client AnalysisServices *analysisservices_v2017_08_01.Client From c0876c8b79d9807397f9c43f2c16072949d5130f Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Fri, 26 Jul 2024 15:18:17 +0800 Subject: [PATCH 30/35] address comments, change elem type, removing redundant code --- .../extended_location_custom_location.go | 67 +++++++------------ .../extended_location_custom_location_test.go | 13 ++-- .../testdata/install_agent.py | 1 + .../functions/parse_resource_id.html.markdown | 2 +- 4 files changed, 31 insertions(+), 52 deletions(-) diff --git a/internal/services/extendedlocation/extended_location_custom_location.go b/internal/services/extendedlocation/extended_location_custom_location.go index 20f51bc0b24a..8e52e5ece7ce 100644 --- a/internal/services/extendedlocation/extended_location_custom_location.go +++ b/internal/services/extendedlocation/extended_location_custom_location.go @@ -14,6 +14,8 @@ import ( "github.com/hashicorp/go-azure-helpers/resourcemanager/commonschema" "github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations" arckubernetes "github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters" + "github.com/hashicorp/go-azure-sdk/resource-manager/kubernetesconfiguration/2022-11-01/extensions" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-provider-azurerm/internal/sdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" @@ -39,7 +41,7 @@ type AuthModel struct { } func (r CustomLocationResource) Arguments() map[string]*pluginsdk.Schema { - return map[string]*pluginsdk.Schema{ + return map[string]*schema.Schema{ "name": { Type: pluginsdk.TypeString, Required: true, @@ -67,9 +69,7 @@ func (r CustomLocationResource) Arguments() map[string]*pluginsdk.Schema { "cluster_extension_ids": { Type: pluginsdk.TypeList, Required: true, - Elem: &pluginsdk.Schema{ - Type: pluginsdk.TypeString, - }, + Elem: commonschema.ResourceIDReferenceElem(&extensions.ScopedExtensionId{}), }, "host_resource_id": { @@ -87,6 +87,13 @@ func (r CustomLocationResource) Arguments() map[string]*pluginsdk.Schema { }, false), }, + "display_name": { + Type: pluginsdk.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + "authentication": { Type: pluginsdk.TypeList, Optional: true, @@ -102,17 +109,11 @@ func (r CustomLocationResource) Arguments() map[string]*pluginsdk.Schema { "value": { Type: pluginsdk.TypeString, Required: true, - ValidateFunc: validation.StringIsNotEmpty, + ValidateFunc: validation.StringIsBase64, }, }, }, }, - - "display_name": { - Type: pluginsdk.TypeString, - Optional: true, - ValidateFunc: validation.StringIsNotEmpty, - }, } } @@ -205,25 +206,14 @@ func (r CustomLocationResource) Read() sdk.ResourceFunc { props := model.Properties state := CustomLocationResourceModel{ - Name: id.CustomLocationName, - ResourceGroupName: id.ResourceGroupName, - Location: model.Location, - } - - if props.ClusterExtensionIds != nil { - state.ClusterExtensionIds = pointer.From(props.ClusterExtensionIds) - } - if props.DisplayName != nil { - state.DisplayName = pointer.From(props.DisplayName) - } - if props.HostResourceId != nil { - state.HostResourceId = pointer.From(props.HostResourceId) - } - if props.HostType != nil { - state.HostType = string(pointer.From(props.HostType)) - } - if props.Namespace != nil { - state.Namespace = pointer.From(props.Namespace) + Name: id.CustomLocationName, + ResourceGroupName: id.ResourceGroupName, + Location: model.Location, + ClusterExtensionIds: pointer.From(props.ClusterExtensionIds), + DisplayName: pointer.From(props.DisplayName), + HostResourceId: pointer.From(props.HostResourceId), + HostType: string(pointer.From(props.HostType)), + Namespace: pointer.From(props.Namespace), } if props.Authentication != nil && props.Authentication.Type != nil && props.Authentication.Value != nil { @@ -254,10 +244,8 @@ func (r CustomLocationResource) Delete() sdk.ResourceFunc { metadata.Logger.Infof("deleting %s", *id) - if resp, err := client.Delete(ctx, *id); err != nil { - if !response.WasNotFound(resp.HttpResponse) { - return fmt.Errorf("deleting %s: %+v", *id, err) - } + if err := client.DeleteThenPoll(ctx, *id); err != nil { + return fmt.Errorf("deleting %s: %+v", id, err) } return nil @@ -290,6 +278,8 @@ func (r CustomLocationResource) Update() sdk.ResourceFunc { Type: pointer.To(auth.Type), Value: pointer.To(auth.Value), } + } else { + customLocationProps.Authentication = nil } } @@ -297,19 +287,10 @@ func (r CustomLocationResource) Update() sdk.ResourceFunc { customLocationProps.ClusterExtensionIds = pointer.To(state.ClusterExtensionIds) } - if d.HasChange("display_name") { - customLocationProps.DisplayName = pointer.To(state.DisplayName) - } - if d.HasChange("host_resource_id") { customLocationProps.HostResourceId = pointer.To(state.HostResourceId) } - if d.HasChange("host_type") { - hostType := customlocations.HostType(state.HostType) - customLocationProps.HostType = pointer.To(hostType) - } - props := customlocations.PatchableCustomLocations{ Properties: pointer.To(customLocationProps), } diff --git a/internal/services/extendedlocation/extended_location_custom_location_test.go b/internal/services/extendedlocation/extended_location_custom_location_test.go index 65347d737566..425628485236 100644 --- a/internal/services/extendedlocation/extended_location_custom_location_test.go +++ b/internal/services/extendedlocation/extended_location_custom_location_test.go @@ -12,12 +12,10 @@ import ( "encoding/pem" "fmt" "math/rand" - "os" "testing" "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/go-azure-sdk/resource-manager/extendedlocation/2021-08-15/customlocations" - "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" @@ -226,7 +224,7 @@ resource "azurerm_network_security_group" "my_terraform_nsg" { } } -resource "azurerm_network_interface_security_group_association" "example" { +resource "azurerm_network_interface_security_group_association" "test" { network_interface_id = azurerm_network_interface.test.id network_security_group_id = azurerm_network_security_group.my_terraform_nsg.id } @@ -254,6 +252,10 @@ resource "azurerm_linux_virtual_machine" "test" { sku = "22_04-lts" version = "latest" } + + depends_on = [ + azurerm_network_interface_security_group_association.test + ] } resource "azurerm_arc_kubernetes_cluster" "test" { @@ -310,11 +312,6 @@ func (r CustomLocationResource) generateKey() (string, string, error) { } func (r CustomLocationResource) getCredentials(t *testing.T) (credential, privateKey, publicKey string) { - // generateKey() is a time-consuming operation, we only run this test if an env var is set. - if os.Getenv(resource.EnvTfAcc) == "" { - t.Skipf("Acceptance tests skipped unless env '%s' set", resource.EnvTfAcc) - } - credential = fmt.Sprintf("P@$$w0rd%d!", rand.Intn(10000)) privateKey, publicKey, err := r.generateKey() if err != nil { diff --git a/internal/services/extendedlocation/testdata/install_agent.py b/internal/services/extendedlocation/testdata/install_agent.py index 8838009373f5..3db6b7743fcc 100644 --- a/internal/services/extendedlocation/testdata/install_agent.py +++ b/internal/services/extendedlocation/testdata/install_agent.py @@ -1,4 +1,5 @@ # This python script is used to install a Helm client on the cluster. +# This should be identical to the script used in the Azure Arc onboarding flow, plus setting custom location enabled. import argparse import json diff --git a/website/docs/functions/parse_resource_id.html.markdown b/website/docs/functions/parse_resource_id.html.markdown index b4539cca5a28..010a99e13bb2 100644 --- a/website/docs/functions/parse_resource_id.html.markdown +++ b/website/docs/functions/parse_resource_id.html.markdown @@ -66,4 +66,4 @@ normalise_resource_id(id string) string ## Arguments -1. `id` (String) Azure Resource Manager ID. \ No newline at end of file +1. `id` (String) Azure Resource Manager ID. From ef9be028ac8824659673e401bd09bc9a282f0a81 Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Fri, 26 Jul 2024 17:21:31 +0800 Subject: [PATCH 31/35] Update vendors --- .../2021-10-01/connectedclusters/README.md | 142 ++++++++++++++++ .../2021-10-01/connectedclusters/client.go | 26 +++ .../2021-10-01/connectedclusters/constants.go | 154 ++++++++++++++++++ .../connectedclusters/id_connectedcluster.go | 130 +++++++++++++++ .../method_connectedclustercreate.go | 75 +++++++++ .../method_connectedclusterdelete.go | 71 ++++++++ .../method_connectedclusterget.go | 54 ++++++ ...hod_connectedclusterlistbyresourcegroup.go | 106 ++++++++++++ ...thod_connectedclusterlistbysubscription.go | 106 ++++++++++++ ...nnectedclusterlistclusterusercredential.go | 59 +++++++ .../method_connectedclusterupdate.go | 58 +++++++ .../model_connectedcluster.go | 20 +++ .../model_connectedclusterpatch.go | 9 + .../model_connectedclusterproperties.go | 49 ++++++ .../model_credentialresult.go | 9 + .../model_credentialresults.go | 9 + .../model_hybridconnectionconfig.go | 11 ++ ...del_listclusterusercredentialproperties.go | 9 + .../connectedclusters/predicates.go | 32 ++++ .../2021-10-01/connectedclusters/version.go | 12 ++ vendor/modules.txt | 1 + 21 files changed, 1142 insertions(+) create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/README.md create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/client.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/constants.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/id_connectedcluster.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclustercreate.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterdelete.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterget.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterlistbyresourcegroup.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterlistbysubscription.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterlistclusterusercredential.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterupdate.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_connectedcluster.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_connectedclusterpatch.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_connectedclusterproperties.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_credentialresult.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_credentialresults.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_hybridconnectionconfig.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_listclusterusercredentialproperties.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/predicates.go create mode 100644 vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/version.go diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/README.md b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/README.md new file mode 100644 index 000000000000..29736a828c95 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/README.md @@ -0,0 +1,142 @@ + +## `github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters` Documentation + +The `connectedclusters` SDK allows for interaction with the Azure Resource Manager Service `hybridkubernetes` (API Version `2021-10-01`). + +This readme covers example usages, but further information on [using this SDK can be found in the project root](https://github.com/hashicorp/go-azure-sdk/tree/main/docs). + +### Import Path + +```go +import "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" +import "github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters" +``` + + +### Client Initialization + +```go +client := connectedclusters.NewConnectedClustersClientWithBaseURI("https://management.azure.com") +client.Client.Authorizer = authorizer +``` + + +### Example Usage: `ConnectedClustersClient.ConnectedClusterCreate` + +```go +ctx := context.TODO() +id := connectedclusters.NewConnectedClusterID("12345678-1234-9876-4563-123456789012", "example-resource-group", "connectedClusterValue") + +payload := connectedclusters.ConnectedCluster{ + // ... +} + + +if err := client.ConnectedClusterCreateThenPoll(ctx, id, payload); err != nil { + // handle the error +} +``` + + +### Example Usage: `ConnectedClustersClient.ConnectedClusterDelete` + +```go +ctx := context.TODO() +id := connectedclusters.NewConnectedClusterID("12345678-1234-9876-4563-123456789012", "example-resource-group", "connectedClusterValue") + +if err := client.ConnectedClusterDeleteThenPoll(ctx, id); err != nil { + // handle the error +} +``` + + +### Example Usage: `ConnectedClustersClient.ConnectedClusterGet` + +```go +ctx := context.TODO() +id := connectedclusters.NewConnectedClusterID("12345678-1234-9876-4563-123456789012", "example-resource-group", "connectedClusterValue") + +read, err := client.ConnectedClusterGet(ctx, id) +if err != nil { + // handle the error +} +if model := read.Model; model != nil { + // do something with the model/response object +} +``` + + +### Example Usage: `ConnectedClustersClient.ConnectedClusterListByResourceGroup` + +```go +ctx := context.TODO() +id := commonids.NewResourceGroupID("12345678-1234-9876-4563-123456789012", "example-resource-group") + +// alternatively `client.ConnectedClusterListByResourceGroup(ctx, id)` can be used to do batched pagination +items, err := client.ConnectedClusterListByResourceGroupComplete(ctx, id) +if err != nil { + // handle the error +} +for _, item := range items { + // do something +} +``` + + +### Example Usage: `ConnectedClustersClient.ConnectedClusterListBySubscription` + +```go +ctx := context.TODO() +id := commonids.NewSubscriptionID("12345678-1234-9876-4563-123456789012") + +// alternatively `client.ConnectedClusterListBySubscription(ctx, id)` can be used to do batched pagination +items, err := client.ConnectedClusterListBySubscriptionComplete(ctx, id) +if err != nil { + // handle the error +} +for _, item := range items { + // do something +} +``` + + +### Example Usage: `ConnectedClustersClient.ConnectedClusterListClusterUserCredential` + +```go +ctx := context.TODO() +id := connectedclusters.NewConnectedClusterID("12345678-1234-9876-4563-123456789012", "example-resource-group", "connectedClusterValue") + +payload := connectedclusters.ListClusterUserCredentialProperties{ + // ... +} + + +read, err := client.ConnectedClusterListClusterUserCredential(ctx, id, payload) +if err != nil { + // handle the error +} +if model := read.Model; model != nil { + // do something with the model/response object +} +``` + + +### Example Usage: `ConnectedClustersClient.ConnectedClusterUpdate` + +```go +ctx := context.TODO() +id := connectedclusters.NewConnectedClusterID("12345678-1234-9876-4563-123456789012", "example-resource-group", "connectedClusterValue") + +payload := connectedclusters.ConnectedClusterPatch{ + // ... +} + + +read, err := client.ConnectedClusterUpdate(ctx, id, payload) +if err != nil { + // handle the error +} +if model := read.Model; model != nil { + // do something with the model/response object +} +``` diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/client.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/client.go new file mode 100644 index 000000000000..c25ebd209c77 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/client.go @@ -0,0 +1,26 @@ +package connectedclusters + +import ( + "fmt" + + "github.com/hashicorp/go-azure-sdk/sdk/client/resourcemanager" + sdkEnv "github.com/hashicorp/go-azure-sdk/sdk/environments" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ConnectedClustersClient struct { + Client *resourcemanager.Client +} + +func NewConnectedClustersClientWithBaseURI(sdkApi sdkEnv.Api) (*ConnectedClustersClient, error) { + client, err := resourcemanager.NewResourceManagerClient(sdkApi, "connectedclusters", defaultApiVersion) + if err != nil { + return nil, fmt.Errorf("instantiating ConnectedClustersClient: %+v", err) + } + + return &ConnectedClustersClient{ + Client: client, + }, nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/constants.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/constants.go new file mode 100644 index 000000000000..2cd96141a25a --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/constants.go @@ -0,0 +1,154 @@ +package connectedclusters + +import ( + "encoding/json" + "fmt" + "strings" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type AuthenticationMethod string + +const ( + AuthenticationMethodAAD AuthenticationMethod = "AAD" + AuthenticationMethodToken AuthenticationMethod = "Token" +) + +func PossibleValuesForAuthenticationMethod() []string { + return []string{ + string(AuthenticationMethodAAD), + string(AuthenticationMethodToken), + } +} + +func (s *AuthenticationMethod) UnmarshalJSON(bytes []byte) error { + var decoded string + if err := json.Unmarshal(bytes, &decoded); err != nil { + return fmt.Errorf("unmarshaling: %+v", err) + } + out, err := parseAuthenticationMethod(decoded) + if err != nil { + return fmt.Errorf("parsing %q: %+v", decoded, err) + } + *s = *out + return nil +} + +func parseAuthenticationMethod(input string) (*AuthenticationMethod, error) { + vals := map[string]AuthenticationMethod{ + "aad": AuthenticationMethodAAD, + "token": AuthenticationMethodToken, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := AuthenticationMethod(input) + return &out, nil +} + +type ConnectivityStatus string + +const ( + ConnectivityStatusConnected ConnectivityStatus = "Connected" + ConnectivityStatusConnecting ConnectivityStatus = "Connecting" + ConnectivityStatusExpired ConnectivityStatus = "Expired" + ConnectivityStatusOffline ConnectivityStatus = "Offline" +) + +func PossibleValuesForConnectivityStatus() []string { + return []string{ + string(ConnectivityStatusConnected), + string(ConnectivityStatusConnecting), + string(ConnectivityStatusExpired), + string(ConnectivityStatusOffline), + } +} + +func (s *ConnectivityStatus) UnmarshalJSON(bytes []byte) error { + var decoded string + if err := json.Unmarshal(bytes, &decoded); err != nil { + return fmt.Errorf("unmarshaling: %+v", err) + } + out, err := parseConnectivityStatus(decoded) + if err != nil { + return fmt.Errorf("parsing %q: %+v", decoded, err) + } + *s = *out + return nil +} + +func parseConnectivityStatus(input string) (*ConnectivityStatus, error) { + vals := map[string]ConnectivityStatus{ + "connected": ConnectivityStatusConnected, + "connecting": ConnectivityStatusConnecting, + "expired": ConnectivityStatusExpired, + "offline": ConnectivityStatusOffline, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := ConnectivityStatus(input) + return &out, nil +} + +type ProvisioningState string + +const ( + ProvisioningStateAccepted ProvisioningState = "Accepted" + ProvisioningStateCanceled ProvisioningState = "Canceled" + ProvisioningStateDeleting ProvisioningState = "Deleting" + ProvisioningStateFailed ProvisioningState = "Failed" + ProvisioningStateProvisioning ProvisioningState = "Provisioning" + ProvisioningStateSucceeded ProvisioningState = "Succeeded" + ProvisioningStateUpdating ProvisioningState = "Updating" +) + +func PossibleValuesForProvisioningState() []string { + return []string{ + string(ProvisioningStateAccepted), + string(ProvisioningStateCanceled), + string(ProvisioningStateDeleting), + string(ProvisioningStateFailed), + string(ProvisioningStateProvisioning), + string(ProvisioningStateSucceeded), + string(ProvisioningStateUpdating), + } +} + +func (s *ProvisioningState) UnmarshalJSON(bytes []byte) error { + var decoded string + if err := json.Unmarshal(bytes, &decoded); err != nil { + return fmt.Errorf("unmarshaling: %+v", err) + } + out, err := parseProvisioningState(decoded) + if err != nil { + return fmt.Errorf("parsing %q: %+v", decoded, err) + } + *s = *out + return nil +} + +func parseProvisioningState(input string) (*ProvisioningState, error) { + vals := map[string]ProvisioningState{ + "accepted": ProvisioningStateAccepted, + "canceled": ProvisioningStateCanceled, + "deleting": ProvisioningStateDeleting, + "failed": ProvisioningStateFailed, + "provisioning": ProvisioningStateProvisioning, + "succeeded": ProvisioningStateSucceeded, + "updating": ProvisioningStateUpdating, + } + if v, ok := vals[strings.ToLower(input)]; ok { + return &v, nil + } + + // otherwise presume it's an undefined value and best-effort it + out := ProvisioningState(input) + return &out, nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/id_connectedcluster.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/id_connectedcluster.go new file mode 100644 index 000000000000..d70d3e3a357c --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/id_connectedcluster.go @@ -0,0 +1,130 @@ +package connectedclusters + +import ( + "fmt" + "strings" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/recaser" + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +func init() { + recaser.RegisterResourceId(&ConnectedClusterId{}) +} + +var _ resourceids.ResourceId = &ConnectedClusterId{} + +// ConnectedClusterId is a struct representing the Resource ID for a Connected Cluster +type ConnectedClusterId struct { + SubscriptionId string + ResourceGroupName string + ConnectedClusterName string +} + +// NewConnectedClusterID returns a new ConnectedClusterId struct +func NewConnectedClusterID(subscriptionId string, resourceGroupName string, connectedClusterName string) ConnectedClusterId { + return ConnectedClusterId{ + SubscriptionId: subscriptionId, + ResourceGroupName: resourceGroupName, + ConnectedClusterName: connectedClusterName, + } +} + +// ParseConnectedClusterID parses 'input' into a ConnectedClusterId +func ParseConnectedClusterID(input string) (*ConnectedClusterId, error) { + parser := resourceids.NewParserFromResourceIdType(&ConnectedClusterId{}) + parsed, err := parser.Parse(input, false) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + id := ConnectedClusterId{} + if err := id.FromParseResult(*parsed); err != nil { + return nil, err + } + + return &id, nil +} + +// ParseConnectedClusterIDInsensitively parses 'input' case-insensitively into a ConnectedClusterId +// note: this method should only be used for API response data and not user input +func ParseConnectedClusterIDInsensitively(input string) (*ConnectedClusterId, error) { + parser := resourceids.NewParserFromResourceIdType(&ConnectedClusterId{}) + parsed, err := parser.Parse(input, true) + if err != nil { + return nil, fmt.Errorf("parsing %q: %+v", input, err) + } + + id := ConnectedClusterId{} + if err := id.FromParseResult(*parsed); err != nil { + return nil, err + } + + return &id, nil +} + +func (id *ConnectedClusterId) FromParseResult(input resourceids.ParseResult) error { + var ok bool + + if id.SubscriptionId, ok = input.Parsed["subscriptionId"]; !ok { + return resourceids.NewSegmentNotSpecifiedError(id, "subscriptionId", input) + } + + if id.ResourceGroupName, ok = input.Parsed["resourceGroupName"]; !ok { + return resourceids.NewSegmentNotSpecifiedError(id, "resourceGroupName", input) + } + + if id.ConnectedClusterName, ok = input.Parsed["connectedClusterName"]; !ok { + return resourceids.NewSegmentNotSpecifiedError(id, "connectedClusterName", input) + } + + return nil +} + +// ValidateConnectedClusterID checks that 'input' can be parsed as a Connected Cluster ID +func ValidateConnectedClusterID(input interface{}, key string) (warnings []string, errors []error) { + v, ok := input.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected %q to be a string", key)) + return + } + + if _, err := ParseConnectedClusterID(v); err != nil { + errors = append(errors, err) + } + + return +} + +// ID returns the formatted Connected Cluster ID +func (id ConnectedClusterId) ID() string { + fmtString := "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Kubernetes/connectedClusters/%s" + return fmt.Sprintf(fmtString, id.SubscriptionId, id.ResourceGroupName, id.ConnectedClusterName) +} + +// Segments returns a slice of Resource ID Segments which comprise this Connected Cluster ID +func (id ConnectedClusterId) Segments() []resourceids.Segment { + return []resourceids.Segment{ + resourceids.StaticSegment("staticSubscriptions", "subscriptions", "subscriptions"), + resourceids.SubscriptionIdSegment("subscriptionId", "12345678-1234-9876-4563-123456789012"), + resourceids.StaticSegment("staticResourceGroups", "resourceGroups", "resourceGroups"), + resourceids.ResourceGroupSegment("resourceGroupName", "example-resource-group"), + resourceids.StaticSegment("staticProviders", "providers", "providers"), + resourceids.ResourceProviderSegment("staticMicrosoftKubernetes", "Microsoft.Kubernetes", "Microsoft.Kubernetes"), + resourceids.StaticSegment("staticConnectedClusters", "connectedClusters", "connectedClusters"), + resourceids.UserSpecifiedSegment("connectedClusterName", "connectedClusterValue"), + } +} + +// String returns a human-readable description of this Connected Cluster ID +func (id ConnectedClusterId) String() string { + components := []string{ + fmt.Sprintf("Subscription: %q", id.SubscriptionId), + fmt.Sprintf("Resource Group Name: %q", id.ResourceGroupName), + fmt.Sprintf("Connected Cluster Name: %q", id.ConnectedClusterName), + } + return fmt.Sprintf("Connected Cluster (%s)", strings.Join(components, "\n")) +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclustercreate.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclustercreate.go new file mode 100644 index 000000000000..04be54c4fee2 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclustercreate.go @@ -0,0 +1,75 @@ +package connectedclusters + +import ( + "context" + "fmt" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/client/pollers" + "github.com/hashicorp/go-azure-sdk/sdk/client/resourcemanager" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ConnectedClusterCreateOperationResponse struct { + Poller pollers.Poller + HttpResponse *http.Response + OData *odata.OData + Model *ConnectedCluster +} + +// ConnectedClusterCreate ... +func (c ConnectedClustersClient) ConnectedClusterCreate(ctx context.Context, id ConnectedClusterId, input ConnectedCluster) (result ConnectedClusterCreateOperationResponse, err error) { + opts := client.RequestOptions{ + ContentType: "application/json; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusCreated, + http.StatusOK, + }, + HttpMethod: http.MethodPut, + Path: id.ID(), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + return + } + + if err = req.Marshal(input); err != nil { + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.OData = resp.OData + result.HttpResponse = resp.Response + } + if err != nil { + return + } + + result.Poller, err = resourcemanager.PollerFromResponse(resp, c.Client) + if err != nil { + return + } + + return +} + +// ConnectedClusterCreateThenPoll performs ConnectedClusterCreate then polls until it's completed +func (c ConnectedClustersClient) ConnectedClusterCreateThenPoll(ctx context.Context, id ConnectedClusterId, input ConnectedCluster) error { + result, err := c.ConnectedClusterCreate(ctx, id, input) + if err != nil { + return fmt.Errorf("performing ConnectedClusterCreate: %+v", err) + } + + if err := result.Poller.PollUntilDone(ctx); err != nil { + return fmt.Errorf("polling after ConnectedClusterCreate: %+v", err) + } + + return nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterdelete.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterdelete.go new file mode 100644 index 000000000000..26ad549db1b0 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterdelete.go @@ -0,0 +1,71 @@ +package connectedclusters + +import ( + "context" + "fmt" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/client/pollers" + "github.com/hashicorp/go-azure-sdk/sdk/client/resourcemanager" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ConnectedClusterDeleteOperationResponse struct { + Poller pollers.Poller + HttpResponse *http.Response + OData *odata.OData +} + +// ConnectedClusterDelete ... +func (c ConnectedClustersClient) ConnectedClusterDelete(ctx context.Context, id ConnectedClusterId) (result ConnectedClusterDeleteOperationResponse, err error) { + opts := client.RequestOptions{ + ContentType: "application/json; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusAccepted, + http.StatusNoContent, + http.StatusOK, + }, + HttpMethod: http.MethodDelete, + Path: id.ID(), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.OData = resp.OData + result.HttpResponse = resp.Response + } + if err != nil { + return + } + + result.Poller, err = resourcemanager.PollerFromResponse(resp, c.Client) + if err != nil { + return + } + + return +} + +// ConnectedClusterDeleteThenPoll performs ConnectedClusterDelete then polls until it's completed +func (c ConnectedClustersClient) ConnectedClusterDeleteThenPoll(ctx context.Context, id ConnectedClusterId) error { + result, err := c.ConnectedClusterDelete(ctx, id) + if err != nil { + return fmt.Errorf("performing ConnectedClusterDelete: %+v", err) + } + + if err := result.Poller.PollUntilDone(ctx); err != nil { + return fmt.Errorf("polling after ConnectedClusterDelete: %+v", err) + } + + return nil +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterget.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterget.go new file mode 100644 index 000000000000..9ba97354addb --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterget.go @@ -0,0 +1,54 @@ +package connectedclusters + +import ( + "context" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ConnectedClusterGetOperationResponse struct { + HttpResponse *http.Response + OData *odata.OData + Model *ConnectedCluster +} + +// ConnectedClusterGet ... +func (c ConnectedClustersClient) ConnectedClusterGet(ctx context.Context, id ConnectedClusterId) (result ConnectedClusterGetOperationResponse, err error) { + opts := client.RequestOptions{ + ContentType: "application/json; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + Path: id.ID(), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.OData = resp.OData + result.HttpResponse = resp.Response + } + if err != nil { + return + } + + var model ConnectedCluster + result.Model = &model + + if err = resp.Unmarshal(result.Model); err != nil { + return + } + + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterlistbyresourcegroup.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterlistbyresourcegroup.go new file mode 100644 index 000000000000..4429def6a6fb --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterlistbyresourcegroup.go @@ -0,0 +1,106 @@ +package connectedclusters + +import ( + "context" + "fmt" + "net/http" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ConnectedClusterListByResourceGroupOperationResponse struct { + HttpResponse *http.Response + OData *odata.OData + Model *[]ConnectedCluster +} + +type ConnectedClusterListByResourceGroupCompleteResult struct { + LatestHttpResponse *http.Response + Items []ConnectedCluster +} + +type ConnectedClusterListByResourceGroupCustomPager struct { + NextLink *odata.Link `json:"nextLink"` +} + +func (p *ConnectedClusterListByResourceGroupCustomPager) NextPageLink() *odata.Link { + defer func() { + p.NextLink = nil + }() + + return p.NextLink +} + +// ConnectedClusterListByResourceGroup ... +func (c ConnectedClustersClient) ConnectedClusterListByResourceGroup(ctx context.Context, id commonids.ResourceGroupId) (result ConnectedClusterListByResourceGroupOperationResponse, err error) { + opts := client.RequestOptions{ + ContentType: "application/json; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + Pager: &ConnectedClusterListByResourceGroupCustomPager{}, + Path: fmt.Sprintf("%s/providers/Microsoft.Kubernetes/connectedClusters", id.ID()), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + return + } + + var resp *client.Response + resp, err = req.ExecutePaged(ctx) + if resp != nil { + result.OData = resp.OData + result.HttpResponse = resp.Response + } + if err != nil { + return + } + + var values struct { + Values *[]ConnectedCluster `json:"value"` + } + if err = resp.Unmarshal(&values); err != nil { + return + } + + result.Model = values.Values + + return +} + +// ConnectedClusterListByResourceGroupComplete retrieves all the results into a single object +func (c ConnectedClustersClient) ConnectedClusterListByResourceGroupComplete(ctx context.Context, id commonids.ResourceGroupId) (ConnectedClusterListByResourceGroupCompleteResult, error) { + return c.ConnectedClusterListByResourceGroupCompleteMatchingPredicate(ctx, id, ConnectedClusterOperationPredicate{}) +} + +// ConnectedClusterListByResourceGroupCompleteMatchingPredicate retrieves all the results and then applies the predicate +func (c ConnectedClustersClient) ConnectedClusterListByResourceGroupCompleteMatchingPredicate(ctx context.Context, id commonids.ResourceGroupId, predicate ConnectedClusterOperationPredicate) (result ConnectedClusterListByResourceGroupCompleteResult, err error) { + items := make([]ConnectedCluster, 0) + + resp, err := c.ConnectedClusterListByResourceGroup(ctx, id) + if err != nil { + result.LatestHttpResponse = resp.HttpResponse + err = fmt.Errorf("loading results: %+v", err) + return + } + if resp.Model != nil { + for _, v := range *resp.Model { + if predicate.Matches(v) { + items = append(items, v) + } + } + } + + result = ConnectedClusterListByResourceGroupCompleteResult{ + LatestHttpResponse: resp.HttpResponse, + Items: items, + } + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterlistbysubscription.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterlistbysubscription.go new file mode 100644 index 000000000000..6abe9817dda7 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterlistbysubscription.go @@ -0,0 +1,106 @@ +package connectedclusters + +import ( + "context" + "fmt" + "net/http" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ConnectedClusterListBySubscriptionOperationResponse struct { + HttpResponse *http.Response + OData *odata.OData + Model *[]ConnectedCluster +} + +type ConnectedClusterListBySubscriptionCompleteResult struct { + LatestHttpResponse *http.Response + Items []ConnectedCluster +} + +type ConnectedClusterListBySubscriptionCustomPager struct { + NextLink *odata.Link `json:"nextLink"` +} + +func (p *ConnectedClusterListBySubscriptionCustomPager) NextPageLink() *odata.Link { + defer func() { + p.NextLink = nil + }() + + return p.NextLink +} + +// ConnectedClusterListBySubscription ... +func (c ConnectedClustersClient) ConnectedClusterListBySubscription(ctx context.Context, id commonids.SubscriptionId) (result ConnectedClusterListBySubscriptionOperationResponse, err error) { + opts := client.RequestOptions{ + ContentType: "application/json; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + Pager: &ConnectedClusterListBySubscriptionCustomPager{}, + Path: fmt.Sprintf("%s/providers/Microsoft.Kubernetes/connectedClusters", id.ID()), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + return + } + + var resp *client.Response + resp, err = req.ExecutePaged(ctx) + if resp != nil { + result.OData = resp.OData + result.HttpResponse = resp.Response + } + if err != nil { + return + } + + var values struct { + Values *[]ConnectedCluster `json:"value"` + } + if err = resp.Unmarshal(&values); err != nil { + return + } + + result.Model = values.Values + + return +} + +// ConnectedClusterListBySubscriptionComplete retrieves all the results into a single object +func (c ConnectedClustersClient) ConnectedClusterListBySubscriptionComplete(ctx context.Context, id commonids.SubscriptionId) (ConnectedClusterListBySubscriptionCompleteResult, error) { + return c.ConnectedClusterListBySubscriptionCompleteMatchingPredicate(ctx, id, ConnectedClusterOperationPredicate{}) +} + +// ConnectedClusterListBySubscriptionCompleteMatchingPredicate retrieves all the results and then applies the predicate +func (c ConnectedClustersClient) ConnectedClusterListBySubscriptionCompleteMatchingPredicate(ctx context.Context, id commonids.SubscriptionId, predicate ConnectedClusterOperationPredicate) (result ConnectedClusterListBySubscriptionCompleteResult, err error) { + items := make([]ConnectedCluster, 0) + + resp, err := c.ConnectedClusterListBySubscription(ctx, id) + if err != nil { + result.LatestHttpResponse = resp.HttpResponse + err = fmt.Errorf("loading results: %+v", err) + return + } + if resp.Model != nil { + for _, v := range *resp.Model { + if predicate.Matches(v) { + items = append(items, v) + } + } + } + + result = ConnectedClusterListBySubscriptionCompleteResult{ + LatestHttpResponse: resp.HttpResponse, + Items: items, + } + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterlistclusterusercredential.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterlistclusterusercredential.go new file mode 100644 index 000000000000..6154d1cf2313 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterlistclusterusercredential.go @@ -0,0 +1,59 @@ +package connectedclusters + +import ( + "context" + "fmt" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ConnectedClusterListClusterUserCredentialOperationResponse struct { + HttpResponse *http.Response + OData *odata.OData + Model *CredentialResults +} + +// ConnectedClusterListClusterUserCredential ... +func (c ConnectedClustersClient) ConnectedClusterListClusterUserCredential(ctx context.Context, id ConnectedClusterId, input ListClusterUserCredentialProperties) (result ConnectedClusterListClusterUserCredentialOperationResponse, err error) { + opts := client.RequestOptions{ + ContentType: "application/json; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodPost, + Path: fmt.Sprintf("%s/listClusterUserCredential", id.ID()), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + return + } + + if err = req.Marshal(input); err != nil { + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.OData = resp.OData + result.HttpResponse = resp.Response + } + if err != nil { + return + } + + var model CredentialResults + result.Model = &model + + if err = resp.Unmarshal(result.Model); err != nil { + return + } + + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterupdate.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterupdate.go new file mode 100644 index 000000000000..c4a8cbe1c31a --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/method_connectedclusterupdate.go @@ -0,0 +1,58 @@ +package connectedclusters + +import ( + "context" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ConnectedClusterUpdateOperationResponse struct { + HttpResponse *http.Response + OData *odata.OData + Model *ConnectedCluster +} + +// ConnectedClusterUpdate ... +func (c ConnectedClustersClient) ConnectedClusterUpdate(ctx context.Context, id ConnectedClusterId, input ConnectedClusterPatch) (result ConnectedClusterUpdateOperationResponse, err error) { + opts := client.RequestOptions{ + ContentType: "application/json; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodPatch, + Path: id.ID(), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + return + } + + if err = req.Marshal(input); err != nil { + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.OData = resp.OData + result.HttpResponse = resp.Response + } + if err != nil { + return + } + + var model ConnectedCluster + result.Model = &model + + if err = resp.Unmarshal(result.Model); err != nil { + return + } + + return +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_connectedcluster.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_connectedcluster.go new file mode 100644 index 000000000000..d1f61f12e1a9 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_connectedcluster.go @@ -0,0 +1,20 @@ +package connectedclusters + +import ( + "github.com/hashicorp/go-azure-helpers/resourcemanager/identity" + "github.com/hashicorp/go-azure-helpers/resourcemanager/systemdata" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ConnectedCluster struct { + Id *string `json:"id,omitempty"` + Identity identity.SystemAssigned `json:"identity"` + Location string `json:"location"` + Name *string `json:"name,omitempty"` + Properties ConnectedClusterProperties `json:"properties"` + SystemData *systemdata.SystemData `json:"systemData,omitempty"` + Tags *map[string]string `json:"tags,omitempty"` + Type *string `json:"type,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_connectedclusterpatch.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_connectedclusterpatch.go new file mode 100644 index 000000000000..560b8bccc64f --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_connectedclusterpatch.go @@ -0,0 +1,9 @@ +package connectedclusters + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ConnectedClusterPatch struct { + Properties *interface{} `json:"properties,omitempty"` + Tags *map[string]string `json:"tags,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_connectedclusterproperties.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_connectedclusterproperties.go new file mode 100644 index 000000000000..eb7e5c945f1d --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_connectedclusterproperties.go @@ -0,0 +1,49 @@ +package connectedclusters + +import ( + "time" + + "github.com/hashicorp/go-azure-helpers/lang/dates" +) + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ConnectedClusterProperties struct { + AgentPublicKeyCertificate string `json:"agentPublicKeyCertificate"` + AgentVersion *string `json:"agentVersion,omitempty"` + ConnectivityStatus *ConnectivityStatus `json:"connectivityStatus,omitempty"` + Distribution *string `json:"distribution,omitempty"` + Infrastructure *string `json:"infrastructure,omitempty"` + KubernetesVersion *string `json:"kubernetesVersion,omitempty"` + LastConnectivityTime *string `json:"lastConnectivityTime,omitempty"` + ManagedIdentityCertificateExpirationTime *string `json:"managedIdentityCertificateExpirationTime,omitempty"` + Offering *string `json:"offering,omitempty"` + ProvisioningState *ProvisioningState `json:"provisioningState,omitempty"` + TotalCoreCount *int64 `json:"totalCoreCount,omitempty"` + TotalNodeCount *int64 `json:"totalNodeCount,omitempty"` +} + +func (o *ConnectedClusterProperties) GetLastConnectivityTimeAsTime() (*time.Time, error) { + if o.LastConnectivityTime == nil { + return nil, nil + } + return dates.ParseAsFormat(o.LastConnectivityTime, "2006-01-02T15:04:05Z07:00") +} + +func (o *ConnectedClusterProperties) SetLastConnectivityTimeAsTime(input time.Time) { + formatted := input.Format("2006-01-02T15:04:05Z07:00") + o.LastConnectivityTime = &formatted +} + +func (o *ConnectedClusterProperties) GetManagedIdentityCertificateExpirationTimeAsTime() (*time.Time, error) { + if o.ManagedIdentityCertificateExpirationTime == nil { + return nil, nil + } + return dates.ParseAsFormat(o.ManagedIdentityCertificateExpirationTime, "2006-01-02T15:04:05Z07:00") +} + +func (o *ConnectedClusterProperties) SetManagedIdentityCertificateExpirationTimeAsTime(input time.Time) { + formatted := input.Format("2006-01-02T15:04:05Z07:00") + o.ManagedIdentityCertificateExpirationTime = &formatted +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_credentialresult.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_credentialresult.go new file mode 100644 index 000000000000..dc74c9fd42e6 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_credentialresult.go @@ -0,0 +1,9 @@ +package connectedclusters + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type CredentialResult struct { + Name *string `json:"name,omitempty"` + Value *string `json:"value,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_credentialresults.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_credentialresults.go new file mode 100644 index 000000000000..a64afb76a343 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_credentialresults.go @@ -0,0 +1,9 @@ +package connectedclusters + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type CredentialResults struct { + HybridConnectionConfig *HybridConnectionConfig `json:"hybridConnectionConfig,omitempty"` + Kubeconfigs *[]CredentialResult `json:"kubeconfigs,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_hybridconnectionconfig.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_hybridconnectionconfig.go new file mode 100644 index 000000000000..2f2c102d61a2 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_hybridconnectionconfig.go @@ -0,0 +1,11 @@ +package connectedclusters + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type HybridConnectionConfig struct { + ExpirationTime *int64 `json:"expirationTime,omitempty"` + HybridConnectionName *string `json:"hybridConnectionName,omitempty"` + Relay *string `json:"relay,omitempty"` + Token *string `json:"token,omitempty"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_listclusterusercredentialproperties.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_listclusterusercredentialproperties.go new file mode 100644 index 000000000000..e8e0c57aaab7 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/model_listclusterusercredentialproperties.go @@ -0,0 +1,9 @@ +package connectedclusters + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ListClusterUserCredentialProperties struct { + AuthenticationMethod AuthenticationMethod `json:"authenticationMethod"` + ClientProxy bool `json:"clientProxy"` +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/predicates.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/predicates.go new file mode 100644 index 000000000000..a1dcf6aaa3a2 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/predicates.go @@ -0,0 +1,32 @@ +package connectedclusters + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +type ConnectedClusterOperationPredicate struct { + Id *string + Location *string + Name *string + Type *string +} + +func (p ConnectedClusterOperationPredicate) Matches(input ConnectedCluster) bool { + + if p.Id != nil && (input.Id == nil || *p.Id != *input.Id) { + return false + } + + if p.Location != nil && *p.Location != input.Location { + return false + } + + if p.Name != nil && (input.Name == nil || *p.Name != *input.Name) { + return false + } + + if p.Type != nil && (input.Type == nil || *p.Type != *input.Type) { + return false + } + + return true +} diff --git a/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/version.go b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/version.go new file mode 100644 index 000000000000..078fe01f8f68 --- /dev/null +++ b/vendor/github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters/version.go @@ -0,0 +1,12 @@ +package connectedclusters + +import "fmt" + +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. See NOTICE.txt in the project root for license information. + +const defaultApiVersion = "2021-10-01" + +func userAgent() string { + return fmt.Sprintf("hashicorp/go-azure-sdk/connectedclusters/%s", defaultApiVersion) +} diff --git a/vendor/modules.txt b/vendor/modules.txt index be8b1e1382ec..4c438ff782f2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -564,6 +564,7 @@ github.com/hashicorp/go-azure-sdk/resource-manager/hybridcompute/2022-11-10/mach github.com/hashicorp/go-azure-sdk/resource-manager/hybridcompute/2022-11-10/machines github.com/hashicorp/go-azure-sdk/resource-manager/hybridcompute/2022-11-10/privateendpointconnections github.com/hashicorp/go-azure-sdk/resource-manager/hybridcompute/2022-11-10/privatelinkscopes +github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2021-10-01/connectedclusters github.com/hashicorp/go-azure-sdk/resource-manager/hybridkubernetes/2024-01-01/connectedclusters github.com/hashicorp/go-azure-sdk/resource-manager/insights/2015-04-01/activitylogs github.com/hashicorp/go-azure-sdk/resource-manager/insights/2016-03-01/logprofiles From 51d1ef478116ba6e6b2dc52831538f074b5be102 Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Tue, 30 Jul 2024 15:16:38 +0800 Subject: [PATCH 32/35] update oid in python script, add more comments inline for users --- internal/services/extendedlocation/testdata/install_agent.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/internal/services/extendedlocation/testdata/install_agent.py b/internal/services/extendedlocation/testdata/install_agent.py index 3db6b7743fcc..a1640c942dc1 100644 --- a/internal/services/extendedlocation/testdata/install_agent.py +++ b/internal/services/extendedlocation/testdata/install_agent.py @@ -188,9 +188,10 @@ def helm_install_release(chart_path, subscription_id, kubernetes_distro, kuberne cloud_name), "--set", "systemDefaultValues.clusterconnect-agent.enabled=true", "--set", "systemDefaultValues.customLocations.enabled=true", - # feb5d117-1f5e-486d-8aa7-0606b8056bda is from: az ad sp show --id bc313c14-388c-4e7d-a58e-70017303ee3b --query id -o tsv + # ccce55cc-eb6c-45ec-b9ca-562ababa6a44 is from: az ad sp show --id bc313c14-388c-4e7d-a58e-70017303ee3b --query id -o tsv + # As a user, you need to run the above command to get the object id of the service principal and replace it in the below command. # refs: https://learn.microsoft.com/en-us/azure/azure-arc/kubernetes/custom-locations#enable-custom-locations-on-your-cluster - "--set", "systemDefaultValues.customLocations.oid={}".format("feb5d117-1f5e-486d-8aa7-0606b8056bda"), + "--set", "systemDefaultValues.customLocations.oid={}".format("ccce55cc-eb6c-45ec-b9ca-562ababa6a44"), "--namespace", "{}".format("azure-arc-release"), "--create-namespace", "--output", "json"] From b44259bd2f3a5a09903d92995c65f64fa3715cae Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Thu, 1 Aug 2024 17:12:15 +0800 Subject: [PATCH 33/35] Address comments, remove some unupdatable attributes --- .../extended_location_custom_location.go | 19 +++++++------------ .../extended_location_custom_location_test.go | 2 +- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/internal/services/extendedlocation/extended_location_custom_location.go b/internal/services/extendedlocation/extended_location_custom_location.go index 8e52e5ece7ce..e33ca400eff7 100644 --- a/internal/services/extendedlocation/extended_location_custom_location.go +++ b/internal/services/extendedlocation/extended_location_custom_location.go @@ -66,18 +66,19 @@ func (r CustomLocationResource) Arguments() map[string]*pluginsdk.Schema { ), }, - "cluster_extension_ids": { - Type: pluginsdk.TypeList, - Required: true, - Elem: commonschema.ResourceIDReferenceElem(&extensions.ScopedExtensionId{}), - }, - "host_resource_id": { Type: pluginsdk.TypeString, Required: true, + ForceNew: true, ValidateFunc: arckubernetes.ValidateConnectedClusterID, }, + "cluster_extension_ids": { + Type: pluginsdk.TypeList, + Required: true, + Elem: commonschema.ResourceIDReferenceElem(&extensions.ScopedExtensionId{}), + }, + "host_type": { Type: pluginsdk.TypeString, Optional: true, @@ -278,8 +279,6 @@ func (r CustomLocationResource) Update() sdk.ResourceFunc { Type: pointer.To(auth.Type), Value: pointer.To(auth.Value), } - } else { - customLocationProps.Authentication = nil } } @@ -287,10 +286,6 @@ func (r CustomLocationResource) Update() sdk.ResourceFunc { customLocationProps.ClusterExtensionIds = pointer.To(state.ClusterExtensionIds) } - if d.HasChange("host_resource_id") { - customLocationProps.HostResourceId = pointer.To(state.HostResourceId) - } - props := customlocations.PatchableCustomLocations{ Properties: pointer.To(customLocationProps), } diff --git a/internal/services/extendedlocation/extended_location_custom_location_test.go b/internal/services/extendedlocation/extended_location_custom_location_test.go index 425628485236..740df1db9bdd 100644 --- a/internal/services/extendedlocation/extended_location_custom_location_test.go +++ b/internal/services/extendedlocation/extended_location_custom_location_test.go @@ -57,7 +57,7 @@ func TestAccExtendedLocationCustomLocations_basic(t *testing.T) { }) } -func TestAccExtendedLocationCustomLocaitons_complete(t *testing.T) { +func TestAccExtendedLocationCustomLocations_complete(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_extended_custom_location", "test") r := CustomLocationResource{} credential, privateKey, publicKey := r.getCredentials(t) From df7abf8d89c9962d4ab28d6d4d8fc5e23533cd54 Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Thu, 1 Aug 2024 17:24:05 +0800 Subject: [PATCH 34/35] revert --- website/docs/functions/parse_resource_id.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/functions/parse_resource_id.html.markdown b/website/docs/functions/parse_resource_id.html.markdown index 010a99e13bb2..b4539cca5a28 100644 --- a/website/docs/functions/parse_resource_id.html.markdown +++ b/website/docs/functions/parse_resource_id.html.markdown @@ -66,4 +66,4 @@ normalise_resource_id(id string) string ## Arguments -1. `id` (String) Azure Resource Manager ID. +1. `id` (String) Azure Resource Manager ID. \ No newline at end of file From 4793feda88bf2b783c37747ad9b67b2c60aabb9e Mon Sep 17 00:00:00 2001 From: Jiawei Tao Date: Wed, 7 Aug 2024 14:17:30 +0800 Subject: [PATCH 35/35] address comments on update --- .../extended_location_custom_location.go | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/internal/services/extendedlocation/extended_location_custom_location.go b/internal/services/extendedlocation/extended_location_custom_location.go index e33ca400eff7..cb3bfbb38cd6 100644 --- a/internal/services/extendedlocation/extended_location_custom_location.go +++ b/internal/services/extendedlocation/extended_location_custom_location.go @@ -217,6 +217,7 @@ func (r CustomLocationResource) Read() sdk.ResourceFunc { Namespace: pointer.From(props.Namespace), } + // API always returns an empty `authentication` block even it's not specified. Tracing the bug: https://github.com/Azure/azure-rest-api-specs/issues/30101 if props.Authentication != nil && props.Authentication.Type != nil && props.Authentication.Value != nil { state.Authentication = []AuthModel{ { @@ -269,28 +270,35 @@ func (r CustomLocationResource) Update() sdk.ResourceFunc { return fmt.Errorf("decoding %+v", err) } - customLocationProps := customlocations.CustomLocationProperties{} + existing, err := client.Get(ctx, *id) + if err != nil { + return err + } + + model := existing.Model + + if model.Properties == nil { + return fmt.Errorf("retreiving properties for %s for update: %+v", *id, err) + } d := metadata.ResourceData if d.HasChanges("authentication") { if len(state.Authentication) > 0 { auth := state.Authentication[0] - customLocationProps.Authentication = &customlocations.CustomLocationPropertiesAuthentication{ + model.Properties.Authentication = &customlocations.CustomLocationPropertiesAuthentication{ Type: pointer.To(auth.Type), Value: pointer.To(auth.Value), } } + } else { + model.Properties.Authentication = nil } if d.HasChange("cluster_extension_ids") { - customLocationProps.ClusterExtensionIds = pointer.To(state.ClusterExtensionIds) - } - - props := customlocations.PatchableCustomLocations{ - Properties: pointer.To(customLocationProps), + model.Properties.ClusterExtensionIds = pointer.To(state.ClusterExtensionIds) } - if _, err := client.Update(ctx, *id, props); err != nil { + if _, err := client.CreateOrUpdate(ctx, *id, *model); err != nil { return fmt.Errorf("updating %s: %+v", *id, err) } return nil