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