2017-01-02 15:37:45 +01:00
|
|
|
package azurerm
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
|
|
|
|
"net/http"
|
|
|
|
|
|
|
|
"regexp"
|
|
|
|
|
|
|
|
"github.com/Azure/azure-sdk-for-go/arm/containerregistry"
|
|
|
|
"github.com/hashicorp/terraform/helper/hashcode"
|
|
|
|
"github.com/hashicorp/terraform/helper/schema"
|
2017-06-01 11:18:22 +02:00
|
|
|
"github.com/hashicorp/terraform/helper/validation"
|
2017-01-02 15:37:45 +01:00
|
|
|
"github.com/jen20/riviera/azure"
|
|
|
|
)
|
|
|
|
|
|
|
|
func resourceArmContainerRegistry() *schema.Resource {
|
|
|
|
return &schema.Resource{
|
|
|
|
Create: resourceArmContainerRegistryCreate,
|
|
|
|
Read: resourceArmContainerRegistryRead,
|
2017-06-01 11:18:22 +02:00
|
|
|
Update: resourceArmContainerRegistryUpdate,
|
2017-01-02 15:37:45 +01:00
|
|
|
Delete: resourceArmContainerRegistryDelete,
|
|
|
|
Importer: &schema.ResourceImporter{
|
|
|
|
State: schema.ImportStatePassthrough,
|
|
|
|
},
|
2017-06-01 11:18:22 +02:00
|
|
|
MigrateState: resourceAzureRMContainerRegistryMigrateState,
|
|
|
|
SchemaVersion: 1,
|
2017-01-02 15:37:45 +01:00
|
|
|
|
|
|
|
Schema: map[string]*schema.Schema{
|
|
|
|
"name": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
ForceNew: true,
|
|
|
|
ValidateFunc: validateAzureRMContainerRegistryName,
|
|
|
|
},
|
|
|
|
|
|
|
|
"resource_group_name": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
ForceNew: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
"location": locationSchema(),
|
|
|
|
|
2017-06-01 11:18:22 +02:00
|
|
|
"sku": {
|
|
|
|
Type: schema.TypeString,
|
2017-06-01 15:00:04 +02:00
|
|
|
Optional: true,
|
2017-06-01 11:18:22 +02:00
|
|
|
ForceNew: true,
|
2017-06-01 15:00:04 +02:00
|
|
|
Default: string(containerregistry.Basic),
|
2017-06-01 11:18:22 +02:00
|
|
|
DiffSuppressFunc: ignoreCaseDiffSuppressFunc,
|
|
|
|
ValidateFunc: validation.StringInSlice([]string{
|
|
|
|
string(containerregistry.Basic),
|
|
|
|
}, true),
|
|
|
|
},
|
|
|
|
|
2017-01-02 15:37:45 +01:00
|
|
|
"admin_enabled": {
|
|
|
|
Type: schema.TypeBool,
|
|
|
|
Optional: true,
|
|
|
|
Default: false,
|
|
|
|
},
|
|
|
|
|
|
|
|
"storage_account": {
|
|
|
|
Type: schema.TypeSet,
|
|
|
|
Required: true,
|
|
|
|
MaxItems: 1,
|
|
|
|
Elem: &schema.Resource{
|
|
|
|
Schema: map[string]*schema.Schema{
|
|
|
|
"name": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
"access_key": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Required: true,
|
|
|
|
Sensitive: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
"login_server": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Computed: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
"admin_username": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Computed: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
"admin_password": {
|
|
|
|
Type: schema.TypeString,
|
|
|
|
Computed: true,
|
|
|
|
},
|
|
|
|
|
|
|
|
"tags": tagsSchema(),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceArmContainerRegistryCreate(d *schema.ResourceData, meta interface{}) error {
|
|
|
|
client := meta.(*ArmClient).containerRegistryClient
|
|
|
|
log.Printf("[INFO] preparing arguments for AzureRM Container Registry creation.")
|
|
|
|
|
|
|
|
resourceGroup := d.Get("resource_group_name").(string)
|
|
|
|
name := d.Get("name").(string)
|
|
|
|
location := d.Get("location").(string)
|
2017-06-01 11:18:22 +02:00
|
|
|
sku := d.Get("sku").(string)
|
2017-01-02 15:37:45 +01:00
|
|
|
|
|
|
|
adminUserEnabled := d.Get("admin_enabled").(bool)
|
|
|
|
tags := d.Get("tags").(map[string]interface{})
|
|
|
|
|
2017-06-01 11:18:22 +02:00
|
|
|
parameters := containerregistry.RegistryCreateParameters{
|
2017-01-02 15:37:45 +01:00
|
|
|
Location: &location,
|
2017-06-01 11:18:22 +02:00
|
|
|
Sku: &containerregistry.Sku{
|
|
|
|
Name: &sku,
|
|
|
|
Tier: containerregistry.SkuTier(sku),
|
|
|
|
},
|
|
|
|
RegistryPropertiesCreateParameters: &containerregistry.RegistryPropertiesCreateParameters{
|
2017-01-02 15:37:45 +01:00
|
|
|
AdminUserEnabled: &adminUserEnabled,
|
|
|
|
},
|
|
|
|
Tags: expandTags(tags),
|
|
|
|
}
|
|
|
|
|
|
|
|
accounts := d.Get("storage_account").(*schema.Set).List()
|
|
|
|
account := accounts[0].(map[string]interface{})
|
|
|
|
storageAccountName := account["name"].(string)
|
|
|
|
storageAccountAccessKey := account["access_key"].(string)
|
2017-06-01 11:18:22 +02:00
|
|
|
parameters.RegistryPropertiesCreateParameters.StorageAccount = &containerregistry.StorageAccountParameters{
|
2017-01-02 15:37:45 +01:00
|
|
|
Name: azure.String(storageAccountName),
|
|
|
|
AccessKey: azure.String(storageAccountAccessKey),
|
|
|
|
}
|
|
|
|
|
2017-06-01 11:18:22 +02:00
|
|
|
_, error := client.Create(resourceGroup, name, parameters, make(<-chan struct{}))
|
|
|
|
err := <-error
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
read, err := client.Get(resourceGroup, name)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if read.ID == nil {
|
|
|
|
return fmt.Errorf("Cannot read Container Registry %s (resource group %s) ID", name, resourceGroup)
|
|
|
|
}
|
|
|
|
|
|
|
|
d.SetId(*read.ID)
|
|
|
|
|
|
|
|
return resourceArmContainerRegistryRead(d, meta)
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceArmContainerRegistryUpdate(d *schema.ResourceData, meta interface{}) error {
|
|
|
|
client := meta.(*ArmClient).containerRegistryClient
|
|
|
|
log.Printf("[INFO] preparing arguments for AzureRM Container Registry update.")
|
|
|
|
|
|
|
|
resourceGroup := d.Get("resource_group_name").(string)
|
|
|
|
name := d.Get("name").(string)
|
|
|
|
|
|
|
|
accounts := d.Get("storage_account").(*schema.Set).List()
|
|
|
|
account := accounts[0].(map[string]interface{})
|
|
|
|
storageAccountName := account["name"].(string)
|
|
|
|
storageAccountAccessKey := account["access_key"].(string)
|
|
|
|
|
|
|
|
adminUserEnabled := d.Get("admin_enabled").(bool)
|
|
|
|
tags := d.Get("tags").(map[string]interface{})
|
|
|
|
|
|
|
|
parameters := containerregistry.RegistryUpdateParameters{
|
|
|
|
RegistryPropertiesUpdateParameters: &containerregistry.RegistryPropertiesUpdateParameters{
|
|
|
|
AdminUserEnabled: &adminUserEnabled,
|
|
|
|
StorageAccount: &containerregistry.StorageAccountParameters{
|
|
|
|
Name: azure.String(storageAccountName),
|
|
|
|
AccessKey: azure.String(storageAccountAccessKey),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Tags: expandTags(tags),
|
|
|
|
}
|
|
|
|
|
|
|
|
_, err := client.Update(resourceGroup, name, parameters)
|
2017-01-02 15:37:45 +01:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2017-06-01 11:18:22 +02:00
|
|
|
read, err := client.Get(resourceGroup, name)
|
2017-01-02 15:37:45 +01:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if read.ID == nil {
|
|
|
|
return fmt.Errorf("Cannot read Container Registry %s (resource group %s) ID", name, resourceGroup)
|
|
|
|
}
|
|
|
|
|
|
|
|
d.SetId(*read.ID)
|
|
|
|
|
|
|
|
return resourceArmContainerRegistryRead(d, meta)
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceArmContainerRegistryRead(d *schema.ResourceData, meta interface{}) error {
|
|
|
|
client := meta.(*ArmClient).containerRegistryClient
|
|
|
|
|
|
|
|
id, err := parseAzureResourceID(d.Id())
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
resourceGroup := id.ResourceGroup
|
|
|
|
name := id.Path["registries"]
|
|
|
|
|
2017-06-01 11:18:22 +02:00
|
|
|
resp, err := client.Get(resourceGroup, name)
|
2017-01-02 15:37:45 +01:00
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Error making Read request on Azure Container Registry %s: %s", name, err)
|
|
|
|
}
|
|
|
|
if resp.StatusCode == http.StatusNotFound {
|
|
|
|
d.SetId("")
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
d.Set("name", resp.Name)
|
|
|
|
d.Set("resource_group_name", resourceGroup)
|
|
|
|
d.Set("location", azureRMNormalizeLocation(*resp.Location))
|
|
|
|
d.Set("admin_enabled", resp.AdminUserEnabled)
|
|
|
|
d.Set("login_server", resp.LoginServer)
|
|
|
|
|
2017-06-01 11:18:22 +02:00
|
|
|
if resp.Sku != nil {
|
|
|
|
d.Set("sku", string(resp.Sku.Tier))
|
|
|
|
}
|
|
|
|
|
2017-01-02 15:37:45 +01:00
|
|
|
if resp.StorageAccount != nil {
|
|
|
|
flattenArmContainerRegistryStorageAccount(d, resp.StorageAccount)
|
|
|
|
}
|
|
|
|
|
|
|
|
if *resp.AdminUserEnabled {
|
2017-06-01 11:18:22 +02:00
|
|
|
credsResp, err := client.ListCredentials(resourceGroup, name)
|
2017-01-02 15:37:45 +01:00
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Error making Read request on Azure Container Registry %s for Credentials: %s", name, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
d.Set("admin_username", credsResp.Username)
|
2017-06-01 11:18:22 +02:00
|
|
|
for _, v := range *credsResp.Passwords {
|
|
|
|
d.Set("admin_password", v.Value)
|
|
|
|
break
|
|
|
|
}
|
2017-01-02 15:37:45 +01:00
|
|
|
} else {
|
|
|
|
d.Set("admin_username", "")
|
|
|
|
d.Set("admin_password", "")
|
|
|
|
}
|
|
|
|
|
|
|
|
flattenAndSetTags(d, resp.Tags)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceArmContainerRegistryDelete(d *schema.ResourceData, meta interface{}) error {
|
|
|
|
client := meta.(*ArmClient).containerRegistryClient
|
|
|
|
|
|
|
|
id, err := parseAzureResourceID(d.Id())
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
resourceGroup := id.ResourceGroup
|
|
|
|
name := id.Path["registries"]
|
|
|
|
|
|
|
|
resp, err := client.Delete(resourceGroup, name)
|
|
|
|
|
|
|
|
if resp.StatusCode != http.StatusOK {
|
|
|
|
return fmt.Errorf("Error issuing Azure ARM delete request of Container Registry '%s': %s", name, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func flattenArmContainerRegistryStorageAccount(d *schema.ResourceData, properties *containerregistry.StorageAccountProperties) {
|
|
|
|
storageAccounts := schema.Set{
|
|
|
|
F: resourceAzureRMContainerRegistryStorageAccountHash,
|
|
|
|
}
|
|
|
|
|
|
|
|
storageAccount := map[string]interface{}{}
|
|
|
|
storageAccount["name"] = properties.Name
|
|
|
|
storageAccounts.Add(storageAccount)
|
|
|
|
|
|
|
|
d.Set("storage_account", &storageAccounts)
|
|
|
|
}
|
|
|
|
|
|
|
|
func resourceAzureRMContainerRegistryStorageAccountHash(v interface{}) int {
|
|
|
|
m := v.(map[string]interface{})
|
|
|
|
name := m["name"].(*string)
|
|
|
|
return hashcode.String(*name)
|
|
|
|
}
|
|
|
|
|
|
|
|
func validateAzureRMContainerRegistryName(v interface{}, k string) (ws []string, errors []error) {
|
|
|
|
value := v.(string)
|
|
|
|
if !regexp.MustCompile(`^[a-zA-Z0-9]+$`).MatchString(value) {
|
|
|
|
errors = append(errors, fmt.Errorf(
|
|
|
|
"alpha numeric characters only are allowed in %q: %q", k, value))
|
|
|
|
}
|
|
|
|
|
|
|
|
if 5 > len(value) {
|
|
|
|
errors = append(errors, fmt.Errorf("%q cannot be less than 5 characters: %q", k, value))
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(value) >= 50 {
|
|
|
|
errors = append(errors, fmt.Errorf("%q cannot be longer than 50 characters: %q %d", k, value, len(value)))
|
|
|
|
}
|
|
|
|
|
|
|
|
return
|
|
|
|
}
|