<commit_before>// Copyright 2016-2019 terraform-provider-sakuracloud authors
//
// 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.

package sakuracloud

import (
	"context"
	"fmt"
	"time"

	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
	"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
	"github.com/sacloud/libsacloud/v2/sacloud"
	"github.com/sacloud/libsacloud/v2/sacloud/types"
)

func resourceSakuraCloudContainerRegistry() *schema.Resource {
	return &schema.Resource{
		Create: resourceSakuraCloudContainerRegistryCreate,
		Read:   resourceSakuraCloudContainerRegistryRead,
		Update: resourceSakuraCloudContainerRegistryUpdate,
		Delete: resourceSakuraCloudContainerRegistryDelete,

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

		Schema: map[string]*schema.Schema{
			"name": {
				Type:     schema.TypeString,
				Required: true,
			},
			"access_level": {
				Type:         schema.TypeString,
				Required:     true,
				ValidateFunc: validation.StringInSlice(types.ContainerRegistryVisibilityStrings, false),
			},
			"subdomain_label": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"fqdn": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"icon_id": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validateSakuracloudIDType,
			},
			"description": {
				Type:     schema.TypeString,
				Optional: true,
			},
			"tags": {
				Type:     schema.TypeSet,
				Optional: true,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Set:      schema.HashString,
			},
			"user": {
				Type:     schema.TypeList,
				Optional: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"name": {
							Type:     schema.TypeString,
							Required: true,
						},
						"password": {
							Type:      schema.TypeString,
							Required:  true,
							Sensitive: true,
						},
					},
				},
			},
		},
	}
}

func resourceSakuraCloudContainerRegistryCreate(d *schema.ResourceData, meta interface{}) error {
	client, _, err := sakuraCloudClient(d, meta)
	if err != nil {
		return err
	}
	ctx, cancel := operationContext(d, schema.TimeoutCreate)
	defer cancel()

	builder := expandContainerRegistryBuilder(d, client, "")
	reg, err := builder.Build(ctx)
	if err != nil {
		return fmt.Errorf("creating SakuraCloud ContainerRegistry is failed: %s", err)
	}

	d.SetId(reg.ID.String())
	return resourceSakuraCloudContainerRegistryRead(d, meta)
}

func resourceSakuraCloudContainerRegistryRead(d *schema.ResourceData, meta interface{}) error {
	client, _, err := sakuraCloudClient(d, meta)
	if err != nil {
		return err
	}
	ctx, cancel := operationContext(d, schema.TimeoutRead)
	defer cancel()

	regOp := sacloud.NewContainerRegistryOp(client)

	reg, err := regOp.Read(ctx, sakuraCloudID(d.Id()))
	if err != nil {
		if sacloud.IsNotFoundError(err) {
			d.SetId("")
			return nil
		}
		return fmt.Errorf("could not find SakuraCloud ContainerRegistry[%s]: %s", d.Id(), err)
	}
	return setContainerRegistryResourceData(ctx, d, client, reg)
}

func resourceSakuraCloudContainerRegistryUpdate(d *schema.ResourceData, meta interface{}) error {
	client, _, err := sakuraCloudClient(d, meta)
	if err != nil {
		return err
	}
	ctx, cancel := operationContext(d, schema.TimeoutUpdate)
	defer cancel()

	regOp := sacloud.NewContainerRegistryOp(client)
	reg, err := regOp.Read(ctx, sakuraCloudID(d.Id()))
	if err != nil {
		return fmt.Errorf("could not read SakuraCloud ContainerRegistry[%s]: %s", d.Id(), err)
	}

	builder := expandContainerRegistryBuilder(d, client, reg.SettingsHash)
	if _, err := builder.Update(ctx, reg.ID); err != nil {
		return fmt.Errorf("updating SakuraCloud ContainerRegistry[%s] is failed: %s", reg.ID, err)
	}

	return resourceSakuraCloudContainerRegistryRead(d, meta)
}

func resourceSakuraCloudContainerRegistryDelete(d *schema.ResourceData, meta interface{}) error {
	client, _, err := sakuraCloudClient(d, meta)
	if err != nil {
		return err
	}
	ctx, cancel := operationContext(d, schema.TimeoutDelete)
	defer cancel()

	regOp := sacloud.NewContainerRegistryOp(client)
	reg, err := regOp.Read(ctx, sakuraCloudID(d.Id()))
	if err != nil {
		if sacloud.IsNotFoundError(err) {
			d.SetId("")
			return nil
		}
		return fmt.Errorf("could not read SakuraCloud ContainerRegistry[%s]: %s", d.Id(), err)
	}

	if err := regOp.Delete(ctx, reg.ID); err != nil {
		return fmt.Errorf("deleting SakuraCloud ContainerRegistry[%s] is failed: %s", reg.ID, err)
	}

	d.SetId("")
	return nil
}

func setContainerRegistryResourceData(ctx context.Context, d *schema.ResourceData, client *APIClient, data *sacloud.ContainerRegistry) error {
	d.Set("name", data.Name)                         // nolint
	d.Set("access_level", data.AccessLevel.String()) // nolint
	d.Set("subdomain_label", data.SubDomainLabel)    // nolint
	d.Set("fqdn", data.FQDN)                         // nolint
	d.Set("icon_id", data.IconID.String())           // nolint
	d.Set("description", data.Description)           // nolint
	return d.Set("tags", flattenTags(data.Tags))
}
<commit_msg>Add DeprecationMessage to sakuracloud_container_registry<commit_after>// Copyright 2016-2019 terraform-provider-sakuracloud authors
//
// 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.

package sakuracloud

import (
	"context"
	"fmt"
	"time"

	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
	"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
	"github.com/sacloud/libsacloud/v2/sacloud"
	"github.com/sacloud/libsacloud/v2/sacloud/types"
)

func resourceSakuraCloudContainerRegistry() *schema.Resource {
	return &schema.Resource{
		Create: resourceSakuraCloudContainerRegistryCreate,
		Read:   resourceSakuraCloudContainerRegistryRead,
		Update: resourceSakuraCloudContainerRegistryUpdate,
		Delete: resourceSakuraCloudContainerRegistryDelete,

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

		Schema: map[string]*schema.Schema{
			"name": {
				Type:     schema.TypeString,
				Required: true,
			},
			"access_level": {
				Type:         schema.TypeString,
				Required:     true,
				ValidateFunc: validation.StringInSlice(types.ContainerRegistryVisibilityStrings, false),
			},
			"subdomain_label": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"fqdn": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"icon_id": {
				Type:         schema.TypeString,
				Optional:     true,
				ValidateFunc: validateSakuracloudIDType,
			},
			"description": {
				Type:     schema.TypeString,
				Optional: true,
			},
			"tags": {
				Type:     schema.TypeSet,
				Optional: true,
				Elem:     &schema.Schema{Type: schema.TypeString},
				Set:      schema.HashString,
			},
			"user": {
				Type:     schema.TypeList,
				Optional: true,
				Elem: &schema.Resource{
					Schema: map[string]*schema.Schema{
						"name": {
							Type:     schema.TypeString,
							Required: true,
						},
						"password": {
							Type:      schema.TypeString,
							Required:  true,
							Sensitive: true,
						},
					},
				},
			},
		},

		DeprecationMessage: "sakuracloud_container_registry is an experimental resource. Please note that you will need to update the tfstate manually if the resource schema is changed.",
	}
}

func resourceSakuraCloudContainerRegistryCreate(d *schema.ResourceData, meta interface{}) error {
	client, _, err := sakuraCloudClient(d, meta)
	if err != nil {
		return err
	}
	ctx, cancel := operationContext(d, schema.TimeoutCreate)
	defer cancel()

	builder := expandContainerRegistryBuilder(d, client, "")
	reg, err := builder.Build(ctx)
	if err != nil {
		return fmt.Errorf("creating SakuraCloud ContainerRegistry is failed: %s", err)
	}

	d.SetId(reg.ID.String())
	return resourceSakuraCloudContainerRegistryRead(d, meta)
}

func resourceSakuraCloudContainerRegistryRead(d *schema.ResourceData, meta interface{}) error {
	client, _, err := sakuraCloudClient(d, meta)
	if err != nil {
		return err
	}
	ctx, cancel := operationContext(d, schema.TimeoutRead)
	defer cancel()

	regOp := sacloud.NewContainerRegistryOp(client)

	reg, err := regOp.Read(ctx, sakuraCloudID(d.Id()))
	if err != nil {
		if sacloud.IsNotFoundError(err) {
			d.SetId("")
			return nil
		}
		return fmt.Errorf("could not find SakuraCloud ContainerRegistry[%s]: %s", d.Id(), err)
	}
	return setContainerRegistryResourceData(ctx, d, client, reg)
}

func resourceSakuraCloudContainerRegistryUpdate(d *schema.ResourceData, meta interface{}) error {
	client, _, err := sakuraCloudClient(d, meta)
	if err != nil {
		return err
	}
	ctx, cancel := operationContext(d, schema.TimeoutUpdate)
	defer cancel()

	regOp := sacloud.NewContainerRegistryOp(client)
	reg, err := regOp.Read(ctx, sakuraCloudID(d.Id()))
	if err != nil {
		return fmt.Errorf("could not read SakuraCloud ContainerRegistry[%s]: %s", d.Id(), err)
	}

	builder := expandContainerRegistryBuilder(d, client, reg.SettingsHash)
	if _, err := builder.Update(ctx, reg.ID); err != nil {
		return fmt.Errorf("updating SakuraCloud ContainerRegistry[%s] is failed: %s", reg.ID, err)
	}

	return resourceSakuraCloudContainerRegistryRead(d, meta)
}

func resourceSakuraCloudContainerRegistryDelete(d *schema.ResourceData, meta interface{}) error {
	client, _, err := sakuraCloudClient(d, meta)
	if err != nil {
		return err
	}
	ctx, cancel := operationContext(d, schema.TimeoutDelete)
	defer cancel()

	regOp := sacloud.NewContainerRegistryOp(client)
	reg, err := regOp.Read(ctx, sakuraCloudID(d.Id()))
	if err != nil {
		if sacloud.IsNotFoundError(err) {
			d.SetId("")
			return nil
		}
		return fmt.Errorf("could not read SakuraCloud ContainerRegistry[%s]: %s", d.Id(), err)
	}

	if err := regOp.Delete(ctx, reg.ID); err != nil {
		return fmt.Errorf("deleting SakuraCloud ContainerRegistry[%s] is failed: %s", reg.ID, err)
	}

	d.SetId("")
	return nil
}

func setContainerRegistryResourceData(ctx context.Context, d *schema.ResourceData, client *APIClient, data *sacloud.ContainerRegistry) error {
	d.Set("name", data.Name)                         // nolint
	d.Set("access_level", data.AccessLevel.String()) // nolint
	d.Set("subdomain_label", data.SubDomainLabel)    // nolint
	d.Set("fqdn", data.FQDN)                         // nolint
	d.Set("icon_id", data.IconID.String())           // nolint
	d.Set("description", data.Description)           // nolint
	return d.Set("tags", flattenTags(data.Tags))
}

{'fraction_non_alphanumeric': 0.1253382949932341, 'fraction_numerical': 0.003044654939106901, 'mean_word_length': 3.7413793103448274, 'pattern_counts': {'":': 20, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '975948', 'n_tokens_mistral': 4202, 'n_tokens_neox': 3769, 'n_words': 896}