Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Resource][Data Source] ACR Scope Map and Tokens #11350

Merged
merged 5 commits into from
Apr 28, 2021
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions azurerm/internal/services/containers/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ type Client struct {
ReplicationsClient *containerregistry.ReplicationsClient
ServicesClient *legacy.ContainerServicesClient
WebhooksClient *containerregistry.WebhooksClient
TokensClient *containerregistry.TokensClient
ScopeMapsClient *containerregistry.ScopeMapsClient

Environment azure.Environment
}
Expand All @@ -31,6 +33,12 @@ func NewClient(o *common.ClientOptions) *Client {
replicationsClient := containerregistry.NewReplicationsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&replicationsClient.Client, o.ResourceManagerAuthorizer)

tokensClient := containerregistry.NewTokensClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&tokensClient.Client, o.ResourceManagerAuthorizer)

scopeMapsClient := containerregistry.NewScopeMapsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&scopeMapsClient.Client, o.ResourceManagerAuthorizer)

groupsClient := containerinstance.NewContainerGroupsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId)
o.ConfigureClient(&groupsClient.Client, o.ResourceManagerAuthorizer)

Expand All @@ -53,5 +61,7 @@ func NewClient(o *common.ClientOptions) *Client {
ReplicationsClient: &replicationsClient,
ServicesClient: &servicesClient,
Environment: o.Environment,
TokensClient: &tokensClient,
ScopeMapsClient: &scopeMapsClient,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package containers

import (
"fmt"
"time"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/helpers/azure"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/clients"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/containers/validate"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func dataSourceContainerRegistryScopeMap() *schema.Resource {
return &schema.Resource{
Read: dataSourceContainerRegistryScopeMapRead,

Timeouts: &schema.ResourceTimeout{
Read: schema.DefaultTimeout(5 * time.Minute),
},

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
katbyte marked this conversation as resolved.
Show resolved Hide resolved
"container_registry_name": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validate.ContainerRegistryName,
},
"resource_group_name": azure.SchemaResourceGroupNameForDataSource(),
"description": {
Type: schema.TypeString,
Computed: true,
},
"actions": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
}
}

func dataSourceContainerRegistryScopeMapRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Containers.ScopeMapsClient
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

resourceGroup := d.Get("resource_group_name").(string)
containerRegistryName := d.Get("container_registry_name").(string)
name := d.Get("name").(string)

resp, err := client.Get(ctx, resourceGroup, containerRegistryName, name)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return fmt.Errorf("Container Registry Scope Map %q was not found in Resource Group %q", name, resourceGroup)
}

return fmt.Errorf("Error making Read request on Scope Map %q (Azure Container Registry %q, Resource Group %q): %+v", name, containerRegistryName, resourceGroup, err)
}

if resp.ID == nil || *resp.ID == "" {
return fmt.Errorf("retrieving Container Registry Scope Map %q (Azure Container Registry %q, Resource Group %q): `id` was nil", name, containerRegistryName, resourceGroup)
}

d.SetId(*resp.ID)
MattiasAng marked this conversation as resolved.
Show resolved Hide resolved
d.Set("name", resp.Name)
d.Set("resource_group_name", resourceGroup)
d.Set("container_registry_name", containerRegistryName)
d.Set("description", resp.Description)
d.Set("actions", utils.FlattenStringSlice(resp.Actions))

return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package containers_test

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/acceptance/check"
)

type ContainerRegistryScopeMapDataSource struct {
}

func TestAccDataSourceContainerRegistryScopeMap_complete(t *testing.T) {
data := acceptance.BuildTestData(t, "data.azurerm_container_registry_scope_map", "test")
r := ContainerRegistryScopeMapDataSource{}

data.DataSourceTest(t, []resource.TestStep{
{
Config: r.complete(data),
Check: resource.ComposeTestCheckFunc(
check.That(data.ResourceName).Key("name").Exists(),
check.That(data.ResourceName).Key("resource_group_name").Exists(),
check.That(data.ResourceName).Key("container_registry_name").Exists(),
check.That(data.ResourceName).Key("scope_map_id").Exists(),
katbyte marked this conversation as resolved.
Show resolved Hide resolved
check.That(data.ResourceName).Key("description").HasValue("A test scope map"),
check.That(data.ResourceName).Key("actions.#").HasValue("1"),
check.That(data.ResourceName).Key("actions.0").HasValue("repositories/testrepo/content/read"),
),
},
})
}

func (ContainerRegistryScopeMapDataSource) complete(data acceptance.TestData) string {
return fmt.Sprintf(`
%s

resource "azurerm_container_registry_scope_map" "test" {
name = "testscopemap%d"
description = "A test scope map"
resource_group_name = azurerm_resource_group.test.name
container_registry_name = azurerm_container_registry.test.name
actions = ["repositories/testrepo/content/read"]
}

data "azurerm_container_registry_scope_map" "test" {
name = azurerm_container_registry_scope_map.test.name
container_registry_name = azurerm_container_registry.test.name
resource_group_name = azurerm_container_registry.test.resource_group_name
}
`, ContainerRegistryResource{}.basicManaged(data, "Premium"), data.RandomInteger)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
package containers

import (
"fmt"
"log"
"time"

"github.com/Azure/azure-sdk-for-go/services/preview/containerregistry/mgmt/2020-11-01-preview/containerregistry"
"github.com/hashicorp/go-azure-helpers/response"
"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/azure"
"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/containers/parse"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/services/containers/validate"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/internal/timeouts"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func resourceContainerRegistryScopeMap() *schema.Resource {
return &schema.Resource{
Create: resourceContainerRegistryScopeMapCreate,
Read: resourceContainerRegistryScopeMapRead,
Update: resourceContainerRegistryScopeMapUpdate,
Delete: resourceContainerRegistryScopeMapDelete,
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,
ForceNew: true,
ValidateFunc: validate.ContainerRegistryName,
},

"description": {
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringLenBetween(1, 256),
},

"resource_group_name": azure.SchemaResourceGroupName(),

"container_registry_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validate.ContainerRegistryName,
},

"actions": {
Type: schema.TypeList,
Required: true,
MinItems: 1,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validation.StringIsNotEmpty,
},
},
},
}
}

func resourceContainerRegistryScopeMapCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Containers.ScopeMapsClient
ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d)
defer cancel()

log.Printf("[INFO] preparing arguments for AzureRM Container Registry scope map creation.")
resourceGroup := d.Get("resource_group_name").(string)
containerRegistryName := d.Get("container_registry_name").(string)
name := d.Get("name").(string)

if d.IsNewResource() {
existing, err := client.Get(ctx, resourceGroup, containerRegistryName, name)
if err != nil {
if !utils.ResponseWasNotFound(existing.Response) {
return fmt.Errorf("Error checking for presence of existing scope map %q in Container Registry %q (Resource Group %q): %s", name, containerRegistryName, resourceGroup, err)
}
}

if existing.ID != nil && *existing.ID != "" {
return tf.ImportAsExistsError("azurerm_container_registry_scope_map", *existing.ID)
}
}

description := d.Get("description").(string)
actions := d.Get("actions").([]interface{})

parameters := containerregistry.ScopeMap{
ScopeMapProperties: &containerregistry.ScopeMapProperties{
Description: utils.String(description),
Actions: utils.ExpandStringSlice(actions),
},
}

future, err := client.Create(ctx, resourceGroup, containerRegistryName, name, parameters)
if err != nil {
return fmt.Errorf("Error creating scope map %q in Container Registry %q (Resource Group %q): %+v", name, containerRegistryName, resourceGroup, err)
}

if err = future.WaitForCompletionRef(ctx, client.Client); err != nil {
return fmt.Errorf("Error waiting for creation of scope map %q (Container Registry %q, Resource Group %q): %+v", name, containerRegistryName, resourceGroup, err)
}

read, err := client.Get(ctx, resourceGroup, containerRegistryName, name)
if err != nil {
return fmt.Errorf("Error retrieving scope map %q for Container Registry %q (Resource Group %q): %+v", name, containerRegistryName, resourceGroup, err)
}

if read.ID == nil {
return fmt.Errorf("Cannot read scope map %q for Container Registry %q (resource group %q) ID", name, containerRegistryName, resourceGroup)
}

d.SetId(*read.ID)

return resourceContainerRegistryScopeMapRead(d, meta)
}

func resourceContainerRegistryScopeMapUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Containers.ScopeMapsClient
ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d)
defer cancel()

log.Printf("[INFO] preparing arguments for AzureRM Container Registry scope map update.")
resourceGroup := d.Get("resource_group_name").(string)
containerRegistryName := d.Get("container_registry_name").(string)
name := d.Get("name").(string)
description := d.Get("description").(string)
actions := d.Get("actions").([]interface{})

parameters := containerregistry.ScopeMapUpdateParameters{
ScopeMapPropertiesUpdateParameters: &containerregistry.ScopeMapPropertiesUpdateParameters{
Description: utils.String(description),
Actions: utils.ExpandStringSlice(actions),
},
}

future, err := client.Update(ctx, resourceGroup, containerRegistryName, name, parameters)
if err != nil {
return fmt.Errorf("Error updating scope map %q for Container Registry %q (Resource Group %q): %+v", name, containerRegistryName, resourceGroup, err)
}

if err = future.WaitForCompletionRef(ctx, client.Client); err != nil {
return fmt.Errorf("Error waiting for update of scope map %q (Container Registry %q, Resource Group %q): %+v", name, containerRegistryName, resourceGroup, err)
}

read, err := client.Get(ctx, resourceGroup, containerRegistryName, name)
if err != nil {
return fmt.Errorf("Error retrieving scope map %q (Container Registry %q, Resource Group %q): %+v", name, containerRegistryName, resourceGroup, err)
}

if read.ID == nil {
return fmt.Errorf("Cannot read scope map %q (Container Registry %q, resource group %q) ID", name, containerRegistryName, resourceGroup)
}

d.SetId(*read.ID)

return resourceContainerRegistryScopeMapRead(d, meta)
}

func resourceContainerRegistryScopeMapRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Containers.ScopeMapsClient
ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d)
defer cancel()

id, err := parse.ContainerRegistryScopeMapID(d.Id())
if err != nil {
return err
}

resp, err := client.Get(ctx, id.ResourceGroup, id.RegistryName, id.ScopeMapName)

if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
log.Printf("[DEBUG] Scope Map %q was not found in Container Registry %q in Resource Group %q", id.ScopeMapName, id.RegistryName, id.ResourceGroup)
d.SetId("")
return nil
}

return fmt.Errorf("Error making Read request on scope map %q in Azure Container Registry %q (Resource Group %q): %+v", id.ScopeMapName, id.RegistryName, id.ResourceGroup, err)
}

d.Set("name", resp.Name)
d.Set("resource_group_name", id.ResourceGroup)
d.Set("container_registry_name", id.RegistryName)
d.Set("description", resp.Description)
d.Set("actions", utils.FlattenStringSlice(resp.Actions))

return nil
}

func resourceContainerRegistryScopeMapDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*clients.Client).Containers.ScopeMapsClient
ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d)
defer cancel()

id, err := parse.ContainerRegistryScopeMapID(d.Id())
if err != nil {
return err
}

future, err := client.Delete(ctx, id.ResourceGroup, id.RegistryName, id.ScopeMapName)
if err != nil {
if response.WasNotFound(future.Response()) {
return nil
}
return fmt.Errorf("Error issuing Azure ARM delete request of Container Registry scope map '%s': %+v", id.ScopeMapName, err)
}

if err = future.WaitForCompletionRef(ctx, client.Client); err != nil {
if response.WasNotFound(future.Response()) {
return nil
}
return fmt.Errorf("Error issuing Azure ARM delete request of Container Registry scope map '%s': %+v", id.ScopeMapName, err)
}

return nil
}
Loading