github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/atlas/resource_artifact.go (about) 1 package atlas 2 3 import ( 4 "fmt" 5 "regexp" 6 7 "github.com/hashicorp/atlas-go/v1" 8 "github.com/hashicorp/terraform/helper/schema" 9 ) 10 11 var ( 12 // saneMetaKey is used to sanitize the metadata keys so that 13 // they can be accessed as a variable interpolation from TF 14 saneMetaKey = regexp.MustCompile("[^a-zA-Z0-9-_]") 15 ) 16 17 func resourceArtifact() *schema.Resource { 18 return &schema.Resource{ 19 Create: resourceArtifactRead, 20 Read: resourceArtifactRead, 21 Delete: resourceArtifactDelete, 22 23 Schema: map[string]*schema.Schema{ 24 "name": &schema.Schema{ 25 Type: schema.TypeString, 26 Required: true, 27 ForceNew: true, 28 Deprecated: `atlas_artifact is now deprecated. Use the Atlas Artifact Data Source instead. See https://terraform.io/docs/providers/atlas/d/artifact.html`, 29 }, 30 31 "type": &schema.Schema{ 32 Type: schema.TypeString, 33 Required: true, 34 ForceNew: true, 35 }, 36 37 "build": &schema.Schema{ 38 Type: schema.TypeString, 39 Optional: true, 40 ForceNew: true, 41 }, 42 43 "version": &schema.Schema{ 44 Type: schema.TypeString, 45 Optional: true, 46 ForceNew: true, 47 }, 48 49 "metadata_keys": &schema.Schema{ 50 Type: schema.TypeSet, 51 Optional: true, 52 ForceNew: true, 53 Elem: &schema.Schema{Type: schema.TypeString}, 54 Set: schema.HashString, 55 }, 56 57 "metadata": &schema.Schema{ 58 Type: schema.TypeMap, 59 Optional: true, 60 ForceNew: true, 61 }, 62 63 "file_url": &schema.Schema{ 64 Type: schema.TypeString, 65 Computed: true, 66 }, 67 68 "metadata_full": &schema.Schema{ 69 Type: schema.TypeMap, 70 Computed: true, 71 }, 72 73 "slug": &schema.Schema{ 74 Type: schema.TypeString, 75 Computed: true, 76 }, 77 78 "version_real": &schema.Schema{ 79 Type: schema.TypeString, 80 Computed: true, 81 }, 82 }, 83 } 84 } 85 86 func resourceArtifactRead(d *schema.ResourceData, meta interface{}) error { 87 client := meta.(*atlas.Client) 88 89 // Parse the slug from the name given of the artifact since the API 90 // expects these to be split. 91 user, name, err := atlas.ParseSlug(d.Get("name").(string)) 92 if err != nil { 93 return err 94 } 95 96 // Filter by version or build if given 97 var build, version string 98 if v, ok := d.GetOk("version"); ok { 99 version = v.(string) 100 } else if b, ok := d.GetOk("build"); ok { 101 build = b.(string) 102 } 103 104 // If we have neither, default to latest version 105 if build == "" && version == "" { 106 version = "latest" 107 } 108 109 // Compile the metadata search params 110 md := make(map[string]string) 111 for _, v := range d.Get("metadata_keys").(*schema.Set).List() { 112 md[v.(string)] = atlas.MetadataAnyValue 113 } 114 for k, v := range d.Get("metadata").(map[string]interface{}) { 115 md[k] = v.(string) 116 } 117 118 // Do the search! 119 vs, err := client.ArtifactSearch(&atlas.ArtifactSearchOpts{ 120 User: user, 121 Name: name, 122 Type: d.Get("type").(string), 123 Build: build, 124 Version: version, 125 Metadata: md, 126 }) 127 if err != nil { 128 return fmt.Errorf( 129 "Error searching for artifact '%s/%s': %s", 130 user, name, err) 131 } 132 133 if len(vs) == 0 { 134 return fmt.Errorf("No matching artifact for '%s/%s'", user, name) 135 } else if len(vs) > 1 { 136 return fmt.Errorf( 137 "Got %d results for '%s/%s', only one is allowed", 138 len(vs), user, name) 139 } 140 v := vs[0] 141 142 d.SetId(v.ID) 143 if v.ID == "" { 144 d.SetId(fmt.Sprintf("%s %d", v.Tag, v.Version)) 145 } 146 d.Set("version_real", v.Version) 147 d.Set("metadata_full", cleanMetadata(v.Metadata)) 148 d.Set("slug", v.Slug) 149 150 d.Set("file_url", "") 151 if u, err := client.ArtifactFileURL(v); err != nil { 152 return fmt.Errorf( 153 "Error reading file URL: %s", err) 154 } else if u != nil { 155 d.Set("file_url", u.String()) 156 } 157 158 return nil 159 } 160 161 func resourceArtifactDelete(d *schema.ResourceData, meta interface{}) error { 162 // This just always succeeds since this is a readonly element. 163 d.SetId("") 164 return nil 165 } 166 167 // cleanMetadata is used to ensure the metadata is accessible as 168 // a variable by doing a simple re-write. 169 func cleanMetadata(in map[string]string) map[string]string { 170 out := make(map[string]string, len(in)) 171 for k, v := range in { 172 sane := saneMetaKey.ReplaceAllString(k, "-") 173 out[sane] = v 174 } 175 return out 176 }