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