github.com/ctrox/terraform@v0.11.12-beta1/state/remote/artifactory.go (about) 1 package remote 2 3 import ( 4 "crypto/md5" 5 "fmt" 6 "os" 7 "strings" 8 9 artifactory "github.com/lusis/go-artifactory/src/artifactory.v401" 10 ) 11 12 const ARTIF_TFSTATE_NAME = "terraform.tfstate" 13 14 func artifactoryFactory(conf map[string]string) (Client, error) { 15 userName, ok := conf["username"] 16 if !ok { 17 userName = os.Getenv("ARTIFACTORY_USERNAME") 18 if userName == "" { 19 return nil, fmt.Errorf( 20 "missing 'username' configuration or ARTIFACTORY_USERNAME environment variable") 21 } 22 } 23 password, ok := conf["password"] 24 if !ok { 25 password = os.Getenv("ARTIFACTORY_PASSWORD") 26 if password == "" { 27 return nil, fmt.Errorf( 28 "missing 'password' configuration or ARTIFACTORY_PASSWORD environment variable") 29 } 30 } 31 url, ok := conf["url"] 32 if !ok { 33 url = os.Getenv("ARTIFACTORY_URL") 34 if url == "" { 35 return nil, fmt.Errorf( 36 "missing 'url' configuration or ARTIFACTORY_URL environment variable") 37 } 38 } 39 repo, ok := conf["repo"] 40 if !ok { 41 return nil, fmt.Errorf( 42 "missing 'repo' configuration") 43 } 44 subpath, ok := conf["subpath"] 45 if !ok { 46 return nil, fmt.Errorf( 47 "missing 'subpath' configuration") 48 } 49 50 clientConf := &artifactory.ClientConfig{ 51 BaseURL: url, 52 Username: userName, 53 Password: password, 54 } 55 nativeClient := artifactory.NewClient(clientConf) 56 57 return &ArtifactoryClient{ 58 nativeClient: &nativeClient, 59 userName: userName, 60 password: password, 61 url: url, 62 repo: repo, 63 subpath: subpath, 64 }, nil 65 66 } 67 68 type ArtifactoryClient struct { 69 nativeClient *artifactory.ArtifactoryClient 70 userName string 71 password string 72 url string 73 repo string 74 subpath string 75 } 76 77 func (c *ArtifactoryClient) Get() (*Payload, error) { 78 p := fmt.Sprintf("%s/%s/%s", c.repo, c.subpath, ARTIF_TFSTATE_NAME) 79 output, err := c.nativeClient.Get(p, make(map[string]string)) 80 if err != nil { 81 if strings.Contains(err.Error(), "404") { 82 return nil, nil 83 } 84 return nil, err 85 } 86 87 // TODO: migrate to using X-Checksum-Md5 header from artifactory 88 // needs to be exposed by go-artifactory first 89 90 hash := md5.Sum(output) 91 payload := &Payload{ 92 Data: output, 93 MD5: hash[:md5.Size], 94 } 95 96 // If there was no data, then return nil 97 if len(payload.Data) == 0 { 98 return nil, nil 99 } 100 101 return payload, nil 102 } 103 104 func (c *ArtifactoryClient) Put(data []byte) error { 105 p := fmt.Sprintf("%s/%s/%s", c.repo, c.subpath, ARTIF_TFSTATE_NAME) 106 if _, err := c.nativeClient.Put(p, string(data), make(map[string]string)); err == nil { 107 return nil 108 } else { 109 return fmt.Errorf("Failed to upload state: %v", err) 110 } 111 } 112 113 func (c *ArtifactoryClient) Delete() error { 114 p := fmt.Sprintf("%s/%s/%s", c.repo, c.subpath, ARTIF_TFSTATE_NAME) 115 err := c.nativeClient.Delete(p) 116 return err 117 }