github.com/cloudfoundry-attic/cli-with-i18n@v6.32.1-0.20171002233121-7401370d3b85+incompatible/api/cloudcontroller/ccv3/package.go (about)

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