/vendor/github.com/hashicorp/terraform/builtin/providers/ovh/resource_ovh_publiccloud_user.go
https://github.com/heap/terraform-ebs-attachmentizer · Go · 289 lines · 230 code · 58 blank · 1 comment · 34 complexity · 6942d650206153af4ffa0279427b6391 MD5 · raw file
- package ovh
- import (
- "fmt"
- "log"
- "regexp"
- "strconv"
- "time"
- "github.com/hashicorp/terraform/helper/resource"
- "github.com/hashicorp/terraform/helper/schema"
- "github.com/ovh/go-ovh/ovh"
- )
- func resourcePublicCloudUser() *schema.Resource {
- return &schema.Resource{
- Create: resourcePublicCloudUserCreate,
- Read: resourcePublicCloudUserRead,
- Delete: resourcePublicCloudUserDelete,
- Importer: &schema.ResourceImporter{
- State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
- return []*schema.ResourceData{d}, nil
- },
- },
- Schema: map[string]*schema.Schema{
- "project_id": &schema.Schema{
- Type: schema.TypeString,
- Required: true,
- ForceNew: true,
- DefaultFunc: schema.EnvDefaultFunc("OVH_PROJECT_ID", nil),
- },
- "description": &schema.Schema{
- Type: schema.TypeString,
- Optional: true,
- ForceNew: true,
- },
- "username": &schema.Schema{
- Type: schema.TypeString,
- Computed: true,
- },
- "password": &schema.Schema{
- Type: schema.TypeString,
- Computed: true,
- Sensitive: true,
- },
- "status": &schema.Schema{
- Type: schema.TypeString,
- Computed: true,
- },
- "creation_date": &schema.Schema{
- Type: schema.TypeString,
- Computed: true,
- },
- "openstack_rc": &schema.Schema{
- Type: schema.TypeMap,
- Optional: true,
- Computed: true,
- },
- },
- }
- }
- func resourcePublicCloudUserCreate(d *schema.ResourceData, meta interface{}) error {
- config := meta.(*Config)
- projectId := d.Get("project_id").(string)
- params := &PublicCloudUserCreateOpts{
- ProjectId: projectId,
- Description: d.Get("description").(string),
- }
- r := &PublicCloudUserResponse{}
- log.Printf("[DEBUG] Will create public cloud user: %s", params)
- // Resource is partial because we will also compute Openstack RC & creds
- d.Partial(true)
- endpoint := fmt.Sprintf("/cloud/project/%s/user", params.ProjectId)
- err := config.OVHClient.Post(endpoint, params, r)
- if err != nil {
- return fmt.Errorf("calling Post %s with params %s:\n\t %q", endpoint, params, err)
- }
- log.Printf("[DEBUG] Waiting for User %s:", r)
- stateConf := &resource.StateChangeConf{
- Pending: []string{"creating"},
- Target: []string{"ok"},
- Refresh: waitForPublicCloudUserActive(config.OVHClient, projectId, strconv.Itoa(r.Id)),
- Timeout: 10 * time.Minute,
- Delay: 10 * time.Second,
- MinTimeout: 3 * time.Second,
- }
- _, err = stateConf.WaitForState()
- if err != nil {
- return fmt.Errorf("waiting for user (%s): %s", params, err)
- }
- log.Printf("[DEBUG] Created User %s", r)
- readPublicCloudUser(d, r, true)
- openstackrc := make(map[string]string)
- err = publicCloudUserGetOpenstackRC(projectId, d.Id(), config.OVHClient, openstackrc)
- if err != nil {
- return fmt.Errorf("Creating openstack creds for user %s: %s", d.Id(), err)
- }
- d.Set("openstack_rc", &openstackrc)
- d.Partial(false)
- return nil
- }
- func resourcePublicCloudUserRead(d *schema.ResourceData, meta interface{}) error {
- config := meta.(*Config)
- projectId := d.Get("project_id").(string)
- d.Partial(true)
- r := &PublicCloudUserResponse{}
- log.Printf("[DEBUG] Will read public cloud user %s from project: %s", d.Id(), projectId)
- endpoint := fmt.Sprintf("/cloud/project/%s/user/%s", projectId, d.Id())
- err := config.OVHClient.Get(endpoint, r)
- if err != nil {
- return fmt.Errorf("calling Get %s:\n\t %q", endpoint, err)
- }
- readPublicCloudUser(d, r, false)
- openstackrc := make(map[string]string)
- err = publicCloudUserGetOpenstackRC(projectId, d.Id(), config.OVHClient, openstackrc)
- if err != nil {
- return fmt.Errorf("Reading openstack creds for user %s: %s", d.Id(), err)
- }
- d.Set("openstack_rc", &openstackrc)
- d.Partial(false)
- log.Printf("[DEBUG] Read Public Cloud User %s", r)
- return nil
- }
- func resourcePublicCloudUserDelete(d *schema.ResourceData, meta interface{}) error {
- config := meta.(*Config)
- projectId := d.Get("project_id").(string)
- id := d.Id()
- log.Printf("[DEBUG] Will delete public cloud user %s from project: %s", id, projectId)
- endpoint := fmt.Sprintf("/cloud/project/%s/user/%s", projectId, id)
- err := config.OVHClient.Delete(endpoint, nil)
- if err != nil {
- return fmt.Errorf("calling Delete %s:\n\t %q", endpoint, err)
- }
- log.Printf("[DEBUG] Deleting Public Cloud User %s from project %s:", id, projectId)
- stateConf := &resource.StateChangeConf{
- Pending: []string{"deleting"},
- Target: []string{"deleted"},
- Refresh: waitForPublicCloudUserDelete(config.OVHClient, projectId, id),
- Timeout: 10 * time.Minute,
- Delay: 10 * time.Second,
- MinTimeout: 3 * time.Second,
- }
- _, err = stateConf.WaitForState()
- if err != nil {
- return fmt.Errorf("Deleting Public Cloud user %s from project %s", id, projectId)
- }
- log.Printf("[DEBUG] Deleted Public Cloud User %s from project %s", id, projectId)
- d.SetId("")
- return nil
- }
- func publicCloudUserExists(projectId, id string, c *ovh.Client) error {
- r := &PublicCloudUserResponse{}
- log.Printf("[DEBUG] Will read public cloud user for project: %s, id: %s", projectId, id)
- endpoint := fmt.Sprintf("/cloud/project/%s/user/%s", projectId, id)
- err := c.Get(endpoint, r)
- if err != nil {
- return fmt.Errorf("calling Get %s:\n\t %q", endpoint, err)
- }
- log.Printf("[DEBUG] Read public cloud user: %s", r)
- return nil
- }
- var publicCloudUserOSTenantName = regexp.MustCompile("export OS_TENANT_NAME=\"?([[:alnum:]]+)\"?")
- var publicCloudUserOSTenantId = regexp.MustCompile("export OS_TENANT_ID=\"??([[:alnum:]]+)\"??")
- var publicCloudUserOSAuthURL = regexp.MustCompile("export OS_AUTH_URL=\"??([[:^space:]]+)\"??")
- var publicCloudUserOSUsername = regexp.MustCompile("export OS_USERNAME=\"?([[:alnum:]]+)\"?")
- func publicCloudUserGetOpenstackRC(projectId, id string, c *ovh.Client, rc map[string]string) error {
- log.Printf("[DEBUG] Will read public cloud user openstack rc for project: %s, id: %s", projectId, id)
- endpoint := fmt.Sprintf("/cloud/project/%s/user/%s/openrc?region=to_be_overriden", projectId, id)
- r := &PublicCloudUserOpenstackRC{}
- err := c.Get(endpoint, r)
- if err != nil {
- return fmt.Errorf("calling Get %s:\n\t %q", endpoint, err)
- }
- authURL := publicCloudUserOSAuthURL.FindStringSubmatch(r.Content)
- if authURL == nil {
- return fmt.Errorf("couln't extract OS_AUTH_URL from content: \n\t%s", r.Content)
- }
- tenantName := publicCloudUserOSTenantName.FindStringSubmatch(r.Content)
- if tenantName == nil {
- return fmt.Errorf("couln't extract OS_TENANT_NAME from content: \n\t%s", r.Content)
- }
- tenantId := publicCloudUserOSTenantId.FindStringSubmatch(r.Content)
- if tenantId == nil {
- return fmt.Errorf("couln't extract OS_TENANT_ID from content: \n\t%s", r.Content)
- }
- username := publicCloudUserOSUsername.FindStringSubmatch(r.Content)
- if username == nil {
- return fmt.Errorf("couln't extract OS_USERNAME from content: \n\t%s", r.Content)
- }
- rc["OS_AUTH_URL"] = authURL[1]
- rc["OS_TENANT_ID"] = tenantId[1]
- rc["OS_TENANT_NAME"] = tenantName[1]
- rc["OS_USERNAME"] = username[1]
- return nil
- }
- func readPublicCloudUser(d *schema.ResourceData, r *PublicCloudUserResponse, setPassword bool) {
- d.Set("description", r.Description)
- d.Set("status", r.Status)
- d.Set("creation_date", r.CreationDate)
- d.Set("username", r.Username)
- if setPassword {
- d.Set("password", r.Password)
- }
- d.SetId(strconv.Itoa(r.Id))
- }
- func waitForPublicCloudUserActive(c *ovh.Client, projectId, PublicCloudUserId string) resource.StateRefreshFunc {
- return func() (interface{}, string, error) {
- r := &PublicCloudUserResponse{}
- endpoint := fmt.Sprintf("/cloud/project/%s/user/%s", projectId, PublicCloudUserId)
- err := c.Get(endpoint, r)
- if err != nil {
- return r, "", err
- }
- log.Printf("[DEBUG] Pending User: %s", r)
- return r, r.Status, nil
- }
- }
- func waitForPublicCloudUserDelete(c *ovh.Client, projectId, PublicCloudUserId string) resource.StateRefreshFunc {
- return func() (interface{}, string, error) {
- r := &PublicCloudUserResponse{}
- endpoint := fmt.Sprintf("/cloud/project/%s/user/%s", projectId, PublicCloudUserId)
- err := c.Get(endpoint, r)
- if err != nil {
- if err.(*ovh.APIError).Code == 404 {
- log.Printf("[DEBUG] user id %s on project %s deleted", PublicCloudUserId, projectId)
- return r, "deleted", nil
- } else {
- return r, "", err
- }
- }
- log.Printf("[DEBUG] Pending User: %s", r)
- return r, r.Status, nil
- }
- }