diff --git a/.teamcity/components/generated/services.kt b/.teamcity/components/generated/services.kt index 99069a48a838..6a9ac037da88 100644 --- a/.teamcity/components/generated/services.kt +++ b/.teamcity/components/generated/services.kt @@ -43,6 +43,7 @@ var services = mapOf( "machinelearning" to "Machine Learning", "maintenance" to "Maintenance", "managedapplications" to "Managed Applications", + "lighthouse" to "Lighthouse", "managementgroup" to "Management Group", "maps" to "Maps", "mariadb" to "MariaDB", diff --git a/azurerm/internal/clients/client.go b/azurerm/internal/clients/client.go index 9ed0b26315dd..2e2b500ce8ec 100644 --- a/azurerm/internal/clients/client.go +++ b/azurerm/internal/clients/client.go @@ -44,6 +44,7 @@ import ( timeseriesinsights "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/iottimeseriesinsights/client" keyvault "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/keyvault/client" kusto "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/kusto/client" + lighthouse "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/lighthouse/client" loganalytics "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/loganalytics/client" logic "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/logic/client" machinelearning "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/machinelearning/client" @@ -130,6 +131,7 @@ type Client struct { IoTTimeSeriesInsights *timeseriesinsights.Client KeyVault *keyvault.Client Kusto *kusto.Client + Lighthouse *lighthouse.Client LogAnalytics *loganalytics.Client Logic *logic.Client MachineLearning *machinelearning.Client @@ -217,6 +219,7 @@ func (client *Client) Build(ctx context.Context, o *common.ClientOptions) error client.IoTTimeSeriesInsights = timeseriesinsights.NewClient(o) client.KeyVault = keyvault.NewClient(o) client.Kusto = kusto.NewClient(o) + client.Lighthouse = lighthouse.NewClient(o) client.LogAnalytics = loganalytics.NewClient(o) client.Logic = logic.NewClient(o) client.MachineLearning = machinelearning.NewClient(o) diff --git a/azurerm/internal/provider/services.go b/azurerm/internal/provider/services.go index fb13e315327b..1cab72a14e5c 100644 --- a/azurerm/internal/provider/services.go +++ b/azurerm/internal/provider/services.go @@ -40,6 +40,7 @@ import ( "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/iottimeseriesinsights" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/keyvault" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/kusto" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/lighthouse" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/loganalytics" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/logic" "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/machinelearning" @@ -127,6 +128,7 @@ func SupportedServices() []common.ServiceRegistration { machinelearning.Registration{}, maintenance.Registration{}, managedapplications.Registration{}, + lighthouse.Registration{}, managementgroup.Registration{}, maps.Registration{}, mariadb.Registration{}, diff --git a/azurerm/internal/resourceproviders/required.go b/azurerm/internal/resourceproviders/required.go index 620a8653fb01..fbb0d130c583 100644 --- a/azurerm/internal/resourceproviders/required.go +++ b/azurerm/internal/resourceproviders/required.go @@ -45,6 +45,7 @@ func Required() map[string]struct{} { "Microsoft.MachineLearningServices": {}, "Microsoft.Maintenance": {}, "Microsoft.ManagedIdentity": {}, + "Microsoft.ManagedServices": {}, "Microsoft.Management": {}, "Microsoft.Maps": {}, "Microsoft.MarketplaceOrdering": {}, diff --git a/azurerm/internal/services/lighthouse/client/client.go b/azurerm/internal/services/lighthouse/client/client.go new file mode 100644 index 000000000000..6b7fa92bd6de --- /dev/null +++ b/azurerm/internal/services/lighthouse/client/client.go @@ -0,0 +1,24 @@ +package client + +import ( + "github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/common" +) + +type Client struct { + DefinitionsClient *managedservices.RegistrationDefinitionsClient + AssignmentsClient *managedservices.RegistrationAssignmentsClient +} + +func NewClient(o *common.ClientOptions) *Client { + DefinitionsClient := managedservices.NewRegistrationDefinitionsClientWithBaseURI(o.ResourceManagerEndpoint) + o.ConfigureClient(&DefinitionsClient.Client, o.ResourceManagerAuthorizer) + + AssignmentsClient := managedservices.NewRegistrationAssignmentsClientWithBaseURI(o.ResourceManagerEndpoint) + o.ConfigureClient(&AssignmentsClient.Client, o.ResourceManagerAuthorizer) + + return &Client{ + DefinitionsClient: &DefinitionsClient, + AssignmentsClient: &AssignmentsClient, + } +} diff --git a/azurerm/internal/services/lighthouse/parse/lighthouse_assignment.go b/azurerm/internal/services/lighthouse/parse/lighthouse_assignment.go new file mode 100644 index 000000000000..2f3b395a9430 --- /dev/null +++ b/azurerm/internal/services/lighthouse/parse/lighthouse_assignment.go @@ -0,0 +1,25 @@ +package parse + +import ( + "fmt" + "strings" +) + +type LighthouseAssignmentId struct { + Scope string + Name string +} + +func LighthouseAssignmentID(id string) (*LighthouseAssignmentId, error) { + segments := strings.Split(id, "/providers/Microsoft.ManagedServices/registrationAssignments/") + if len(segments) != 2 { + return nil, fmt.Errorf("Expected ID to be in the format `{scope}/providers/Microsoft.ManagedServices/registrationAssignments/{name} - got %d segments", len(segments)) + } + + lighthouseAssignmentId := LighthouseAssignmentId{ + Scope: segments[0], + Name: segments[1], + } + + return &lighthouseAssignmentId, nil +} diff --git a/azurerm/internal/services/lighthouse/parse/lighthouse_assignment_test.go b/azurerm/internal/services/lighthouse/parse/lighthouse_assignment_test.go new file mode 100644 index 000000000000..e3275e12a604 --- /dev/null +++ b/azurerm/internal/services/lighthouse/parse/lighthouse_assignment_test.go @@ -0,0 +1,57 @@ +package parse + +import ( + "testing" +) + +func TestLighthouseAssignmentID(t *testing.T) { + testData := []struct { + Name string + Input string + Expected *LighthouseAssignmentId + }{ + { + Name: "Empty", + Input: "", + Expected: nil, + }, + { + Name: "Missing Scope", + Input: "providers/Microsoft.ManagedServices/registrationAssignments/00000000-0000-0000-0000-000000000000", + Expected: nil, + }, + { + Name: "Missing Name", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ManagedServices/registrationAssignments", + Expected: nil, + }, + { + Name: "Lighthouse assignment ID", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ManagedServices/registrationAssignments/00000000-0000-0000-0000-000000000000", + Expected: &LighthouseAssignmentId{ + Name: "00000000-0000-0000-0000-000000000000", + Scope: "/subscriptions/00000000-0000-0000-0000-000000000000", + }, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q..", v.Name) + + actual, err := LighthouseAssignmentID(v.Input) + if err != nil { + if v.Expected == nil { + continue + } + t.Fatalf("Expected a value but got an error: %s", err) + } + + if actual.Scope != v.Expected.Scope { + t.Fatalf("Expected %q but got %q for Scope", v.Expected.Scope, actual.Scope) + } + + if actual.Name != v.Expected.Name { + t.Fatalf("Expected %q but got %q for Name", v.Expected.Name, actual.Name) + } + } +} diff --git a/azurerm/internal/services/lighthouse/parse/lighthouse_definition.go b/azurerm/internal/services/lighthouse/parse/lighthouse_definition.go new file mode 100644 index 000000000000..68086e8ac964 --- /dev/null +++ b/azurerm/internal/services/lighthouse/parse/lighthouse_definition.go @@ -0,0 +1,26 @@ +package parse + +import ( + "fmt" + "strings" +) + +type LighthouseDefinitionId struct { + Scope string + LighthouseDefinitionID string +} + +func LighthouseDefinitionID(id string) (*LighthouseDefinitionId, error) { + segments := strings.Split(id, "/providers/Microsoft.ManagedServices/registrationDefinitions/") + + if len(segments) != 2 { + return nil, fmt.Errorf("Expected ID to be in the format `{scope}/providers/Microsoft.ManagedServices/registrationDefinitions/{name} - got %d segments", len(segments)) + } + + lighthouseDefinitionId := LighthouseDefinitionId{ + Scope: segments[0], + LighthouseDefinitionID: segments[1], + } + + return &lighthouseDefinitionId, nil +} diff --git a/azurerm/internal/services/lighthouse/parse/lighthouse_definition_test.go b/azurerm/internal/services/lighthouse/parse/lighthouse_definition_test.go new file mode 100644 index 000000000000..51cdb89c97c7 --- /dev/null +++ b/azurerm/internal/services/lighthouse/parse/lighthouse_definition_test.go @@ -0,0 +1,58 @@ +package parse + +import ( + "testing" +) + +func TestLighthouseDefinitionID(t *testing.T) { + testData := []struct { + Name string + Input string + Expected *LighthouseDefinitionId + }{ + { + Name: "Empty", + Input: "", + Expected: nil, + }, + { + Name: "Missing Scope", + Input: "providers/Microsoft.ManagedServices/registrationDefinitions/00000000-0000-0000-0000-000000000000", + Expected: nil, + }, + { + Name: "Missing LighthouseDefinitionID", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ManagedServices/registrationDefinitions", + Expected: nil, + }, + { + Name: "Lighthouse Definition ID", + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/providers/Microsoft.ManagedServices/registrationDefinitions/00000000-0000-0000-0000-000000000000", + Expected: &LighthouseDefinitionId{ + LighthouseDefinitionID: "00000000-0000-0000-0000-000000000000", + Scope: "/subscriptions/00000000-0000-0000-0000-000000000000", + }, + }, + } + + for _, v := range testData { + t.Logf("[DEBUG] Testing %q..", v.Name) + + actual, err := LighthouseDefinitionID(v.Input) + if err != nil { + if v.Expected == nil { + continue + } + t.Fatalf("Expected a value but got an error: %s", err) + } + + if actual.Scope != v.Expected.Scope { + t.Fatalf("Expected %q but got %q for Scope", v.Expected.Scope, actual.Scope) + } + + if actual.LighthouseDefinitionID != v.Expected.LighthouseDefinitionID { + t.Fatalf("Expected %q but got %q for LighthouseDefinitionID", + v.Expected.LighthouseDefinitionID, actual.LighthouseDefinitionID) + } + } +} diff --git a/azurerm/internal/services/lighthouse/registration.go b/azurerm/internal/services/lighthouse/registration.go new file mode 100644 index 000000000000..eebf0b495ef9 --- /dev/null +++ b/azurerm/internal/services/lighthouse/registration.go @@ -0,0 +1,32 @@ +package lighthouse + +import ( + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +type Registration struct{} + +// Name is the name of this Service +func (r Registration) Name() string { + return "Lighthouse" +} + +// WebsiteCategories returns a list of categories which can be used for the sidebar +func (r Registration) WebsiteCategories() []string { + return []string{ + "Lighthouse", + } +} + +// SupportedDataSources returns the supported Data Sources supported by this Service +func (r Registration) SupportedDataSources() map[string]*schema.Resource { + return map[string]*schema.Resource{} +} + +// SupportedResources returns the supported Resources supported by this Service +func (r Registration) SupportedResources() map[string]*schema.Resource { + return map[string]*schema.Resource{ + "azurerm_lighthouse_definition": resourceArmLighthouseDefinition(), + "azurerm_lighthouse_assignment": resourceArmLighthouseAssignment(), + } +} diff --git a/azurerm/internal/services/lighthouse/resource_arm_lighthouse_assignment.go b/azurerm/internal/services/lighthouse/resource_arm_lighthouse_assignment.go new file mode 100644 index 000000000000..11fda40c2bb2 --- /dev/null +++ b/azurerm/internal/services/lighthouse/resource_arm_lighthouse_assignment.go @@ -0,0 +1,191 @@ +package lighthouse + +import ( + "context" + "fmt" + "log" + "time" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/lighthouse/validate" + + "github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices" + "github.com/hashicorp/go-uuid" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/lighthouse/parse" + subscriptionValidate "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/subscription/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmLighthouseAssignment() *schema.Resource { + return &schema.Resource{ + Create: resourceArmLighthouseAssignmentCreate, + Read: resourceArmLighthouseAssignmentRead, + Delete: resourceArmLighthouseAssignmentDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(30 * time.Minute), + Read: schema.DefaultTimeout(5 * time.Minute), + Delete: schema.DefaultTimeout(30 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + Computed: true, + ValidateFunc: validation.IsUUID, + }, + + "lighthouse_definition_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.LighthouseDefinitionID, + }, + + "scope": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: subscriptionValidate.SubscriptionID, + }, + }, + } +} + +func resourceArmLighthouseAssignmentCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).Lighthouse.AssignmentsClient + ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d) + defer cancel() + + lighthouseAssignmentName := d.Get("name").(string) + if lighthouseAssignmentName == "" { + uuid, err := uuid.GenerateUUID() + if err != nil { + return fmt.Errorf("Error generating UUID for Lighthouse Assignment: %+v", err) + } + + lighthouseAssignmentName = uuid + } + + scope := d.Get("scope").(string) + + existing, err := client.Get(ctx, scope, lighthouseAssignmentName, utils.Bool(false)) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("Error checking for presence of existing Lighthouse Assignment %q (Scope %q): %+v", lighthouseAssignmentName, scope, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_lighthouse_assignment", *existing.ID) + } + + parameters := managedservices.RegistrationAssignment{ + Properties: &managedservices.RegistrationAssignmentProperties{ + RegistrationDefinitionID: utils.String(d.Get("lighthouse_definition_id").(string)), + }, + } + + if _, err := client.CreateOrUpdate(ctx, scope, lighthouseAssignmentName, parameters); err != nil { + return fmt.Errorf("creating Lighthouse Assignment %q (Scope %q): %+v", lighthouseAssignmentName, scope, err) + } + + read, err := client.Get(ctx, scope, lighthouseAssignmentName, utils.Bool(false)) + if err != nil { + return fmt.Errorf("retrieving Lighthouse Assessment %q (Scope %q): %+v", lighthouseAssignmentName, scope, err) + } + + if read.ID == nil || *read.ID == "" { + return fmt.Errorf("ID was nil or empty for Lighthouse Assignment %q ID (scope %q) ID", lighthouseAssignmentName, scope) + } + + d.SetId(*read.ID) + + return resourceArmLighthouseAssignmentRead(d, meta) +} + +func resourceArmLighthouseAssignmentRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).Lighthouse.AssignmentsClient + ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) + defer cancel() + + id, err := parse.LighthouseAssignmentID(d.Id()) + if err != nil { + return err + } + + resp, err := client.Get(ctx, id.Scope, id.Name, utils.Bool(false)) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[WARN] Lighthouse Assignment %q was not found (Scope %q)", id.Name, id.Scope) + d.SetId("") + return nil + } + + return fmt.Errorf("Error making Read request on Lighthouse Assignment %q (Scope %q): %+v", id.Name, id.Scope, err) + } + + d.Set("name", resp.Name) + d.Set("scope", id.Scope) + + if props := resp.Properties; props != nil { + d.Set("lighthouse_definition_id", props.RegistrationDefinitionID) + } + + return nil +} + +func resourceArmLighthouseAssignmentDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).Lighthouse.AssignmentsClient + ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) + defer cancel() + + id, err := parse.LighthouseAssignmentID(d.Id()) + if err != nil { + return err + } + + _, err = client.Delete(ctx, id.Scope, id.Name) + if err != nil { + return fmt.Errorf("Error deleting Lighthouse Assignment %q at Scope %q: %+v", id.Name, id.Scope, err) + } + + stateConf := &resource.StateChangeConf{ + Pending: []string{"Deleting"}, + Target: []string{"Deleted"}, + Refresh: lighthouseAssignmentDeleteRefreshFunc(ctx, client, id.Scope, id.Name), + MinTimeout: 15 * time.Second, + Timeout: d.Timeout(schema.TimeoutDelete), + } + + if _, err := stateConf.WaitForState(); err != nil { + return fmt.Errorf("Error waiting for Lighthouse Assignment %q (Scope %q) to be deleted: %s", id.Name, id.Scope, err) + } + + return nil +} + +func lighthouseAssignmentDeleteRefreshFunc(ctx context.Context, client *managedservices.RegistrationAssignmentsClient, scope string, lighthouseAssignmentName string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + expandLighthouseDefinition := true + res, err := client.Get(ctx, scope, lighthouseAssignmentName, &expandLighthouseDefinition) + if err != nil { + if utils.ResponseWasNotFound(res.Response) { + return res, "Deleted", nil + } + return nil, "Error", fmt.Errorf("Error issuing read request in lighthouseAssignmentDeleteRefreshFunc to Lighthouse Assignment %q (Scope %q): %s", lighthouseAssignmentName, scope, err) + } + + return res, "Deleting", nil + } +} diff --git a/azurerm/internal/services/lighthouse/resource_arm_lighthouse_definition.go b/azurerm/internal/services/lighthouse/resource_arm_lighthouse_definition.go new file mode 100644 index 000000000000..73617bd6ff75 --- /dev/null +++ b/azurerm/internal/services/lighthouse/resource_arm_lighthouse_definition.go @@ -0,0 +1,249 @@ +package lighthouse + +import ( + "fmt" + "log" + "time" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/subscription/validate" + + "github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices" + "github.com/hashicorp/go-uuid" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/helper/validation" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/tf" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/lighthouse/parse" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func resourceArmLighthouseDefinition() *schema.Resource { + return &schema.Resource{ + Create: resourceArmLighthouseDefinitionCreateUpdate, + Read: resourceArmLighthouseDefinitionRead, + Update: resourceArmLighthouseDefinitionCreateUpdate, + Delete: resourceArmLighthouseDefinitionDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + + Timeouts: &schema.ResourceTimeout{ + Create: schema.DefaultTimeout(30 * time.Minute), + Read: schema.DefaultTimeout(5 * time.Minute), + Update: schema.DefaultTimeout(30 * time.Minute), + Delete: schema.DefaultTimeout(30 * time.Minute), + }, + + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringIsNotEmpty, + }, + + "managing_tenant_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validation.IsUUID, + }, + + "scope": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + ValidateFunc: validate.SubscriptionID, + }, + + "authorization": { + Type: schema.TypeSet, + Required: true, + MinItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "principal_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.IsUUID, + }, + + "role_definition_id": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.IsUUID, + }, + }, + }, + }, + + "description": { + Type: schema.TypeString, + Optional: true, + }, + + "lighthouse_definition_id": { + Type: schema.TypeString, + Optional: true, + Computed: true, + ForceNew: true, + ValidateFunc: validation.IsUUID, + }, + }, + } +} + +func resourceArmLighthouseDefinitionCreateUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).Lighthouse.DefinitionsClient + ctx, cancel := timeouts.ForCreateUpdate(meta.(*clients.Client).StopContext, d) + defer cancel() + + lighthouseDefinitionID := d.Get("lighthouse_definition_id").(string) + if lighthouseDefinitionID == "" { + uuid, err := uuid.GenerateUUID() + if err != nil { + return fmt.Errorf("Error generating UUID for Lighthouse Definition: %+v", err) + } + + lighthouseDefinitionID = uuid + } + + subscriptionID := meta.(*clients.Client).Account.SubscriptionId + if subscriptionID == "" { + return fmt.Errorf("Error reading Subscription for Lighthouse Definition %q", lighthouseDefinitionID) + } + + scope := d.Get("scope").(string) + + if d.IsNewResource() { + existing, err := client.Get(ctx, scope, lighthouseDefinitionID) + if err != nil { + if !utils.ResponseWasNotFound(existing.Response) { + return fmt.Errorf("checking for presence of existing Lighthouse Definition %q (Scope %q): %+v", lighthouseDefinitionID, scope, err) + } + } + + if existing.ID != nil && *existing.ID != "" { + return tf.ImportAsExistsError("azurerm_lighthouse_definition", *existing.ID) + } + } + + parameters := managedservices.RegistrationDefinition{ + Properties: &managedservices.RegistrationDefinitionProperties{ + Description: utils.String(d.Get("description").(string)), + Authorizations: expandLighthouseDefinitionAuthorization(d.Get("authorization").(*schema.Set).List()), + RegistrationDefinitionName: utils.String(d.Get("name").(string)), + ManagedByTenantID: utils.String(d.Get("managing_tenant_id").(string)), + }, + } + + if _, err := client.CreateOrUpdate(ctx, lighthouseDefinitionID, scope, parameters); err != nil { + return fmt.Errorf("Error Creating/Updating Lighthouse Definition %q (Scope %q): %+v", lighthouseDefinitionID, scope, err) + } + + read, err := client.Get(ctx, scope, lighthouseDefinitionID) + if err != nil { + return err + } + + if read.ID == nil { + return fmt.Errorf("Cannot read Lighthouse Definition %q ID (scope %q) ID", lighthouseDefinitionID, scope) + } + + d.SetId(*read.ID) + + return resourceArmLighthouseDefinitionRead(d, meta) +} + +func resourceArmLighthouseDefinitionRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).Lighthouse.DefinitionsClient + ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) + defer cancel() + + id, err := parse.LighthouseDefinitionID(d.Id()) + if err != nil { + return err + } + + resp, err := client.Get(ctx, id.Scope, id.LighthouseDefinitionID) + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + log.Printf("[WARN] Lighthouse Definition %q was not found (Scope %q)", id.LighthouseDefinitionID, id.Scope) + d.SetId("") + return nil + } + + return fmt.Errorf("Error making Read request on Lighthouse Definition %q (Scope %q): %+v", id.LighthouseDefinitionID, id.Scope, err) + } + + d.Set("lighthouse_definition_id", resp.Name) + d.Set("scope", id.Scope) + + if props := resp.Properties; props != nil { + if err := d.Set("authorization", flattenLighthouseDefinitionAuthorization(props.Authorizations)); err != nil { + return fmt.Errorf("setting `authorization`: %+v", err) + } + d.Set("description", props.Description) + d.Set("name", props.RegistrationDefinitionName) + d.Set("managing_tenant_id", props.ManagedByTenantID) + } + + return nil +} + +func resourceArmLighthouseDefinitionDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*clients.Client).Lighthouse.DefinitionsClient + ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) + defer cancel() + + id, err := parse.LighthouseDefinitionID(d.Id()) + if err != nil { + return err + } + + _, err = client.Delete(ctx, id.LighthouseDefinitionID, id.Scope) + if err != nil { + return fmt.Errorf("Error deleting Lighthouse Definition %q at Scope %q: %+v", id.LighthouseDefinitionID, id.Scope, err) + } + + return nil +} + +func flattenLighthouseDefinitionAuthorization(input *[]managedservices.Authorization) []interface{} { + results := make([]interface{}, 0) + if input == nil { + return results + } + + for _, item := range *input { + principalID := "" + if item.PrincipalID != nil { + principalID = *item.PrincipalID + } + + roleDefinitionID := "" + if item.RoleDefinitionID != nil { + roleDefinitionID = *item.RoleDefinitionID + } + + results = append(results, map[string]interface{}{ + "role_definition_id": roleDefinitionID, + "principal_id": principalID, + }) + } + + return results +} + +func expandLighthouseDefinitionAuthorization(input []interface{}) *[]managedservices.Authorization { + results := make([]managedservices.Authorization, 0) + for _, item := range input { + v := item.(map[string]interface{}) + result := managedservices.Authorization{ + RoleDefinitionID: utils.String(v["role_definition_id"].(string)), + PrincipalID: utils.String(v["principal_id"].(string)), + } + results = append(results, result) + } + return &results +} diff --git a/azurerm/internal/services/lighthouse/tests/data_source_lighthouse_definition_test.go b/azurerm/internal/services/lighthouse/tests/data_source_lighthouse_definition_test.go new file mode 100644 index 000000000000..22578c0ac7ee --- /dev/null +++ b/azurerm/internal/services/lighthouse/tests/data_source_lighthouse_definition_test.go @@ -0,0 +1,70 @@ +package tests + +import ( + "fmt" + "os" + "testing" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance" +) + +func TestAccDataSourceAzureRMLighthouseDefinition_basic(t *testing.T) { + // Multiple tenants are needed to test this resource. + // Second tenant ID needs to be set as a environment variable ARM_TENANT_ID_ALT. + // ObjectId for user, usergroup or service principal from second Tenant needs to be set as a environment variable ARM_PRINCIPAL_ID_ALT_TENANT. + secondTenantID := os.Getenv("ARM_TENANT_ID_ALT") + principalID := os.Getenv("ARM_PRINCIPAL_ID_ALT_TENANT") + data := acceptance.BuildTestData(t, "data.azurerm_lighthouse_definition", "test") + id := uuid.New().String() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourceLighthouseDefinition_basic(id, secondTenantID, principalID, data), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet(data.ResourceName, "id"), + resource.TestCheckResourceAttrSet(data.ResourceName, "scope"), + resource.TestMatchResourceAttr(data.ResourceName, "lighthouse_definition_id", validate.UUIDRegExp), + resource.TestCheckResourceAttr(data.ResourceName, "name", fmt.Sprintf("acctest-LD-%d", data.RandomInteger)), + resource.TestCheckResourceAttr(data.ResourceName, "description", "Acceptance Test Lighthouse Definition"), + resource.TestMatchResourceAttr(data.ResourceName, "managing_tenant_id", validate.UUIDRegExp), + resource.TestMatchResourceAttr(data.ResourceName, "authorization.0.principal_id", validate.UUIDRegExp), + resource.TestMatchResourceAttr(data.ResourceName, "authorization.0.role_definition_id", validate.UUIDRegExp), + ), + }, + }, + }) +} + +func testAccDataSourceLighthouseDefinition_basic(id string, secondTenantID string, principalID string, data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +data "azurerm_role_definition" "contributor" { + role_definition_id = "b24988ac-6180-42a0-ab88-20f7382dd24c" +} + +resource "azurerm_lighthouse_definition" "test" { + lighthouse_definition_id = "%s" + name = "acctest-LD-%d" + description = "Acceptance Test Lighthouse Definition" + managing_tenant_id = "%s" + + authorization { + principal_id = "%s" + role_definition_id = data.azurerm_role_definition.contributor.role_definition_id + } +} + +data "azurerm_lighthouse_definition" "test" { + lighthouse_definition_id = azurerm_lighthouse_definition.test.lighthouse_definition_id +} +`, id, data.RandomInteger, secondTenantID, principalID) +} diff --git a/azurerm/internal/services/lighthouse/tests/resource_arm_lighthouse_assignment_test.go b/azurerm/internal/services/lighthouse/tests/resource_arm_lighthouse_assignment_test.go new file mode 100644 index 000000000000..b0113adc7555 --- /dev/null +++ b/azurerm/internal/services/lighthouse/tests/resource_arm_lighthouse_assignment_test.go @@ -0,0 +1,216 @@ +package tests + +import ( + "fmt" + "os" + "testing" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMLighthouseAssignment_basic(t *testing.T) { + // Multiple tenants are needed to test this resource. + // Second tenant ID needs to be set as a environment variable ARM_TENANT_ID_ALT. + // ObjectId for user, usergroup or service principal from second Tenant needs to be set as a environment variable ARM_PRINCIPAL_ID_ALT_TENANT. + secondTenantID := os.Getenv("ARM_TENANT_ID_ALT") + principalID := os.Getenv("ARM_PRINCIPAL_ID_ALT_TENANT") + data := acceptance.BuildTestData(t, "azurerm_lighthouse_assignment", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMLighthouseAssignmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMLighthouseAssignment_basic(uuid.New().String(), secondTenantID, principalID, data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMLighthouseAssignmentExists(data.ResourceName), + resource.TestCheckResourceAttrSet(data.ResourceName, "name"), + ), + }, + }, + }) +} + +func TestAccAzureRMLighthouseAssignment_requiresImport(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_lighthouse_assignment", "test") + secondTenantID := os.Getenv("ARM_TENANT_ID_ALT") + principalID := os.Getenv("ARM_PRINCIPAL_ID_ALT_TENANT") + id := uuid.New().String() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMLighthouseAssignmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMLighthouseAssignment_basic(id, secondTenantID, principalID, data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMLighthouseAssignmentExists(data.ResourceName), + resource.TestCheckResourceAttrSet(data.ResourceName, "name"), + ), + }, + { + Config: testAccAzureRMLighthouseAssignment_requiresImport(id, secondTenantID, principalID, data), + ExpectError: acceptance.RequiresImportError("azurerm_lighthouse_assignment"), + }, + }, + }) +} + +func TestAccAzureRMLighthouseAssignment_emptyID(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_lighthouse_assignment", "test") + secondTenantID := os.Getenv("ARM_TENANT_ID_ALT") + principalID := os.Getenv("ARM_PRINCIPAL_ID_ALT_TENANT") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMLighthouseAssignmentDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMLighthouseAssignment_emptyId(secondTenantID, principalID, data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMLighthouseAssignmentExists(data.ResourceName), + resource.TestCheckResourceAttrSet(data.ResourceName, "id"), + resource.TestCheckResourceAttrSet(data.ResourceName, "name"), + ), + }, + }, + }) +} + +func testCheckAzureRMLighthouseAssignmentExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := acceptance.AzureProvider.Meta().(*clients.Client).Lighthouse.AssignmentsClient + ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext + + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %q", resourceName) + } + + scope := rs.Primary.Attributes["scope"] + lighthouseAssignmentName := rs.Primary.Attributes["name"] + expandLighthouseDefinition := true + + resp, err := client.Get(ctx, scope, lighthouseAssignmentName, &expandLighthouseDefinition) + + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Lighthouse Assignment %q (Scope: %q) does not exist", lighthouseAssignmentName, scope) + } + return fmt.Errorf("Bad: Get on LighthouseAssignmentsClient: %+v", err) + } + + return nil + } +} + +func testCheckAzureRMLighthouseAssignmentDestroy(s *terraform.State) error { + client := acceptance.AzureProvider.Meta().(*clients.Client).Lighthouse.AssignmentsClient + ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_lighthouse_assignment" { + continue + } + + scope := rs.Primary.Attributes["scope"] + lighthouseAssignmentName := rs.Primary.Attributes["name"] + expandLighthouseDefinition := true + + resp, err := client.Get(ctx, scope, lighthouseAssignmentName, &expandLighthouseDefinition) + + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return err + } + } + + return nil + } + + return nil +} + +func testAccAzureRMLighthouseAssignment_basic(id string, secondTenantID string, principalID string, data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +data "azurerm_subscription" "primary" { +} + +data "azurerm_role_definition" "contributor" { + role_definition_id = "b24988ac-6180-42a0-ab88-20f7382dd24c" +} + +resource "azurerm_lighthouse_definition" "test" { + name = "acctest-LD-%d" + description = "Acceptance Test Lighthouse Definition" + managing_tenant_id = "%s" + + authorization { + principal_id = "%s" + role_definition_id = data.azurerm_role_definition.contributor.role_definition_id + } +} + +resource "azurerm_lighthouse_assignment" "test" { + name = "%s" + scope = data.azurerm_subscription.primary.id + lighthouse_definition_id = azurerm_lighthouse_definition.test.id +} + +`, data.RandomInteger, secondTenantID, principalID, id) +} + +func testAccAzureRMLighthouseAssignment_requiresImport(id string, secondTenantID string, principalID string, data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +resource "azurerm_lighthouse_assignment" "import" { + name = azurerm_lighthouse_assignment.test.name + lighthouse_definition_id = azurerm_lighthouse_assignment.test.lighthouse_definition_id + scope = azurerm_lighthouse_assignment.test.scope +} +`, testAccAzureRMLighthouseAssignment_basic(id, secondTenantID, principalID, data)) +} + +func testAccAzureRMLighthouseAssignment_emptyId(secondTenantID string, principalID string, data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +data "azurerm_subscription" "primary" { +} + +data "azurerm_role_definition" "contributor" { + role_definition_id = "b24988ac-6180-42a0-ab88-20f7382dd24c" +} + +resource "azurerm_lighthouse_definition" "test" { + name = "acctest-LD-%d" + description = "Acceptance Test Lighthouse Definition" + managing_tenant_id = "%s" + + authorization { + principal_id = "%s" + role_definition_id = data.azurerm_role_definition.contributor.role_definition_id + } +} + +resource "azurerm_lighthouse_assignment" "test" { + scope = data.azurerm_subscription.primary.id + lighthouse_definition_id = azurerm_lighthouse_definition.test.id +} +`, data.RandomInteger, secondTenantID, principalID) +} diff --git a/azurerm/internal/services/lighthouse/tests/resource_arm_lighthouse_definition_test.go b/azurerm/internal/services/lighthouse/tests/resource_arm_lighthouse_definition_test.go new file mode 100644 index 000000000000..75c75fad2263 --- /dev/null +++ b/azurerm/internal/services/lighthouse/tests/resource_arm_lighthouse_definition_test.go @@ -0,0 +1,283 @@ +package tests + +import ( + "fmt" + "os" + "testing" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/validate" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils" +) + +func TestAccAzureRMLighthouseDefinition_basic(t *testing.T) { + // Multiple tenants are needed to test this resource. + // Second tenant ID needs to be set as a environment variable ARM_TENANT_ID_ALT. + // ObjectId for user, usergroup or service principal from second Tenant needs to be set as a environment variable ARM_PRINCIPAL_ID_ALT_TENANT. + secondTenantID := os.Getenv("ARM_TENANT_ID_ALT") + principalID := os.Getenv("ARM_PRINCIPAL_ID_ALT_TENANT") + data := acceptance.BuildTestData(t, "azurerm_lighthouse_definition", "test") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMLighthouseDefinitionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMLighthouseDefinition_basic(uuid.New().String(), secondTenantID, principalID, data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMLighthouseDefinitionExists(data.ResourceName), + resource.TestCheckResourceAttrSet(data.ResourceName, "scope"), + resource.TestMatchResourceAttr(data.ResourceName, "lighthouse_definition_id", validate.UUIDRegExp), + ), + }, + }, + }) +} + +func TestAccAzureRMLighthouseDefinition_requiresImport(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_lighthouse_definition", "test") + secondTenantID := os.Getenv("ARM_TENANT_ID_ALT") + principalID := os.Getenv("ARM_PRINCIPAL_ID_ALT_TENANT") + id := uuid.New().String() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMLighthouseDefinitionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMLighthouseDefinition_basic(id, secondTenantID, principalID, data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMLighthouseDefinitionExists(data.ResourceName), + resource.TestCheckResourceAttrSet(data.ResourceName, "scope"), + resource.TestMatchResourceAttr(data.ResourceName, "lighthouse_definition_id", validate.UUIDRegExp), + ), + }, + { + Config: testAccAzureRMLighthouseDefinition_requiresImport(id, secondTenantID, principalID, data), + ExpectError: acceptance.RequiresImportError("azurerm_lighthouse_definition"), + }, + }, + }) +} + +func TestAccAzureRMLighthouseDefinition_complete(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_lighthouse_definition", "test") + secondTenantID := os.Getenv("ARM_TENANT_ID_ALT") + principalID := os.Getenv("ARM_PRINCIPAL_ID_ALT_TENANT") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMLighthouseDefinitionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMLighthouseDefinition_complete(uuid.New().String(), secondTenantID, principalID, data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMLighthouseDefinitionExists(data.ResourceName), + resource.TestCheckResourceAttrSet(data.ResourceName, "scope"), + resource.TestMatchResourceAttr(data.ResourceName, "lighthouse_definition_id", validate.UUIDRegExp), + resource.TestCheckResourceAttr(data.ResourceName, "description", "Acceptance Test Lighthouse Definition"), + ), + }, + data.ImportStep("lighthouse_definition_id"), + }, + }) +} + +func TestAccAzureRMLighthouseDefinition_update(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_lighthouse_definition", "test") + secondTenantID := os.Getenv("ARM_TENANT_ID_ALT") + principalID := os.Getenv("ARM_PRINCIPAL_ID_ALT_TENANT") + id := uuid.New().String() + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMLighthouseDefinitionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMLighthouseDefinition_basic(id, secondTenantID, principalID, data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMLighthouseDefinitionExists(data.ResourceName), + resource.TestCheckResourceAttrSet(data.ResourceName, "scope"), + resource.TestMatchResourceAttr(data.ResourceName, "lighthouse_definition_id", validate.UUIDRegExp), + ), + }, + { + Config: testAccAzureRMLighthouseDefinition_complete(id, secondTenantID, principalID, data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMLighthouseDefinitionExists(data.ResourceName), + resource.TestCheckResourceAttrSet(data.ResourceName, "scope"), + resource.TestMatchResourceAttr(data.ResourceName, "lighthouse_definition_id", validate.UUIDRegExp), + resource.TestCheckResourceAttr(data.ResourceName, "description", "Acceptance Test Lighthouse Definition"), + ), + }, + }, + }) +} + +func TestAccAzureRMLighthouseDefinition_emptyID(t *testing.T) { + data := acceptance.BuildTestData(t, "azurerm_lighthouse_definition", "test") + secondTenantID := os.Getenv("ARM_TENANT_ID_ALT") + principalID := os.Getenv("ARM_PRINCIPAL_ID_ALT_TENANT") + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { acceptance.PreCheck(t) }, + Providers: acceptance.SupportedProviders, + CheckDestroy: testCheckAzureRMLighthouseDefinitionDestroy, + Steps: []resource.TestStep{ + { + Config: testAccAzureRMLighthouseDefinition_emptyId(secondTenantID, principalID, data), + Check: resource.ComposeTestCheckFunc( + testCheckAzureRMLighthouseDefinitionExists(data.ResourceName), + resource.TestCheckResourceAttrSet(data.ResourceName, "id"), + resource.TestCheckResourceAttrSet(data.ResourceName, "lighthouse_definition_id"), + ), + }, + }, + }) +} + +func testCheckAzureRMLighthouseDefinitionExists(resourceName string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := acceptance.AzureProvider.Meta().(*clients.Client).Lighthouse.DefinitionsClient + ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext + + rs, ok := s.RootModule().Resources[resourceName] + if !ok { + return fmt.Errorf("Not found: %q", resourceName) + } + + scope := rs.Primary.Attributes["scope"] + lighthouseDefinitionID := rs.Primary.Attributes["lighthouse_definition_id"] + + resp, err := client.Get(ctx, scope, lighthouseDefinitionID) + + if err != nil { + if utils.ResponseWasNotFound(resp.Response) { + return fmt.Errorf("Bad: Lighthouse Definition %q (Scope: %q) does not exist", lighthouseDefinitionID, scope) + } + return fmt.Errorf("Bad: Get on lighthouseDefinitionsClient: %+v", err) + } + + return nil + } +} + +func testCheckAzureRMLighthouseDefinitionDestroy(s *terraform.State) error { + client := acceptance.AzureProvider.Meta().(*clients.Client).Lighthouse.DefinitionsClient + ctx := acceptance.AzureProvider.Meta().(*clients.Client).StopContext + + for _, rs := range s.RootModule().Resources { + if rs.Type != "azurerm_lighthouse_definition" { + continue + } + + scope := rs.Primary.Attributes["scope"] + lighthouseDefinitionID := rs.Primary.Attributes["lighthouse_definition_id"] + + resp, err := client.Get(ctx, scope, lighthouseDefinitionID) + + if err != nil { + if !utils.ResponseWasNotFound(resp.Response) { + return err + } + } + + return nil + } + + return nil +} + +func testAccAzureRMLighthouseDefinition_basic(id string, secondTenantID string, principalID string, data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +data "azurerm_role_definition" "contributor" { + role_definition_id = "b24988ac-6180-42a0-ab88-20f7382dd24c" +} + +resource "azurerm_lighthouse_definition" "test" { + lighthouse_definition_id = "%s" + name = "acctest-LD-%d" + managing_tenant_id = "%s" + + authorization { + principal_id = "%s" + role_definition_id = data.azurerm_role_definition.contributor.role_definition_id + } +} +`, id, data.RandomInteger, secondTenantID, principalID) +} + +func testAccAzureRMLighthouseDefinition_requiresImport(id string, secondTenantID string, principalID string, data acceptance.TestData) string { + return fmt.Sprintf(` +%s + +resource "azurerm_lighthouse_definition" "import" { + name = azurerm_lighthouse_definition.test.name + lighthouse_definition_id = azurerm_lighthouse_definition.test.lighthouse_definition_id + managing_tenant_id = azurerm_lighthouse_definition.test.managing_tenant_id + authorization { + principal_id = azurerm_lighthouse_definition.test.managing_tenant_id + role_definition_id = "b24988ac-6180-42a0-ab88-20f7382dd24c" + } +} +`, testAccAzureRMLighthouseDefinition_basic(id, secondTenantID, principalID, data)) +} + +func testAccAzureRMLighthouseDefinition_complete(id string, secondTenantID string, principalID string, data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +data "azurerm_role_definition" "contributor" { + role_definition_id = "b24988ac-6180-42a0-ab88-20f7382dd24c" +} + +resource "azurerm_lighthouse_definition" "test" { + lighthouse_definition_id = "%s" + name = "acctest-LD-%d" + description = "Acceptance Test Lighthouse Definition" + managing_tenant_id = "%s" + + authorization { + principal_id = "%s" + role_definition_id = data.azurerm_role_definition.contributor.role_definition_id + } +} +`, id, data.RandomInteger, secondTenantID, principalID) +} + +func testAccAzureRMLighthouseDefinition_emptyId(secondTenantID string, principalID string, data acceptance.TestData) string { + return fmt.Sprintf(` +provider "azurerm" { + features {} +} + +data "azurerm_role_definition" "contributor" { + role_definition_id = "b24988ac-6180-42a0-ab88-20f7382dd24c" +} + +resource "azurerm_lighthouse_definition" "test" { + name = "acctest-LD-%d" + description = "Acceptance Test Lighthouse Definition" + managing_tenant_id = "%s" + + authorization { + principal_id = "%s" + role_definition_id = data.azurerm_role_definition.contributor.role_definition_id + } +} +`, data.RandomInteger, secondTenantID, principalID) +} diff --git a/azurerm/internal/services/lighthouse/validate/lighthouse_definition_id.go b/azurerm/internal/services/lighthouse/validate/lighthouse_definition_id.go new file mode 100644 index 000000000000..8f75f53166da --- /dev/null +++ b/azurerm/internal/services/lighthouse/validate/lighthouse_definition_id.go @@ -0,0 +1,22 @@ +package validate + +import ( + "fmt" + + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/lighthouse/parse" +) + +func LighthouseDefinitionID(i interface{}, k string) (warnings []string, errors []error) { + v, ok := i.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected type of %q to be string", k)) + return + } + + if _, err := parse.LighthouseDefinitionID(v); err != nil { + errors = append(errors, fmt.Errorf("cannot parse %q as a resource id: %v", k, err)) + return + } + + return +} diff --git a/azurerm/internal/services/subscription/validate/subscription_id.go b/azurerm/internal/services/subscription/validate/subscription_id.go new file mode 100644 index 000000000000..570b990ec48f --- /dev/null +++ b/azurerm/internal/services/subscription/validate/subscription_id.go @@ -0,0 +1,32 @@ +package validate + +import ( + "fmt" + + "github.com/hashicorp/go-uuid" + "github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure" +) + +func SubscriptionID(i interface{}, k string) (warnings []string, errors []error) { + v, ok := i.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected type of %q to be string", k)) + return + } + id, err := azure.ParseAzureResourceID(v) + if err != nil { + errors = append(errors, fmt.Errorf("%q expected to be valid subscription ID, got %q", k, v)) + return + } + + if _, err := uuid.ParseUUID(id.SubscriptionID); err != nil { + errors = append(errors, fmt.Errorf("expected subscription id value in %q to be a valid UUID, got %v", v, id.SubscriptionID)) + } + + if id.ResourceGroup != "" || len(id.Path) > 0 { + errors = append(errors, fmt.Errorf("%q expected to be valid subscription ID, got other ID type %q", k, v)) + return + } + + return +} diff --git a/azurerm/internal/services/subscription/validate/subscription_id_test.go b/azurerm/internal/services/subscription/validate/subscription_id_test.go new file mode 100644 index 000000000000..5f36e5f0681d --- /dev/null +++ b/azurerm/internal/services/subscription/validate/subscription_id_test.go @@ -0,0 +1,49 @@ +package validate + +import "testing" + +func TestSubscriptionID(t *testing.T) { + cases := []struct { + Input string + Valid bool + }{ + { + Input: "", + Valid: false, + }, + { + Input: "NotASubscriptionID", + Valid: false, + }, + { + Input: "/subscriptions/", + Valid: false, + }, + { + Input: "/subscriptions/StillNotAValidSubscription", + Valid: false, + }, + { + Input: "/subscriptions/00000000-0000-0000-0000-000000000000", + Valid: true, + }, + { + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups", + Valid: false, + }, + { + Input: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/myGroup1", + Valid: false, + }, + } + + for _, tc := range cases { + _, errors := SubscriptionID(tc.Input, "") + + valid := len(errors) == 0 + + if tc.Valid != valid { + t.Fatalf("Expected %t but got %t for %q", tc.Valid, valid, tc.Input) + } + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices/client.go b/vendor/github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices/client.go new file mode 100644 index 000000000000..3a1816f9f123 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices/client.go @@ -0,0 +1,50 @@ +// Package managedservices implements the Azure ARM Managedservices service API version 2019-06-01. +// +// Specification for ManagedServices. +package managedservices + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "github.com/Azure/go-autorest/autorest" +) + +const ( + // DefaultBaseURI is the default URI used for the service Managedservices + DefaultBaseURI = "https://management.azure.com" +) + +// BaseClient is the base client for Managedservices. +type BaseClient struct { + autorest.Client + BaseURI string +} + +// New creates an instance of the BaseClient client. +func New() BaseClient { + return NewWithBaseURI(DefaultBaseURI) +} + +// NewWithBaseURI creates an instance of the BaseClient client using a custom endpoint. Use this when interacting with +// an Azure cloud that uses a non-standard base URI (sovereign clouds, Azure stack). +func NewWithBaseURI(baseURI string) BaseClient { + return BaseClient{ + Client: autorest.NewClientWithUserAgent(UserAgent()), + BaseURI: baseURI, + } +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices/models.go b/vendor/github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices/models.go new file mode 100644 index 000000000000..cc5e3a4131b2 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices/models.go @@ -0,0 +1,593 @@ +package managedservices + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/to" + "github.com/Azure/go-autorest/tracing" + "net/http" +) + +// The package's fully qualified name. +const fqdn = "github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices" + +// ProvisioningState enumerates the values for provisioning state. +type ProvisioningState string + +const ( + // Accepted ... + Accepted ProvisioningState = "Accepted" + // Canceled ... + Canceled ProvisioningState = "Canceled" + // Created ... + Created ProvisioningState = "Created" + // Creating ... + Creating ProvisioningState = "Creating" + // Deleted ... + Deleted ProvisioningState = "Deleted" + // Deleting ... + Deleting ProvisioningState = "Deleting" + // Failed ... + Failed ProvisioningState = "Failed" + // NotSpecified ... + NotSpecified ProvisioningState = "NotSpecified" + // Ready ... + Ready ProvisioningState = "Ready" + // Running ... + Running ProvisioningState = "Running" + // Succeeded ... + Succeeded ProvisioningState = "Succeeded" + // Updating ... + Updating ProvisioningState = "Updating" +) + +// PossibleProvisioningStateValues returns an array of possible values for the ProvisioningState const type. +func PossibleProvisioningStateValues() []ProvisioningState { + return []ProvisioningState{Accepted, Canceled, Created, Creating, Deleted, Deleting, Failed, NotSpecified, Ready, Running, Succeeded, Updating} +} + +// Authorization authorization tuple containing principal Id (of user/service principal/security group) and +// role definition id. +type Authorization struct { + // PrincipalID - Principal Id of the security group/service principal/user that would be assigned permissions to the projected subscription + PrincipalID *string `json:"principalId,omitempty"` + // RoleDefinitionID - The role definition identifier. This role will define all the permissions that the security group/service principal/user must have on the projected subscription. This role cannot be an owner role. + RoleDefinitionID *string `json:"roleDefinitionId,omitempty"` +} + +// ErrorResponse error response. +type ErrorResponse struct { + // Error - READ-ONLY; Error response indicates Azure Resource Manager is not able to process the incoming request. The reason is provided in the error message. + Error *ErrorResponseError `json:"error,omitempty"` +} + +// ErrorResponseError error response indicates Azure Resource Manager is not able to process the incoming +// request. The reason is provided in the error message. +type ErrorResponseError struct { + // Code - Error code. + Code *string `json:"code,omitempty"` + // Message - Error message indicating why the operation failed. + Message *string `json:"message,omitempty"` +} + +// Operation object that describes a single Microsoft.ManagedServices operation. +type Operation struct { + // Name - READ-ONLY; Operation name: {provider}/{resource}/{operation} + Name *string `json:"name,omitempty"` + // Display - READ-ONLY; The object that represents the operation. + Display *OperationDisplay `json:"display,omitempty"` +} + +// OperationDisplay the object that represents the operation. +type OperationDisplay struct { + // Provider - Service provider: Microsoft.ManagedServices + Provider *string `json:"provider,omitempty"` + // Resource - Resource on which the operation is performed: Registration definition, registration assignment etc. + Resource *string `json:"resource,omitempty"` + // Operation - Operation type: Read, write, delete, etc. + Operation *string `json:"operation,omitempty"` + // Description - Description of the operation. + Description *string `json:"description,omitempty"` +} + +// OperationList list of the operations. +type OperationList struct { + autorest.Response `json:"-"` + // Value - READ-ONLY; List of Microsoft.ManagedServices operations. + Value *[]Operation `json:"value,omitempty"` +} + +// Plan plan details for the managed services. +type Plan struct { + // Name - The plan name. + Name *string `json:"name,omitempty"` + // Publisher - The publisher ID. + Publisher *string `json:"publisher,omitempty"` + // Product - The product code. + Product *string `json:"product,omitempty"` + // Version - The plan's version. + Version *string `json:"version,omitempty"` +} + +// RegistrationAssignment registration assignment. +type RegistrationAssignment struct { + autorest.Response `json:"-"` + // Properties - Properties of a registration assignment. + Properties *RegistrationAssignmentProperties `json:"properties,omitempty"` + // ID - READ-ONLY; The fully qualified path of the registration assignment. + ID *string `json:"id,omitempty"` + // Type - READ-ONLY; Type of the resource. + Type *string `json:"type,omitempty"` + // Name - READ-ONLY; Name of the registration assignment. + Name *string `json:"name,omitempty"` +} + +// RegistrationAssignmentList list of registration assignments. +type RegistrationAssignmentList struct { + autorest.Response `json:"-"` + // Value - READ-ONLY; List of registration assignments. + Value *[]RegistrationAssignment `json:"value,omitempty"` + // NextLink - READ-ONLY; Link to next page of registration assignments. + NextLink *string `json:"nextLink,omitempty"` +} + +// RegistrationAssignmentListIterator provides access to a complete listing of RegistrationAssignment +// values. +type RegistrationAssignmentListIterator struct { + i int + page RegistrationAssignmentListPage +} + +// NextWithContext advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *RegistrationAssignmentListIterator) NextWithContext(ctx context.Context) (err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RegistrationAssignmentListIterator.NextWithContext") + defer func() { + sc := -1 + if iter.Response().Response.Response != nil { + sc = iter.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err = iter.page.NextWithContext(ctx) + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +// Deprecated: Use NextWithContext() instead. +func (iter *RegistrationAssignmentListIterator) Next() error { + return iter.NextWithContext(context.Background()) +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter RegistrationAssignmentListIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter RegistrationAssignmentListIterator) Response() RegistrationAssignmentList { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter RegistrationAssignmentListIterator) Value() RegistrationAssignment { + if !iter.page.NotDone() { + return RegistrationAssignment{} + } + return iter.page.Values()[iter.i] +} + +// Creates a new instance of the RegistrationAssignmentListIterator type. +func NewRegistrationAssignmentListIterator(page RegistrationAssignmentListPage) RegistrationAssignmentListIterator { + return RegistrationAssignmentListIterator{page: page} +} + +// IsEmpty returns true if the ListResult contains no values. +func (ral RegistrationAssignmentList) IsEmpty() bool { + return ral.Value == nil || len(*ral.Value) == 0 +} + +// registrationAssignmentListPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (ral RegistrationAssignmentList) registrationAssignmentListPreparer(ctx context.Context) (*http.Request, error) { + if ral.NextLink == nil || len(to.String(ral.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare((&http.Request{}).WithContext(ctx), + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(ral.NextLink))) +} + +// RegistrationAssignmentListPage contains a page of RegistrationAssignment values. +type RegistrationAssignmentListPage struct { + fn func(context.Context, RegistrationAssignmentList) (RegistrationAssignmentList, error) + ral RegistrationAssignmentList +} + +// NextWithContext advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *RegistrationAssignmentListPage) NextWithContext(ctx context.Context) (err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RegistrationAssignmentListPage.NextWithContext") + defer func() { + sc := -1 + if page.Response().Response.Response != nil { + sc = page.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + next, err := page.fn(ctx, page.ral) + if err != nil { + return err + } + page.ral = next + return nil +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +// Deprecated: Use NextWithContext() instead. +func (page *RegistrationAssignmentListPage) Next() error { + return page.NextWithContext(context.Background()) +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page RegistrationAssignmentListPage) NotDone() bool { + return !page.ral.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page RegistrationAssignmentListPage) Response() RegistrationAssignmentList { + return page.ral +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page RegistrationAssignmentListPage) Values() []RegistrationAssignment { + if page.ral.IsEmpty() { + return nil + } + return *page.ral.Value +} + +// Creates a new instance of the RegistrationAssignmentListPage type. +func NewRegistrationAssignmentListPage(getNextPage func(context.Context, RegistrationAssignmentList) (RegistrationAssignmentList, error)) RegistrationAssignmentListPage { + return RegistrationAssignmentListPage{fn: getNextPage} +} + +// RegistrationAssignmentProperties properties of a registration assignment. +type RegistrationAssignmentProperties struct { + // RegistrationDefinitionID - Fully qualified path of the registration definition. + RegistrationDefinitionID *string `json:"registrationDefinitionId,omitempty"` + // ProvisioningState - READ-ONLY; Current state of the registration assignment. Possible values include: 'NotSpecified', 'Accepted', 'Running', 'Ready', 'Creating', 'Created', 'Deleting', 'Deleted', 'Canceled', 'Failed', 'Succeeded', 'Updating' + ProvisioningState ProvisioningState `json:"provisioningState,omitempty"` + // RegistrationDefinition - READ-ONLY; Registration definition inside registration assignment. + RegistrationDefinition *RegistrationAssignmentPropertiesRegistrationDefinition `json:"registrationDefinition,omitempty"` +} + +// RegistrationAssignmentPropertiesRegistrationDefinition registration definition inside registration +// assignment. +type RegistrationAssignmentPropertiesRegistrationDefinition struct { + // Properties - Properties of registration definition inside registration assignment. + Properties *RegistrationAssignmentPropertiesRegistrationDefinitionProperties `json:"properties,omitempty"` + // Plan - Plan details for the managed services. + Plan *Plan `json:"plan,omitempty"` + // ID - READ-ONLY; Fully qualified path of the registration definition. + ID *string `json:"id,omitempty"` + // Type - READ-ONLY; Type of the resource (Microsoft.ManagedServices/registrationDefinitions). + Type *string `json:"type,omitempty"` + // Name - READ-ONLY; Name of the registration definition. + Name *string `json:"name,omitempty"` +} + +// RegistrationAssignmentPropertiesRegistrationDefinitionProperties properties of registration definition +// inside registration assignment. +type RegistrationAssignmentPropertiesRegistrationDefinitionProperties struct { + // Description - Description of the registration definition. + Description *string `json:"description,omitempty"` + // Authorizations - Authorization tuple containing principal id of the user/security group or service principal and id of the build-in role. + Authorizations *[]Authorization `json:"authorizations,omitempty"` + // RegistrationDefinitionName - Name of the registration definition. + RegistrationDefinitionName *string `json:"registrationDefinitionName,omitempty"` + // ProvisioningState - Current state of the registration definition. Possible values include: 'NotSpecified', 'Accepted', 'Running', 'Ready', 'Creating', 'Created', 'Deleting', 'Deleted', 'Canceled', 'Failed', 'Succeeded', 'Updating' + ProvisioningState ProvisioningState `json:"provisioningState,omitempty"` + // ManageeTenantID - Id of the home tenant. + ManageeTenantID *string `json:"manageeTenantId,omitempty"` + // ManageeTenantName - Name of the home tenant. + ManageeTenantName *string `json:"manageeTenantName,omitempty"` + // ManagedByTenantID - Id of the managedBy tenant. + ManagedByTenantID *string `json:"managedByTenantId,omitempty"` + // ManagedByTenantName - Name of the managedBy tenant. + ManagedByTenantName *string `json:"managedByTenantName,omitempty"` +} + +// RegistrationAssignmentsCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of +// a long-running operation. +type RegistrationAssignmentsCreateOrUpdateFuture struct { + azure.Future +} + +// Result returns the result of the asynchronous operation. +// If the operation has not completed it will return an error. +func (future *RegistrationAssignmentsCreateOrUpdateFuture) Result(client RegistrationAssignmentsClient) (ra RegistrationAssignment, err error) { + var done bool + done, err = future.DoneWithContext(context.Background(), client) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationAssignmentsCreateOrUpdateFuture", "Result", future.Response(), "Polling failure") + return + } + if !done { + err = azure.NewAsyncOpIncompleteError("managedservices.RegistrationAssignmentsCreateOrUpdateFuture") + return + } + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if ra.Response.Response, err = future.GetResult(sender); err == nil && ra.Response.Response.StatusCode != http.StatusNoContent { + ra, err = client.CreateOrUpdateResponder(ra.Response.Response) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationAssignmentsCreateOrUpdateFuture", "Result", ra.Response.Response, "Failure responding to request") + } + } + return +} + +// RegistrationAssignmentsDeleteFuture an abstraction for monitoring and retrieving the results of a +// long-running operation. +type RegistrationAssignmentsDeleteFuture struct { + azure.Future +} + +// Result returns the result of the asynchronous operation. +// If the operation has not completed it will return an error. +func (future *RegistrationAssignmentsDeleteFuture) Result(client RegistrationAssignmentsClient) (ar autorest.Response, err error) { + var done bool + done, err = future.DoneWithContext(context.Background(), client) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationAssignmentsDeleteFuture", "Result", future.Response(), "Polling failure") + return + } + if !done { + err = azure.NewAsyncOpIncompleteError("managedservices.RegistrationAssignmentsDeleteFuture") + return + } + ar.Response = future.Response() + return +} + +// RegistrationDefinition registration definition. +type RegistrationDefinition struct { + autorest.Response `json:"-"` + // Properties - Properties of a registration definition. + Properties *RegistrationDefinitionProperties `json:"properties,omitempty"` + // Plan - Plan details for the managed services. + Plan *Plan `json:"plan,omitempty"` + // ID - READ-ONLY; Fully qualified path of the registration definition. + ID *string `json:"id,omitempty"` + // Type - READ-ONLY; Type of the resource. + Type *string `json:"type,omitempty"` + // Name - READ-ONLY; Name of the registration definition. + Name *string `json:"name,omitempty"` +} + +// RegistrationDefinitionList list of registration definitions. +type RegistrationDefinitionList struct { + autorest.Response `json:"-"` + // Value - READ-ONLY; List of registration definitions. + Value *[]RegistrationDefinition `json:"value,omitempty"` + // NextLink - READ-ONLY; Link to next page of registration definitions. + NextLink *string `json:"nextLink,omitempty"` +} + +// RegistrationDefinitionListIterator provides access to a complete listing of RegistrationDefinition +// values. +type RegistrationDefinitionListIterator struct { + i int + page RegistrationDefinitionListPage +} + +// NextWithContext advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +func (iter *RegistrationDefinitionListIterator) NextWithContext(ctx context.Context) (err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RegistrationDefinitionListIterator.NextWithContext") + defer func() { + sc := -1 + if iter.Response().Response.Response != nil { + sc = iter.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + iter.i++ + if iter.i < len(iter.page.Values()) { + return nil + } + err = iter.page.NextWithContext(ctx) + if err != nil { + iter.i-- + return err + } + iter.i = 0 + return nil +} + +// Next advances to the next value. If there was an error making +// the request the iterator does not advance and the error is returned. +// Deprecated: Use NextWithContext() instead. +func (iter *RegistrationDefinitionListIterator) Next() error { + return iter.NextWithContext(context.Background()) +} + +// NotDone returns true if the enumeration should be started or is not yet complete. +func (iter RegistrationDefinitionListIterator) NotDone() bool { + return iter.page.NotDone() && iter.i < len(iter.page.Values()) +} + +// Response returns the raw server response from the last page request. +func (iter RegistrationDefinitionListIterator) Response() RegistrationDefinitionList { + return iter.page.Response() +} + +// Value returns the current value or a zero-initialized value if the +// iterator has advanced beyond the end of the collection. +func (iter RegistrationDefinitionListIterator) Value() RegistrationDefinition { + if !iter.page.NotDone() { + return RegistrationDefinition{} + } + return iter.page.Values()[iter.i] +} + +// Creates a new instance of the RegistrationDefinitionListIterator type. +func NewRegistrationDefinitionListIterator(page RegistrationDefinitionListPage) RegistrationDefinitionListIterator { + return RegistrationDefinitionListIterator{page: page} +} + +// IsEmpty returns true if the ListResult contains no values. +func (rdl RegistrationDefinitionList) IsEmpty() bool { + return rdl.Value == nil || len(*rdl.Value) == 0 +} + +// registrationDefinitionListPreparer prepares a request to retrieve the next set of results. +// It returns nil if no more results exist. +func (rdl RegistrationDefinitionList) registrationDefinitionListPreparer(ctx context.Context) (*http.Request, error) { + if rdl.NextLink == nil || len(to.String(rdl.NextLink)) < 1 { + return nil, nil + } + return autorest.Prepare((&http.Request{}).WithContext(ctx), + autorest.AsJSON(), + autorest.AsGet(), + autorest.WithBaseURL(to.String(rdl.NextLink))) +} + +// RegistrationDefinitionListPage contains a page of RegistrationDefinition values. +type RegistrationDefinitionListPage struct { + fn func(context.Context, RegistrationDefinitionList) (RegistrationDefinitionList, error) + rdl RegistrationDefinitionList +} + +// NextWithContext advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +func (page *RegistrationDefinitionListPage) NextWithContext(ctx context.Context) (err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RegistrationDefinitionListPage.NextWithContext") + defer func() { + sc := -1 + if page.Response().Response.Response != nil { + sc = page.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + next, err := page.fn(ctx, page.rdl) + if err != nil { + return err + } + page.rdl = next + return nil +} + +// Next advances to the next page of values. If there was an error making +// the request the page does not advance and the error is returned. +// Deprecated: Use NextWithContext() instead. +func (page *RegistrationDefinitionListPage) Next() error { + return page.NextWithContext(context.Background()) +} + +// NotDone returns true if the page enumeration should be started or is not yet complete. +func (page RegistrationDefinitionListPage) NotDone() bool { + return !page.rdl.IsEmpty() +} + +// Response returns the raw server response from the last page request. +func (page RegistrationDefinitionListPage) Response() RegistrationDefinitionList { + return page.rdl +} + +// Values returns the slice of values for the current page or nil if there are no values. +func (page RegistrationDefinitionListPage) Values() []RegistrationDefinition { + if page.rdl.IsEmpty() { + return nil + } + return *page.rdl.Value +} + +// Creates a new instance of the RegistrationDefinitionListPage type. +func NewRegistrationDefinitionListPage(getNextPage func(context.Context, RegistrationDefinitionList) (RegistrationDefinitionList, error)) RegistrationDefinitionListPage { + return RegistrationDefinitionListPage{fn: getNextPage} +} + +// RegistrationDefinitionProperties properties of a registration definition. +type RegistrationDefinitionProperties struct { + // Description - Description of the registration definition. + Description *string `json:"description,omitempty"` + // Authorizations - Authorization tuple containing principal id of the user/security group or service principal and id of the build-in role. + Authorizations *[]Authorization `json:"authorizations,omitempty"` + // RegistrationDefinitionName - Name of the registration definition. + RegistrationDefinitionName *string `json:"registrationDefinitionName,omitempty"` + // ManagedByTenantID - Id of the managedBy tenant. + ManagedByTenantID *string `json:"managedByTenantId,omitempty"` + // ProvisioningState - READ-ONLY; Current state of the registration definition. Possible values include: 'NotSpecified', 'Accepted', 'Running', 'Ready', 'Creating', 'Created', 'Deleting', 'Deleted', 'Canceled', 'Failed', 'Succeeded', 'Updating' + ProvisioningState ProvisioningState `json:"provisioningState,omitempty"` + // ManagedByTenantName - READ-ONLY; Name of the managedBy tenant. + ManagedByTenantName *string `json:"managedByTenantName,omitempty"` +} + +// RegistrationDefinitionsCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of +// a long-running operation. +type RegistrationDefinitionsCreateOrUpdateFuture struct { + azure.Future +} + +// Result returns the result of the asynchronous operation. +// If the operation has not completed it will return an error. +func (future *RegistrationDefinitionsCreateOrUpdateFuture) Result(client RegistrationDefinitionsClient) (rd RegistrationDefinition, err error) { + var done bool + done, err = future.DoneWithContext(context.Background(), client) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationDefinitionsCreateOrUpdateFuture", "Result", future.Response(), "Polling failure") + return + } + if !done { + err = azure.NewAsyncOpIncompleteError("managedservices.RegistrationDefinitionsCreateOrUpdateFuture") + return + } + sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if rd.Response.Response, err = future.GetResult(sender); err == nil && rd.Response.Response.StatusCode != http.StatusNoContent { + rd, err = client.CreateOrUpdateResponder(rd.Response.Response) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationDefinitionsCreateOrUpdateFuture", "Result", rd.Response.Response, "Failure responding to request") + } + } + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices/operations.go b/vendor/github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices/operations.go new file mode 100644 index 000000000000..1e261956783b --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices/operations.go @@ -0,0 +1,108 @@ +package managedservices + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/tracing" + "net/http" +) + +// OperationsClient is the specification for ManagedServices. +type OperationsClient struct { + BaseClient +} + +// NewOperationsClient creates an instance of the OperationsClient client. +func NewOperationsClient() OperationsClient { + return NewOperationsClientWithBaseURI(DefaultBaseURI) +} + +// NewOperationsClientWithBaseURI creates an instance of the OperationsClient client using a custom endpoint. Use this +// when interacting with an Azure cloud that uses a non-standard base URI (sovereign clouds, Azure stack). +func NewOperationsClientWithBaseURI(baseURI string) OperationsClient { + return OperationsClient{NewWithBaseURI(baseURI)} +} + +// List gets a list of the operations. +func (client OperationsClient) List(ctx context.Context) (result OperationList, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/OperationsClient.List") + defer func() { + sc := -1 + if result.Response.Response != nil { + sc = result.Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + req, err := client.ListPreparer(ctx) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.OperationsClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "managedservices.OperationsClient", "List", resp, "Failure sending request") + return + } + + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.OperationsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client OperationsClient) ListPreparer(ctx context.Context) (*http.Request, error) { + const APIVersion = "2019-06-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPath("/providers/Microsoft.ManagedServices/operations"), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client OperationsClient) ListSender(req *http.Request) (*http.Response, error) { + return client.Send(req, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client OperationsClient) ListResponder(resp *http.Response) (result OperationList, err error) { + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices/registrationassignments.go b/vendor/github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices/registrationassignments.go new file mode 100644 index 000000000000..dda1adde8aac --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices/registrationassignments.go @@ -0,0 +1,407 @@ +package managedservices + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "github.com/Azure/go-autorest/tracing" + "net/http" +) + +// RegistrationAssignmentsClient is the specification for ManagedServices. +type RegistrationAssignmentsClient struct { + BaseClient +} + +// NewRegistrationAssignmentsClient creates an instance of the RegistrationAssignmentsClient client. +func NewRegistrationAssignmentsClient() RegistrationAssignmentsClient { + return NewRegistrationAssignmentsClientWithBaseURI(DefaultBaseURI) +} + +// NewRegistrationAssignmentsClientWithBaseURI creates an instance of the RegistrationAssignmentsClient client using a +// custom endpoint. Use this when interacting with an Azure cloud that uses a non-standard base URI (sovereign clouds, +// Azure stack). +func NewRegistrationAssignmentsClientWithBaseURI(baseURI string) RegistrationAssignmentsClient { + return RegistrationAssignmentsClient{NewWithBaseURI(baseURI)} +} + +// CreateOrUpdate creates or updates a registration assignment. +// Parameters: +// scope - scope of the resource. +// registrationAssignmentID - guid of the registration assignment. +// requestBody - the parameters required to create new registration assignment. +func (client RegistrationAssignmentsClient) CreateOrUpdate(ctx context.Context, scope string, registrationAssignmentID string, requestBody RegistrationAssignment) (result RegistrationAssignmentsCreateOrUpdateFuture, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RegistrationAssignmentsClient.CreateOrUpdate") + defer func() { + sc := -1 + if result.Response() != nil { + sc = result.Response().StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + if err := validation.Validate([]validation.Validation{ + {TargetValue: requestBody, + Constraints: []validation.Constraint{{Target: "requestBody.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "requestBody.Properties.RegistrationDefinitionID", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "requestBody.Properties.RegistrationDefinition", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "requestBody.Properties.RegistrationDefinition.Plan", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "requestBody.Properties.RegistrationDefinition.Plan.Name", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "requestBody.Properties.RegistrationDefinition.Plan.Publisher", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "requestBody.Properties.RegistrationDefinition.Plan.Product", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "requestBody.Properties.RegistrationDefinition.Plan.Version", Name: validation.Null, Rule: true, Chain: nil}, + }}, + }}, + }}}}}); err != nil { + return result, validation.NewError("managedservices.RegistrationAssignmentsClient", "CreateOrUpdate", err.Error()) + } + + req, err := client.CreateOrUpdatePreparer(ctx, scope, registrationAssignmentID, requestBody) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationAssignmentsClient", "CreateOrUpdate", nil, "Failure preparing request") + return + } + + result, err = client.CreateOrUpdateSender(req) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationAssignmentsClient", "CreateOrUpdate", result.Response(), "Failure sending request") + return + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client RegistrationAssignmentsClient) CreateOrUpdatePreparer(ctx context.Context, scope string, registrationAssignmentID string, requestBody RegistrationAssignment) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "registrationAssignmentId": autorest.Encode("path", registrationAssignmentID), + "scope": scope, + } + + const APIVersion = "2019-06-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + requestBody.ID = nil + requestBody.Type = nil + requestBody.Name = nil + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/{scope}/providers/Microsoft.ManagedServices/registrationAssignments/{registrationAssignmentId}", pathParameters), + autorest.WithJSON(requestBody), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client RegistrationAssignmentsClient) CreateOrUpdateSender(req *http.Request) (future RegistrationAssignmentsCreateOrUpdateFuture, err error) { + var resp *http.Response + resp, err = client.Send(req, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) + return +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client RegistrationAssignmentsClient) CreateOrUpdateResponder(resp *http.Response) (result RegistrationAssignment, err error) { + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete deletes the specified registration assignment. +// Parameters: +// scope - scope of the resource. +// registrationAssignmentID - guid of the registration assignment. +func (client RegistrationAssignmentsClient) Delete(ctx context.Context, scope string, registrationAssignmentID string) (result RegistrationAssignmentsDeleteFuture, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RegistrationAssignmentsClient.Delete") + defer func() { + sc := -1 + if result.Response() != nil { + sc = result.Response().StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + req, err := client.DeletePreparer(ctx, scope, registrationAssignmentID) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationAssignmentsClient", "Delete", nil, "Failure preparing request") + return + } + + result, err = client.DeleteSender(req) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationAssignmentsClient", "Delete", result.Response(), "Failure sending request") + return + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client RegistrationAssignmentsClient) DeletePreparer(ctx context.Context, scope string, registrationAssignmentID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "registrationAssignmentId": autorest.Encode("path", registrationAssignmentID), + "scope": scope, + } + + const APIVersion = "2019-06-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/{scope}/providers/Microsoft.ManagedServices/registrationAssignments/{registrationAssignmentId}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client RegistrationAssignmentsClient) DeleteSender(req *http.Request) (future RegistrationAssignmentsDeleteFuture, err error) { + var resp *http.Response + resp, err = client.Send(req, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) + return +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client RegistrationAssignmentsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get gets the details of specified registration assignment. +// Parameters: +// scope - scope of the resource. +// registrationAssignmentID - guid of the registration assignment. +// expandRegistrationDefinition - tells whether to return registration definition details also along with +// registration assignment details. +func (client RegistrationAssignmentsClient) Get(ctx context.Context, scope string, registrationAssignmentID string, expandRegistrationDefinition *bool) (result RegistrationAssignment, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RegistrationAssignmentsClient.Get") + defer func() { + sc := -1 + if result.Response.Response != nil { + sc = result.Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + req, err := client.GetPreparer(ctx, scope, registrationAssignmentID, expandRegistrationDefinition) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationAssignmentsClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "managedservices.RegistrationAssignmentsClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationAssignmentsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client RegistrationAssignmentsClient) GetPreparer(ctx context.Context, scope string, registrationAssignmentID string, expandRegistrationDefinition *bool) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "registrationAssignmentId": autorest.Encode("path", registrationAssignmentID), + "scope": scope, + } + + const APIVersion = "2019-06-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if expandRegistrationDefinition != nil { + queryParameters["$expandRegistrationDefinition"] = autorest.Encode("query", *expandRegistrationDefinition) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/{scope}/providers/Microsoft.ManagedServices/registrationAssignments/{registrationAssignmentId}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client RegistrationAssignmentsClient) GetSender(req *http.Request) (*http.Response, error) { + return client.Send(req, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client RegistrationAssignmentsClient) GetResponder(resp *http.Response) (result RegistrationAssignment, err error) { + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List gets a list of the registration assignments. +// Parameters: +// scope - scope of the resource. +// expandRegistrationDefinition - tells whether to return registration definition details also along with +// registration assignment details. +func (client RegistrationAssignmentsClient) List(ctx context.Context, scope string, expandRegistrationDefinition *bool) (result RegistrationAssignmentListPage, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RegistrationAssignmentsClient.List") + defer func() { + sc := -1 + if result.ral.Response.Response != nil { + sc = result.ral.Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + result.fn = client.listNextResults + req, err := client.ListPreparer(ctx, scope, expandRegistrationDefinition) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationAssignmentsClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.ral.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "managedservices.RegistrationAssignmentsClient", "List", resp, "Failure sending request") + return + } + + result.ral, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationAssignmentsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client RegistrationAssignmentsClient) ListPreparer(ctx context.Context, scope string, expandRegistrationDefinition *bool) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "scope": scope, + } + + const APIVersion = "2019-06-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + if expandRegistrationDefinition != nil { + queryParameters["$expandRegistrationDefinition"] = autorest.Encode("query", *expandRegistrationDefinition) + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/{scope}/providers/Microsoft.ManagedServices/registrationAssignments", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client RegistrationAssignmentsClient) ListSender(req *http.Request) (*http.Response, error) { + return client.Send(req, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client RegistrationAssignmentsClient) ListResponder(resp *http.Response) (result RegistrationAssignmentList, err error) { + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listNextResults retrieves the next set of results, if any. +func (client RegistrationAssignmentsClient) listNextResults(ctx context.Context, lastResults RegistrationAssignmentList) (result RegistrationAssignmentList, err error) { + req, err := lastResults.registrationAssignmentListPreparer(ctx) + if err != nil { + return result, autorest.NewErrorWithError(err, "managedservices.RegistrationAssignmentsClient", "listNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "managedservices.RegistrationAssignmentsClient", "listNextResults", resp, "Failure sending next results request") + } + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationAssignmentsClient", "listNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListComplete enumerates all values, automatically crossing page boundaries as required. +func (client RegistrationAssignmentsClient) ListComplete(ctx context.Context, scope string, expandRegistrationDefinition *bool) (result RegistrationAssignmentListIterator, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RegistrationAssignmentsClient.List") + defer func() { + sc := -1 + if result.Response().Response.Response != nil { + sc = result.page.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + result.page, err = client.List(ctx, scope, expandRegistrationDefinition) + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices/registrationdefinitions.go b/vendor/github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices/registrationdefinitions.go new file mode 100644 index 000000000000..f7d692d4d597 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices/registrationdefinitions.go @@ -0,0 +1,396 @@ +package managedservices + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +import ( + "context" + "github.com/Azure/go-autorest/autorest" + "github.com/Azure/go-autorest/autorest/azure" + "github.com/Azure/go-autorest/autorest/validation" + "github.com/Azure/go-autorest/tracing" + "net/http" +) + +// RegistrationDefinitionsClient is the specification for ManagedServices. +type RegistrationDefinitionsClient struct { + BaseClient +} + +// NewRegistrationDefinitionsClient creates an instance of the RegistrationDefinitionsClient client. +func NewRegistrationDefinitionsClient() RegistrationDefinitionsClient { + return NewRegistrationDefinitionsClientWithBaseURI(DefaultBaseURI) +} + +// NewRegistrationDefinitionsClientWithBaseURI creates an instance of the RegistrationDefinitionsClient client using a +// custom endpoint. Use this when interacting with an Azure cloud that uses a non-standard base URI (sovereign clouds, +// Azure stack). +func NewRegistrationDefinitionsClientWithBaseURI(baseURI string) RegistrationDefinitionsClient { + return RegistrationDefinitionsClient{NewWithBaseURI(baseURI)} +} + +// CreateOrUpdate creates or updates a registration definition. +// Parameters: +// registrationDefinitionID - guid of the registration definition. +// scope - scope of the resource. +// requestBody - the parameters required to create new registration definition. +func (client RegistrationDefinitionsClient) CreateOrUpdate(ctx context.Context, registrationDefinitionID string, scope string, requestBody RegistrationDefinition) (result RegistrationDefinitionsCreateOrUpdateFuture, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RegistrationDefinitionsClient.CreateOrUpdate") + defer func() { + sc := -1 + if result.Response() != nil { + sc = result.Response().StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + if err := validation.Validate([]validation.Validation{ + {TargetValue: requestBody, + Constraints: []validation.Constraint{{Target: "requestBody.Properties", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "requestBody.Properties.Authorizations", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "requestBody.Properties.ManagedByTenantID", Name: validation.Null, Rule: true, Chain: nil}, + }}, + {Target: "requestBody.Plan", Name: validation.Null, Rule: false, + Chain: []validation.Constraint{{Target: "requestBody.Plan.Name", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "requestBody.Plan.Publisher", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "requestBody.Plan.Product", Name: validation.Null, Rule: true, Chain: nil}, + {Target: "requestBody.Plan.Version", Name: validation.Null, Rule: true, Chain: nil}, + }}}}}); err != nil { + return result, validation.NewError("managedservices.RegistrationDefinitionsClient", "CreateOrUpdate", err.Error()) + } + + req, err := client.CreateOrUpdatePreparer(ctx, registrationDefinitionID, scope, requestBody) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationDefinitionsClient", "CreateOrUpdate", nil, "Failure preparing request") + return + } + + result, err = client.CreateOrUpdateSender(req) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationDefinitionsClient", "CreateOrUpdate", result.Response(), "Failure sending request") + return + } + + return +} + +// CreateOrUpdatePreparer prepares the CreateOrUpdate request. +func (client RegistrationDefinitionsClient) CreateOrUpdatePreparer(ctx context.Context, registrationDefinitionID string, scope string, requestBody RegistrationDefinition) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "registrationDefinitionId": autorest.Encode("path", registrationDefinitionID), + "scope": scope, + } + + const APIVersion = "2019-06-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + requestBody.ID = nil + requestBody.Type = nil + requestBody.Name = nil + preparer := autorest.CreatePreparer( + autorest.AsContentType("application/json; charset=utf-8"), + autorest.AsPut(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/{scope}/providers/Microsoft.ManagedServices/registrationDefinitions/{registrationDefinitionId}", pathParameters), + autorest.WithJSON(requestBody), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// CreateOrUpdateSender sends the CreateOrUpdate request. The method will close the +// http.Response Body if it receives an error. +func (client RegistrationDefinitionsClient) CreateOrUpdateSender(req *http.Request) (future RegistrationDefinitionsCreateOrUpdateFuture, err error) { + var resp *http.Response + resp, err = client.Send(req, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) + if err != nil { + return + } + future.Future, err = azure.NewFutureFromResponse(resp) + return +} + +// CreateOrUpdateResponder handles the response to the CreateOrUpdate request. The method always +// closes the http.Response Body. +func (client RegistrationDefinitionsClient) CreateOrUpdateResponder(resp *http.Response) (result RegistrationDefinition, err error) { + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusCreated), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// Delete deletes the registration definition. +// Parameters: +// registrationDefinitionID - guid of the registration definition. +// scope - scope of the resource. +func (client RegistrationDefinitionsClient) Delete(ctx context.Context, registrationDefinitionID string, scope string) (result autorest.Response, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RegistrationDefinitionsClient.Delete") + defer func() { + sc := -1 + if result.Response != nil { + sc = result.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + req, err := client.DeletePreparer(ctx, registrationDefinitionID, scope) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationDefinitionsClient", "Delete", nil, "Failure preparing request") + return + } + + resp, err := client.DeleteSender(req) + if err != nil { + result.Response = resp + err = autorest.NewErrorWithError(err, "managedservices.RegistrationDefinitionsClient", "Delete", resp, "Failure sending request") + return + } + + result, err = client.DeleteResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationDefinitionsClient", "Delete", resp, "Failure responding to request") + } + + return +} + +// DeletePreparer prepares the Delete request. +func (client RegistrationDefinitionsClient) DeletePreparer(ctx context.Context, registrationDefinitionID string, scope string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "registrationDefinitionId": autorest.Encode("path", registrationDefinitionID), + "scope": scope, + } + + const APIVersion = "2019-06-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsDelete(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/{scope}/providers/Microsoft.ManagedServices/registrationDefinitions/{registrationDefinitionId}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// DeleteSender sends the Delete request. The method will close the +// http.Response Body if it receives an error. +func (client RegistrationDefinitionsClient) DeleteSender(req *http.Request) (*http.Response, error) { + return client.Send(req, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) +} + +// DeleteResponder handles the response to the Delete request. The method always +// closes the http.Response Body. +func (client RegistrationDefinitionsClient) DeleteResponder(resp *http.Response) (result autorest.Response, err error) { + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusNoContent), + autorest.ByClosing()) + result.Response = resp + return +} + +// Get gets the registration definition details. +// Parameters: +// scope - scope of the resource. +// registrationDefinitionID - guid of the registration definition. +func (client RegistrationDefinitionsClient) Get(ctx context.Context, scope string, registrationDefinitionID string) (result RegistrationDefinition, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RegistrationDefinitionsClient.Get") + defer func() { + sc := -1 + if result.Response.Response != nil { + sc = result.Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + req, err := client.GetPreparer(ctx, scope, registrationDefinitionID) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationDefinitionsClient", "Get", nil, "Failure preparing request") + return + } + + resp, err := client.GetSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "managedservices.RegistrationDefinitionsClient", "Get", resp, "Failure sending request") + return + } + + result, err = client.GetResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationDefinitionsClient", "Get", resp, "Failure responding to request") + } + + return +} + +// GetPreparer prepares the Get request. +func (client RegistrationDefinitionsClient) GetPreparer(ctx context.Context, scope string, registrationDefinitionID string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "registrationDefinitionId": autorest.Encode("path", registrationDefinitionID), + "scope": scope, + } + + const APIVersion = "2019-06-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/{scope}/providers/Microsoft.ManagedServices/registrationDefinitions/{registrationDefinitionId}", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// GetSender sends the Get request. The method will close the +// http.Response Body if it receives an error. +func (client RegistrationDefinitionsClient) GetSender(req *http.Request) (*http.Response, error) { + return client.Send(req, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) +} + +// GetResponder handles the response to the Get request. The method always +// closes the http.Response Body. +func (client RegistrationDefinitionsClient) GetResponder(resp *http.Response) (result RegistrationDefinition, err error) { + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// List gets a list of the registration definitions. +// Parameters: +// scope - scope of the resource. +func (client RegistrationDefinitionsClient) List(ctx context.Context, scope string) (result RegistrationDefinitionListPage, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RegistrationDefinitionsClient.List") + defer func() { + sc := -1 + if result.rdl.Response.Response != nil { + sc = result.rdl.Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + result.fn = client.listNextResults + req, err := client.ListPreparer(ctx, scope) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationDefinitionsClient", "List", nil, "Failure preparing request") + return + } + + resp, err := client.ListSender(req) + if err != nil { + result.rdl.Response = autorest.Response{Response: resp} + err = autorest.NewErrorWithError(err, "managedservices.RegistrationDefinitionsClient", "List", resp, "Failure sending request") + return + } + + result.rdl, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationDefinitionsClient", "List", resp, "Failure responding to request") + } + + return +} + +// ListPreparer prepares the List request. +func (client RegistrationDefinitionsClient) ListPreparer(ctx context.Context, scope string) (*http.Request, error) { + pathParameters := map[string]interface{}{ + "scope": scope, + } + + const APIVersion = "2019-06-01" + queryParameters := map[string]interface{}{ + "api-version": APIVersion, + } + + preparer := autorest.CreatePreparer( + autorest.AsGet(), + autorest.WithBaseURL(client.BaseURI), + autorest.WithPathParameters("/{scope}/providers/Microsoft.ManagedServices/registrationDefinitions", pathParameters), + autorest.WithQueryParameters(queryParameters)) + return preparer.Prepare((&http.Request{}).WithContext(ctx)) +} + +// ListSender sends the List request. The method will close the +// http.Response Body if it receives an error. +func (client RegistrationDefinitionsClient) ListSender(req *http.Request) (*http.Response, error) { + return client.Send(req, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...)) +} + +// ListResponder handles the response to the List request. The method always +// closes the http.Response Body. +func (client RegistrationDefinitionsClient) ListResponder(resp *http.Response) (result RegistrationDefinitionList, err error) { + err = autorest.Respond( + resp, + azure.WithErrorUnlessStatusCode(http.StatusOK), + autorest.ByUnmarshallingJSON(&result), + autorest.ByClosing()) + result.Response = autorest.Response{Response: resp} + return +} + +// listNextResults retrieves the next set of results, if any. +func (client RegistrationDefinitionsClient) listNextResults(ctx context.Context, lastResults RegistrationDefinitionList) (result RegistrationDefinitionList, err error) { + req, err := lastResults.registrationDefinitionListPreparer(ctx) + if err != nil { + return result, autorest.NewErrorWithError(err, "managedservices.RegistrationDefinitionsClient", "listNextResults", nil, "Failure preparing next results request") + } + if req == nil { + return + } + resp, err := client.ListSender(req) + if err != nil { + result.Response = autorest.Response{Response: resp} + return result, autorest.NewErrorWithError(err, "managedservices.RegistrationDefinitionsClient", "listNextResults", resp, "Failure sending next results request") + } + result, err = client.ListResponder(resp) + if err != nil { + err = autorest.NewErrorWithError(err, "managedservices.RegistrationDefinitionsClient", "listNextResults", resp, "Failure responding to next results request") + } + return +} + +// ListComplete enumerates all values, automatically crossing page boundaries as required. +func (client RegistrationDefinitionsClient) ListComplete(ctx context.Context, scope string) (result RegistrationDefinitionListIterator, err error) { + if tracing.IsEnabled() { + ctx = tracing.StartSpan(ctx, fqdn+"/RegistrationDefinitionsClient.List") + defer func() { + sc := -1 + if result.Response().Response.Response != nil { + sc = result.page.Response().Response.Response.StatusCode + } + tracing.EndSpan(ctx, sc, err) + }() + } + result.page, err = client.List(ctx, scope) + return +} diff --git a/vendor/github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices/version.go b/vendor/github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices/version.go new file mode 100644 index 000000000000..431f9b9cf353 --- /dev/null +++ b/vendor/github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices/version.go @@ -0,0 +1,30 @@ +package managedservices + +import "github.com/Azure/azure-sdk-for-go/version" + +// Copyright (c) Microsoft and contributors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// +// See the License for the specific language governing permissions and +// limitations under the License. +// +// Code generated by Microsoft (R) AutoRest Code Generator. +// Changes may cause incorrect behavior and will be lost if the code is regenerated. + +// UserAgent returns the UserAgent string to use when sending http.Requests. +func UserAgent() string { + return "Azure-SDK-For-Go/" + Version() + " managedservices/2019-06-01" +} + +// Version returns the semantic version (see http://semver.org) of the client. +func Version() string { + return version.Number +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 74a0721af471..d76c134e3997 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -41,6 +41,7 @@ github.com/Azure/azure-sdk-for-go/services/keyvault/mgmt/2019-09-01/keyvault github.com/Azure/azure-sdk-for-go/services/kusto/mgmt/2020-02-15/kusto github.com/Azure/azure-sdk-for-go/services/logic/mgmt/2019-05-01/logic github.com/Azure/azure-sdk-for-go/services/machinelearningservices/mgmt/2020-04-01/machinelearningservices +github.com/Azure/azure-sdk-for-go/services/managedservices/mgmt/2019-06-01/managedservices github.com/Azure/azure-sdk-for-go/services/maps/mgmt/2018-05-01/maps github.com/Azure/azure-sdk-for-go/services/mariadb/mgmt/2018-06-01/mariadb github.com/Azure/azure-sdk-for-go/services/marketplaceordering/mgmt/2015-06-01/marketplaceordering diff --git a/website/allowed-subcategories b/website/allowed-subcategories index f1da75ebb476..7c1ddf6f83f6 100644 --- a/website/allowed-subcategories +++ b/website/allowed-subcategories @@ -34,6 +34,7 @@ Healthcare IoT Central IoT Hub Key Vault +Lighthouse Load Balancer Log Analytics Logic App diff --git a/website/azurerm.erb b/website/azurerm.erb index b5847c875ec4..6cb4171c14f5 100644 --- a/website/azurerm.erb +++ b/website/azurerm.erb @@ -1155,15 +1155,15 @@
  • - azurerm_linux_virtual_machine_scale_set + azurerm_managed_application
  • - azurerm_managed_application_definition + azurerm_linux_virtual_machine_scale_set
  • - azurerm_managed_application + azurerm_managed_application_definition
  • @@ -1899,6 +1899,19 @@
  • +
  • + Lighthouse Resources + +
  • +
  • Load Balancer Resources