github.com/ablease/cli@v6.37.1-0.20180613014814-3adbb7d7fb19+incompatible/api/cloudcontroller/ccv3/package.go (about) 1 package ccv3 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "io" 7 "mime/multipart" 8 "os" 9 "path/filepath" 10 11 "code.cloudfoundry.org/cli/api/cloudcontroller" 12 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 13 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant" 14 "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/internal" 15 ) 16 17 // Package represents a Cloud Controller V3 Package. 18 type Package struct { 19 // CreatedAt is the time with zone when the object was created. 20 CreatedAt string 21 22 // DockerImage is the registry address of the docker image. 23 DockerImage string 24 25 // DockerPassword is the password for the docker image's registry. 26 DockerPassword string 27 28 // DockerUsername is the username for the docker image's registry. 29 DockerUsername string 30 31 // GUID is the unique identifier of the package. 32 GUID string 33 34 // Links are links to related resources. 35 Links APILinks 36 37 // Relationships are a list of relationships to other resources. 38 Relationships Relationships 39 40 // State is the state of the package. 41 State constant.PackageState 42 43 // Type is the package type. 44 Type constant.PackageType 45 } 46 47 // MarshalJSON converts a Package into a Cloud Controller Package. 48 func (p Package) MarshalJSON() ([]byte, error) { 49 type ccPackageData struct { 50 Image string `json:"image,omitempty"` 51 Username string `json:"username,omitempty"` 52 Password string `json:"password,omitempty"` 53 } 54 var ccPackage struct { 55 GUID string `json:"guid,omitempty"` 56 CreatedAt string `json:"created_at,omitempty"` 57 Links APILinks `json:"links,omitempty"` 58 Relationships Relationships `json:"relationships,omitempty"` 59 State constant.PackageState `json:"state,omitempty"` 60 Type constant.PackageType `json:"type,omitempty"` 61 Data *ccPackageData `json:"data,omitempty"` 62 } 63 64 ccPackage.GUID = p.GUID 65 ccPackage.CreatedAt = p.CreatedAt 66 ccPackage.Links = p.Links 67 ccPackage.Relationships = p.Relationships 68 ccPackage.State = p.State 69 ccPackage.Type = p.Type 70 if p.DockerImage != "" { 71 ccPackage.Data = &ccPackageData{ 72 Image: p.DockerImage, 73 Username: p.DockerUsername, 74 Password: p.DockerPassword, 75 } 76 } 77 78 return json.Marshal(ccPackage) 79 } 80 81 // UnmarshalJSON helps unmarshal a Cloud Controller Package response. 82 func (p *Package) UnmarshalJSON(data []byte) error { 83 var ccPackage struct { 84 GUID string `json:"guid,omitempty"` 85 CreatedAt string `json:"created_at,omitempty"` 86 Links APILinks `json:"links,omitempty"` 87 Relationships Relationships `json:"relationships,omitempty"` 88 State constant.PackageState `json:"state,omitempty"` 89 Type constant.PackageType `json:"type,omitempty"` 90 Data struct { 91 Image string `json:"image"` 92 Username string `json:"username"` 93 Password string `json:"password"` 94 } `json:"data"` 95 } 96 err := cloudcontroller.DecodeJSON(data, &ccPackage) 97 if err != nil { 98 return err 99 } 100 101 p.GUID = ccPackage.GUID 102 p.CreatedAt = ccPackage.CreatedAt 103 p.Links = ccPackage.Links 104 p.Relationships = ccPackage.Relationships 105 p.State = ccPackage.State 106 p.Type = ccPackage.Type 107 p.DockerImage = ccPackage.Data.Image 108 p.DockerUsername = ccPackage.Data.Username 109 p.DockerPassword = ccPackage.Data.Password 110 111 return nil 112 } 113 114 // CreatePackage creates a package with the given settings, Type and the 115 // ApplicationRelationship must be set. 116 func (client *Client) CreatePackage(pkg Package) (Package, Warnings, error) { 117 bodyBytes, err := json.Marshal(pkg) 118 if err != nil { 119 return Package{}, nil, err 120 } 121 122 request, err := client.newHTTPRequest(requestOptions{ 123 RequestName: internal.PostPackageRequest, 124 Body: bytes.NewReader(bodyBytes), 125 }) 126 if err != nil { 127 return Package{}, nil, err 128 } 129 130 var responsePackage Package 131 response := cloudcontroller.Response{ 132 Result: &responsePackage, 133 } 134 err = client.connection.Make(request, &response) 135 136 return responsePackage, response.Warnings, err 137 } 138 139 // GetPackage returns the package with the given GUID. 140 func (client *Client) GetPackage(packageGUID string) (Package, Warnings, error) { 141 request, err := client.newHTTPRequest(requestOptions{ 142 RequestName: internal.GetPackageRequest, 143 URIParams: internal.Params{"package_guid": packageGUID}, 144 }) 145 if err != nil { 146 return Package{}, nil, err 147 } 148 149 var responsePackage Package 150 response := cloudcontroller.Response{ 151 Result: &responsePackage, 152 } 153 err = client.connection.Make(request, &response) 154 155 return responsePackage, response.Warnings, err 156 } 157 158 // GetPackages returns the list of packages. 159 func (client *Client) GetPackages(query ...Query) ([]Package, Warnings, error) { 160 request, err := client.newHTTPRequest(requestOptions{ 161 RequestName: internal.GetPackagesRequest, 162 Query: query, 163 }) 164 if err != nil { 165 return nil, nil, err 166 } 167 168 var fullPackagesList []Package 169 warnings, err := client.paginate(request, Package{}, func(item interface{}) error { 170 if pkg, ok := item.(Package); ok { 171 fullPackagesList = append(fullPackagesList, pkg) 172 } else { 173 return ccerror.UnknownObjectInListError{ 174 Expected: Package{}, 175 Unexpected: item, 176 } 177 } 178 return nil 179 }) 180 181 return fullPackagesList, warnings, err 182 } 183 184 // UploadPackage uploads a file to a given package's Upload resource. Note: 185 // fileToUpload is read entirely into memory prior to sending data to CC. 186 func (client *Client) UploadPackage(pkg Package, fileToUpload string) (Package, Warnings, error) { 187 link, ok := pkg.Links["upload"] 188 if !ok { 189 return Package{}, nil, ccerror.UploadLinkNotFoundError{PackageGUID: pkg.GUID} 190 } 191 192 body, contentType, err := client.createUploadStream(fileToUpload, "bits") 193 if err != nil { 194 return Package{}, nil, err 195 } 196 197 request, err := client.newHTTPRequest(requestOptions{ 198 URL: link.HREF, 199 Method: link.Method, 200 Body: body, 201 }) 202 if err != nil { 203 return Package{}, nil, err 204 } 205 206 request.Header.Set("Content-Type", contentType) 207 208 var responsePackage Package 209 response := cloudcontroller.Response{ 210 Result: &responsePackage, 211 } 212 err = client.connection.Make(request, &response) 213 214 return responsePackage, response.Warnings, err 215 } 216 217 func (*Client) createUploadStream(path string, paramName string) (io.ReadSeeker, string, error) { 218 file, err := os.Open(path) 219 if err != nil { 220 return nil, "", err 221 } 222 defer file.Close() 223 224 body := &bytes.Buffer{} 225 writer := multipart.NewWriter(body) 226 part, err := writer.CreateFormFile(paramName, filepath.Base(path)) 227 if err != nil { 228 return nil, "", err 229 } 230 _, err = io.Copy(part, file) 231 if err != nil { 232 return nil, "", err 233 } 234 235 err = writer.Close() 236 237 return bytes.NewReader(body.Bytes()), writer.FormDataContentType(), err 238 }