func (gateway Gateway) NewRequestForFile(method, fullUrl, accessToken string, body *os.File) (req *Request, apiErr error) { progressReader := NewProgressReader(body, gateway.ui, 5*time.Second) progressReader.Seek(0, 0) fileStats, err := body.Stat() if err != nil { apiErr = errors.NewWithError(T("Error getting file info"), err) return } request, err := http.NewRequest(method, fullUrl, progressReader) if err != nil { apiErr = errors.NewWithError(T("Error building request"), err) return } fileSize := fileStats.Size() progressReader.SetTotalSize(fileSize) request.ContentLength = fileSize if err != nil { apiErr = errors.NewWithError(T("Error building request"), err) return } return gateway.newRequest(request, accessToken, progressReader) }
func (repo CloudControllerCurlRepository) Request(method, path, headerString, body string) (resHeaders, resBody string, err error) { url := fmt.Sprintf("%s/%s", repo.config.ApiEndpoint(), strings.TrimLeft(path, "/")) req, err := repo.gateway.NewRequest(method, url, repo.config.AccessToken(), strings.NewReader(body)) if err != nil { return } err = mergeHeaders(req.HttpReq.Header, headerString) if err != nil { err = errors.NewWithError("Error parsing headers", err) return } res, err := repo.gateway.PerformRequest(req) if _, ok := err.(errors.HttpError); ok { err = nil } if err != nil { return } headerBytes, _ := httputil.DumpResponse(res, false) resHeaders = string(headerBytes) bytes, err := ioutil.ReadAll(res.Body) if err != nil { err = errors.NewWithError("Error reading response", err) } resBody = string(bytes) return }
func (repo CloudControllerApplicationBitsRepository) UploadApp(appGuid string, appDir string, fileSizePrinter func(path string, zipSize, fileCount uint64)) (apiErr error) { fileutils.TempDir("apps", func(uploadDir string, err error) { if err != nil { apiErr = err return } var presentFiles []resources.AppFileResource repo.sourceDir(appDir, func(sourceDir string, sourceErr error) { if sourceErr != nil { err = sourceErr return } presentFiles, err = repo.copyUploadableFiles(sourceDir, uploadDir) }) if err != nil { apiErr = err return } fileutils.TempFile("uploads", func(zipFile *os.File, err error) { if err != nil { apiErr = err return } zipFileSize := uint64(0) zipFileCount := uint64(0) err = repo.zipper.Zip(uploadDir, zipFile) switch err := err.(type) { case nil: stat, err := zipFile.Stat() if err != nil { apiErr = errors.NewWithError(T("Error zipping application"), err) return } zipFileSize = uint64(stat.Size()) zipFileCount = app_files.CountFiles(uploadDir) case *errors.EmptyDirError: zipFile = nil default: apiErr = errors.NewWithError(T("Error zipping application"), err) return } fileSizePrinter(appDir, zipFileSize, zipFileCount) apiErr = repo.uploadBits(appGuid, zipFile, presentFiles) if apiErr != nil { return } }) }) return }
func (repo CloudControllerBuildpackBitsRepository) UploadBuildpack(buildpack models.Buildpack, buildpackLocation string) (apiErr error) { fileutils.TempFile("buildpack-upload", func(zipFileToUpload *os.File, err error) { if err != nil { apiErr = errors.NewWithError(T("Couldn't create temp file for upload"), err) return } var buildpackFileName string if isWebURL(buildpackLocation) { buildpackFileName = path.Base(buildpackLocation) repo.downloadBuildpack(buildpackLocation, func(downloadFile *os.File, downloadErr error) { if downloadErr != nil { err = downloadErr return } err = normalizeBuildpackArchive(downloadFile, zipFileToUpload) }) } else { buildpackFileName = filepath.Base(buildpackLocation) stats, statError := os.Stat(buildpackLocation) if statError != nil { apiErr = errors.NewWithError(T("Error opening buildpack file"), statError) err = statError return } if stats.IsDir() { buildpackFileName += ".zip" // FIXME: remove once #71167394 is fixed err = repo.zipper.Zip(buildpackLocation, zipFileToUpload) } else { specifiedFile, openError := os.Open(buildpackLocation) if openError != nil { apiErr = errors.NewWithError(T("Couldn't open buildpack file"), openError) err = openError return } err = normalizeBuildpackArchive(specifiedFile, zipFileToUpload) } } if err != nil { apiErr = errors.NewWithError(T("Couldn't write zip file"), err) return } apiErr = repo.uploadBits(buildpack, zipFileToUpload, buildpackFileName) }) return }
func WrapNetworkErrors(host string, err error) error { var innerErr error switch typedErr := err.(type) { case *url.Error: innerErr = typedErr.Err case *websocket.DialError: innerErr = typedErr.Err } if innerErr != nil { switch typedErr := innerErr.(type) { case x509.UnknownAuthorityError: return errors.NewInvalidSSLCert(host, T("unknown authority")) case x509.HostnameError: return errors.NewInvalidSSLCert(host, T("not valid for the requested host")) case x509.CertificateInvalidError: return errors.NewInvalidSSLCert(host, "") case *net.OpError: return typedErr.Err } } return errors.NewWithError(T("Error performing request"), err) }
func (repo CloudControllerBuildpackRepository) Update(buildpack models.Buildpack) (updatedBuildpack models.Buildpack, apiErr error) { path := fmt.Sprintf("%s%s/%s", repo.config.ApiEndpoint(), buildpacks_path, buildpack.Guid) entity := resources.BuildpackEntity{ Name: buildpack.Name, Position: buildpack.Position, Enabled: buildpack.Enabled, Key: "", Filename: "", Locked: buildpack.Locked, } body, err := json.Marshal(entity) if err != nil { apiErr = errors.NewWithError("Could not serialize updates.", err) return } resource := new(resources.BuildpackResource) apiErr = repo.gateway.UpdateResource(path, bytes.NewReader(body), resource) if apiErr != nil { return } updatedBuildpack = resource.ToFields() return }
func (gateway Gateway) ListPaginatedResources(target string, path string, resource interface{}, cb func(interface{}) bool) (apiErr error) { for path != "" { pagination := NewPaginatedResources(resource) apiErr = gateway.GetResource(fmt.Sprintf("%s%s", target, path), &pagination) if apiErr != nil { return } resources, err := pagination.Resources() if err != nil { return errors.NewWithError("Error parsing JSON", err) } for _, resource := range resources { if !cb(resource) { return } } path = pagination.NextURL } return }
func (gateway Gateway) NewRequest(method, path, accessToken string, body io.ReadSeeker) (req *Request, apiErr error) { if body != nil { body.Seek(0, 0) } request, err := http.NewRequest(method, path, body) if err != nil { apiErr = errors.NewWithError("Error building request", err) return } if accessToken != "" { request.Header.Set("Authorization", accessToken) } request.Header.Set("accept", "application/json") request.Header.Set("content-type", "application/json") request.Header.Set("User-Agent", "go-cli "+cf.Version+" / "+runtime.GOOS) if body != nil { switch v := body.(type) { case *os.File: fileStats, err := v.Stat() if err != nil { break } request.ContentLength = fileStats.Size() } } req = &Request{HttpReq: request, SeekableBody: body} return }
func (gateway Gateway) NewRequest(method, path, accessToken string, body io.ReadSeeker) (req *Request, apiErr error) { request, err := http.NewRequest(method, path, body) if err != nil { apiErr = errors.NewWithError(T("Error building request"), err) return } return gateway.newRequest(request, accessToken, body) }
func (uaa UAAAuthenticationRepository) getAuthToken(data url.Values) error { type uaaErrorResponse struct { Code string `json:"error"` Description string `json:"error_description"` } type AuthenticationResponse struct { AccessToken string `json:"access_token"` TokenType string `json:"token_type"` RefreshToken string `json:"refresh_token"` Error uaaErrorResponse `json:"error"` } path := fmt.Sprintf("%s/oauth/token", uaa.config.AuthenticationEndpoint()) request, err := uaa.gateway.NewRequest("POST", path, "Basic "+base64.StdEncoding.EncodeToString([]byte("cf:")), strings.NewReader(data.Encode())) if err != nil { return errors.NewWithError(T("Failed to start oauth request"), err) } request.HttpReq.Header.Set("Content-Type", "application/x-www-form-urlencoded") response := new(AuthenticationResponse) _, err = uaa.gateway.PerformRequestForJSONResponse(request, &response) switch err.(type) { case nil: case errors.HttpError: return err case *errors.InvalidTokenError: return errors.New(T("Authentication has expired. Please log back in to re-authenticate.\n\nTIP: Use `cf login -a <endpoint> -u <user> -o <org> -s <space>` to log back in and re-authenticate.")) default: return errors.NewWithError(T("auth request failed"), err) } // TODO: get the actual status code if response.Error.Code != "" { return errors.NewHttpError(0, response.Error.Code, response.Error.Description) } uaa.config.SetAccessToken(fmt.Sprintf("%s %s", response.TokenType, response.AccessToken)) uaa.config.SetRefreshToken(response.RefreshToken) return nil }
func (repo CloudControllerApplicationBitsRepository) UploadBits(appGuid string, zipFile *os.File, presentFiles []resources.AppFileResource) (apiErr error) { url := fmt.Sprintf("%s/v2/apps/%s/bits", repo.config.ApiEndpoint(), appGuid) fileutils.TempFile("requests", func(requestFile *os.File, err error) { if err != nil { apiErr = errors.NewWithError(T("Error creating tmp file: {{.Err}}", map[string]interface{}{"Err": err}), err) return } // json.Marshal represents a nil value as "null" instead of an empty slice "[]" if presentFiles == nil { presentFiles = []resources.AppFileResource{} } presentFilesJSON, err := json.Marshal(presentFiles) if err != nil { apiErr = errors.NewWithError(T("Error marshaling JSON"), err) return } boundary, err := repo.writeUploadBody(zipFile, requestFile, presentFilesJSON) if err != nil { apiErr = errors.NewWithError(T("Error writing to tmp file: {{.Err}}", map[string]interface{}{"Err": err}), err) return } var request *net.Request request, apiErr = repo.gateway.NewRequest("PUT", url, repo.config.AccessToken(), requestFile) if apiErr != nil { return } contentType := fmt.Sprintf("multipart/form-data; boundary=%s", boundary) request.HttpReq.Header.Set("Content-Type", contentType) response := &resources.Resource{} _, apiErr = repo.gateway.PerformPollingRequestForJSONResponse(request, response, DefaultAppUploadBitsTimeout) if apiErr != nil { return } }) return }
func (gateway Gateway) PerformPollingRequestForJSONResponse(request *Request, response interface{}, timeout time.Duration) (headers http.Header, apiErr error) { query := request.HttpReq.URL.Query() query.Add("async", "true") request.HttpReq.URL.RawQuery = query.Encode() bytes, headers, rawResponse, apiErr := gateway.performRequestForResponseBytes(request) if apiErr != nil { return } defer rawResponse.Body.Close() if rawResponse.StatusCode > 203 || strings.TrimSpace(string(bytes)) == "" { return } err := json.Unmarshal(bytes, &response) if err != nil { apiErr = errors.NewWithError(T("Invalid JSON response from server"), err) return } asyncResource := &AsyncResource{} err = json.Unmarshal(bytes, &asyncResource) if err != nil { apiErr = errors.NewWithError(T("Invalid async response from server"), err) return } jobUrl := asyncResource.Metadata.URL if jobUrl == "" { return } if !strings.Contains(jobUrl, "/jobs/") { return } jobUrl = fmt.Sprintf("%s://%s%s", request.HttpReq.URL.Scheme, request.HttpReq.URL.Host, asyncResource.Metadata.URL) apiErr = gateway.waitForJob(jobUrl, request.HttpReq.Header.Get("Authorization"), timeout) return }
func (cmd *Push) zipWithBetterErrors(uploadDir string, zipFile *os.File) error { zipError := cmd.zipper.Zip(uploadDir, zipFile) switch err := zipError.(type) { case nil: return nil case *errors.EmptyDirError: zipFile = nil return zipError default: return errors.NewWithError(T("Error zipping application"), err) } }
func (gateway Gateway) performRequestForResponseBytes(request *Request) (bytes []byte, headers http.Header, rawResponse *http.Response, apiErr error) { rawResponse, apiErr = gateway.doRequestHandlingAuth(request) if apiErr != nil { return } bytes, err := ioutil.ReadAll(rawResponse.Body) if err != nil { apiErr = errors.NewWithError("Error reading response", err) } headers = rawResponse.Header return }
func (repo CCUserProvidedServiceInstanceRepository) Update(serviceInstanceFields models.ServiceInstanceFields) (apiErr error) { path := fmt.Sprintf("/v2/user_provided_service_instances/%s", serviceInstanceFields.Guid) reqBody := models.UserProvidedService{ Credentials: serviceInstanceFields.Params, SysLogDrainUrl: serviceInstanceFields.SysLogDrainUrl, } jsonBytes, err := json.Marshal(reqBody) if err != nil { apiErr = errors.NewWithError("Error parsing response", err) return } return repo.gateway.UpdateResource(repo.config.ApiEndpoint(), path, bytes.NewReader(jsonBytes)) }
func (repo CloudControllerApplicationRepository) Create(params models.AppParams) (createdApp models.Application, apiErr error) { data, err := repo.formatAppJSON(params) if err != nil { apiErr = errors.NewWithError(T("Failed to marshal JSON"), err) return } resource := new(resources.ApplicationResource) apiErr = repo.gateway.CreateResource(repo.config.ApiEndpoint(), "/v2/apps", strings.NewReader(data), resource) if apiErr != nil { return } createdApp = resource.ToModel() return }
func (gateway Gateway) PerformRequestForJSONResponse(request *Request, response interface{}) (headers http.Header, apiErr error) { bytes, headers, rawResponse, apiErr := gateway.performRequestForResponseBytes(request) if apiErr != nil { return } if rawResponse.StatusCode > 203 || strings.TrimSpace(string(bytes)) == "" { return } err := json.Unmarshal(bytes, &response) if err != nil { apiErr = errors.NewWithError("Invalid JSON response from server", err) } return }
func (repo CCUserProvidedServiceInstanceRepository) Update(serviceInstanceFields models.ServiceInstanceFields) (apiErr error) { path := fmt.Sprintf("%s/v2/user_provided_service_instances/%s", repo.config.ApiEndpoint(), serviceInstanceFields.Guid) type RequestBody struct { Credentials map[string]string `json:"credentials,omitempty"` SysLogDrainUrl string `json:"syslog_drain_url,omitempty"` } reqBody := RequestBody{serviceInstanceFields.Params, serviceInstanceFields.SysLogDrainUrl} jsonBytes, err := json.Marshal(reqBody) if err != nil { apiErr = errors.NewWithError("Error parsing response", err) return } return repo.gateway.UpdateResource(path, bytes.NewReader(jsonBytes)) }
func (repo CloudControllerApplicationRepository) Update(appGuid string, params models.AppParams) (updatedApp models.Application, apiErr error) { data, err := repo.formatAppJSON(params) if err != nil { apiErr = errors.NewWithError(T("Failed to marshal JSON"), err) return } path := fmt.Sprintf("/v2/apps/%s?inline-relations-depth=1", appGuid) resource := new(resources.ApplicationResource) apiErr = repo.gateway.UpdateResource(repo.config.ApiEndpoint(), path, strings.NewReader(data), resource) if apiErr != nil { return } updatedApp = resource.ToModel() return }
func (repo CCUserProvidedServiceInstanceRepository) Create(name, drainUrl string, params map[string]interface{}) (apiErr error) { path := "/v2/user_provided_service_instances" jsonBytes, err := json.Marshal(models.UserProvidedService{ Name: name, Credentials: params, SpaceGuid: repo.config.SpaceFields().Guid, SysLogDrainUrl: drainUrl, }) if err != nil { apiErr = errors.NewWithError("Error parsing response", err) return } return repo.gateway.CreateResource(repo.config.ApiEndpoint(), path, bytes.NewReader(jsonBytes)) }
func (repo CloudControllerBuildpackRepository) Create(name string, position *int, enabled *bool, locked *bool) (createdBuildpack models.Buildpack, apiErr error) { entity := resources.BuildpackEntity{Name: name, Position: position, Enabled: enabled, Locked: locked} body, err := json.Marshal(entity) if err != nil { apiErr = errors.NewWithError(T("Could not serialize information"), err) return } resource := new(resources.BuildpackResource) apiErr = repo.gateway.CreateResource(repo.config.ApiEndpoint(), buildpacks_path, bytes.NewReader(body), resource) if apiErr != nil { return } createdBuildpack = resource.ToFields() return }
func (repo CloudControllerApplicationBitsRepository) GetApplicationFiles(appFilesToCheck []resources.AppFileResource) ([]resources.AppFileResource, error) { allAppFilesJson, err := json.Marshal(appFilesToCheck) if err != nil { apiErr := errors.NewWithError(T("Failed to create json for resource_match request"), err) return nil, apiErr } presentFiles := []resources.AppFileResource{} apiErr := repo.gateway.UpdateResourceSync( repo.config.ApiEndpoint()+"/v2/resource_match", bytes.NewReader(allAppFilesJson), &presentFiles) if apiErr != nil { return nil, apiErr } return presentFiles, nil }
func (repo ManifestDiskRepository) ReadManifest(inputPath string) (*Manifest, error) { m := NewEmptyManifest() manifestPath, err := repo.manifestPath(inputPath) if err != nil { return m, errors.NewWithError(T("Error finding manifest"), err) } m.Path = manifestPath mapp, err := repo.readAllYAMLFiles(manifestPath) if err != nil { return m, err } m.Data = mapp return m, nil }
func (repo CloudControllerApplicationBitsRepository) getFilesToUpload(allAppFiles []models.AppFileFields) (appFilesToUpload []models.AppFileFields, presentFiles []resources.AppFileResource, apiErr error) { appFilesRequest := []resources.AppFileResource{} for _, file := range allAppFiles { appFilesRequest = append(appFilesRequest, resources.AppFileResource{ Path: file.Path, Sha1: file.Sha1, Size: file.Size, }) } allAppFilesJson, err := json.Marshal(appFilesRequest) if err != nil { apiErr = errors.NewWithError(T("Failed to create json for resource_match request"), err) return } apiErr = repo.gateway.UpdateResourceSync( repo.config.ApiEndpoint()+"/v2/resource_match", bytes.NewReader(allAppFilesJson), &presentFiles) if apiErr != nil { return } appFilesToUpload = make([]models.AppFileFields, len(allAppFiles)) copy(appFilesToUpload, allAppFiles) for _, file := range presentFiles { appFile := models.AppFileFields{ Path: file.Path, Sha1: file.Sha1, Size: file.Size, } appFilesToUpload = repo.deleteAppFile(appFilesToUpload, appFile) } return }
func (repo CloudControllerBuildpackBitsRepository) performMultiPartUpload(url string, fieldName string, fileName string, body io.Reader) (apiErr error) { fileutils.TempFile("requests", func(requestFile *os.File, err error) { if err != nil { apiErr = err return } writer := multipart.NewWriter(requestFile) part, err := writer.CreateFormFile(fieldName, fileName) if err != nil { writer.Close() return } _, err = io.Copy(part, body) writer.Close() if err != nil { apiErr = errors.NewWithError(T("Error creating upload"), err) return } var request *net.Request request, apiErr = repo.gateway.NewRequestForFile("PUT", url, repo.config.AccessToken(), requestFile) contentType := fmt.Sprintf("multipart/form-data; boundary=%s", writer.Boundary()) request.HttpReq.Header.Set("Content-Type", contentType) if apiErr != nil { return } _, apiErr = repo.gateway.PerformRequest(request) }) return }
func (repo CCUserProvidedServiceInstanceRepository) Create(name, drainUrl string, params map[string]string) (apiErr error) { path := fmt.Sprintf("%s/v2/user_provided_service_instances", repo.config.ApiEndpoint()) type RequestBody struct { Name string `json:"name"` Credentials map[string]string `json:"credentials"` SpaceGuid string `json:"space_guid"` SysLogDrainUrl string `json:"syslog_drain_url"` } jsonBytes, err := json.Marshal(RequestBody{ Name: name, Credentials: params, SpaceGuid: repo.config.SpaceFields().Guid, SysLogDrainUrl: drainUrl, }) if err != nil { apiErr = errors.NewWithError("Error parsing response", err) return } return repo.gateway.CreateResource(path, bytes.NewReader(jsonBytes)) }
deps.serviceRepo.FindServiceOfferingByLabelAndProviderServiceOffering = offering testcmd.RunCommand( NewPurgeServiceOffering(deps.ui, deps.config, deps.serviceRepo), []string{"-f", "the-service-name"}, deps.requirementsFactory, ) Expect(len(deps.ui.Prompts)).To(Equal(0)) Expect(deps.serviceRepo.PurgeServiceOfferingCalled).To(Equal(true)) }) It("fails with an error message when the request fails", func() { deps := setupDependencies() deps.serviceRepo.FindServiceOfferingByLabelAndProviderApiResponse = cferrors.NewWithError("oh no!", errors.New("!")) testcmd.RunCommand( NewPurgeServiceOffering(deps.ui, deps.config, deps.serviceRepo), []string{"-f", "-p", "the-provider", "the-service-name"}, deps.requirementsFactory, ) Expect(deps.ui.Outputs).To(ContainSubstrings( []string{"FAILED"}, []string{"oh no!"}, )) Expect(deps.serviceRepo.PurgeServiceOfferingCalled).To(Equal(false)) })
It("succeeds when the domain is found", func() { domain := models.DomainFields{Name: "example.com", Guid: "domain-guid"} domainRepo := &testapi.FakeDomainRepository{FindByNameInOrgDomain: []models.DomainFields{domain}} domainReq := NewDomainRequirement("example.com", ui, config, domainRepo) success := domainReq.Execute() Expect(success).To(BeTrue()) Expect(domainRepo.FindByNameInOrgName).To(Equal("example.com")) Expect(domainRepo.FindByNameInOrgGuid).To(Equal("the-org-guid")) Expect(domainReq.GetDomain()).To(Equal(domain)) }) It("fails when the domain is not found", func() { domainRepo := &testapi.FakeDomainRepository{FindByNameInOrgApiResponse: errors.NewModelNotFoundError("Domain", "")} domainReq := NewDomainRequirement("example.com", ui, config, domainRepo) testassert.AssertPanic(testterm.QuietPanic, func() { domainReq.Execute() }) }) It("fails when an error occurs fetching the domain", func() { domainRepo := &testapi.FakeDomainRepository{FindByNameInOrgApiResponse: errors.NewWithError("", errors.New(""))} domainReq := NewDomainRequirement("example.com", ui, config, domainRepo) testassert.AssertPanic(testterm.QuietPanic, func() { domainReq.Execute() }) }) })