copyFileContents(originalS3OutPath, s3OutPath)
	Expect(err).NotTo(HaveOccurred())

	By("Ensuring copy of s3-out is executable")
	err = os.Chmod(s3OutPath, os.ModePerm)
	Expect(err).NotTo(HaveOccurred())

	By("Creating pivnet client (for out-of-band operations)")
	testLogger := logger.NewLogger(GinkgoWriter)

	clientConfig := pivnet.NewClientConfig{
		URL:       pivnet.URL,
		Token:     pivnetAPIToken,
		UserAgent: "pivnet-resource/integration-test",
	}
	pivnetClient = pivnet.NewClient(clientConfig, testLogger)
})

var _ = AfterSuite(func() {
	gexec.CleanupBuildArtifacts()
})

func getProductReleases(productSlug string) []pivnet.Release {
	productURL := fmt.Sprintf(
		"https://network.pivotal.io/api/v2/products/%s/releases",
		productSlug)

	req, err := http.NewRequest("GET", productURL, nil)
	Expect(err).NotTo(HaveOccurred())

	req.Header.Add("Authorization", fmt.Sprintf("Token %s", pivnetAPIToken))
		fakeLogger      logger.Logger
	)

	BeforeEach(func() {
		server = ghttp.NewServer()
		apiAddress = server.URL() + apiPrefix
		token = "my-auth-token"
		userAgent = "pivnet-resource/0.1.0 (some-url)"

		fakeLogger = &logger_fakes.FakeLogger{}
		newClientConfig = pivnet.NewClientConfig{
			URL:       apiAddress,
			Token:     token,
			UserAgent: userAgent,
		}
		client = pivnet.NewClient(newClientConfig, fakeLogger)
	})

	AfterEach(func() {
		server.Close()
	})

	Describe("FindProductForSlug", func() {
		var (
			slug = "my-product"
		)
		Context("when the product can be found", func() {
			It("returns the located product", func() {
				response := fmt.Sprintf(`{"id": 3, "slug": "%s"}`, slug)

				server.AppendHandlers(
Example #3
0
func main() {
	if version == "" {
		version = "dev"
	}

	var input concourse.CheckRequest

	logFile, err := ioutil.TempFile("", "pivnet-resource-check.log")
	if err != nil {
		log.Fatalln(err)
	}
	fmt.Fprintf(logFile, "PivNet Resource version: %s\n", version)

	fmt.Fprintf(os.Stderr, "Logging to %s\n", logFile.Name())

	err = json.NewDecoder(os.Stdin).Decode(&input)
	if err != nil {
		fmt.Fprintf(logFile, "Exiting with error: %v\n", err)
		log.Fatalln(err)
	}

	sanitized := concourse.SanitizedSource(input.Source)
	sanitizer := sanitizer.NewSanitizer(sanitized, logFile)

	l = logger.NewLogger(sanitizer)

	logDir := filepath.Dir(logFile.Name())
	existingLogFiles, err := filepath.Glob(filepath.Join(logDir, "pivnet-resource-check.log*"))
	if err != nil {
		l.Debugf("Exiting with error: %v\n", err)
		log.Fatalln(err)
	}

	for _, f := range existingLogFiles {
		if filepath.Base(f) != filepath.Base(logFile.Name()) {
			l.Debugf("Removing existing log file: %s\n", f)
			err := os.Remove(f)
			if err != nil {
				l.Debugf("Exiting with error: %v\n", err)
				log.Fatalln(err)
			}
		}
	}

	mustBeNonEmpty(input.Source.APIToken, "api_token")
	mustBeNonEmpty(input.Source.ProductSlug, "product_slug")

	l.Debugf("Received input: %+v\n", input)

	clientConfig := pivnet.NewClientConfig{
		URL:       pivnet.URL,
		Token:     input.Source.APIToken,
		UserAgent: fmt.Sprintf("pivnet-resource/%s", version),
	}
	client := pivnet.NewClient(
		clientConfig,
		l,
	)

	l.Debugf("Getting all product versions\n")

	allVersions, err := client.ProductVersions(input.Source.ProductSlug)
	if err != nil {
		l.Debugf("Exiting with error: %v\n", err)
		log.Fatalln(err)
	}

	l.Debugf("All known versions: %+v\n", allVersions)

	newVersions, err := versions.Since(allVersions, input.Version.ProductVersion)
	if err != nil {
		l.Debugf("Exiting with error: %v\n", err)
		log.Fatalln(err)
	}

	l.Debugf("New versions: %+v\n", newVersions)

	reversedVersions, err := versions.Reverse(newVersions)
	if err != nil {
		l.Debugf("Exiting with error: %v\n", err)
		log.Fatalln(err)
	}

	var out concourse.CheckResponse
	for _, v := range reversedVersions {
		out = append(out, concourse.Version{ProductVersion: v})
	}

	if len(out) == 0 {
		out = append(out, concourse.Version{ProductVersion: allVersions[0]})
	}

	l.Debugf("Returning output: %+v\n", out)

	err = json.NewEncoder(os.Stdout).Encode(out)
	if err != nil {
		l.Debugf("Exiting with error: %v\n", err)
		log.Fatalln(err)
	}
}
Example #4
0
func main() {
	if version == "" {
		version = "dev"
	}

	if len(os.Args) < 2 {
		log.Fatalln(fmt.Sprintf(
			"not enough args - usage: %s <sources directory>", os.Args[0]))
	}

	sourcesDir := os.Args[1]

	myDir, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err != nil {
		log.Fatalln(err)
	}

	var input concourse.OutRequest

	err = json.NewDecoder(os.Stdin).Decode(&input)
	if err != nil {
		log.Fatalln(err)
	}

	logFile, err := ioutil.TempFile("", "pivnet-resource-out.log")
	if err != nil {
		log.Fatalln(err)
	}
	fmt.Fprintf(logFile, "PivNet Resource version: %s\n", version)

	fmt.Fprintf(os.Stderr, "logging to %s\n", logFile.Name())

	sanitized := concourse.SanitizedSource(input.Source)
	sanitizer := sanitizer.NewSanitizer(sanitized, logFile)

	l := logger.NewLogger(sanitizer)

	mustBeNonEmpty(input.Source.APIToken, "api_token")
	mustBeNonEmpty(input.Source.ProductSlug, "product_slug")
	mustBeNonEmpty(input.Params.VersionFile, "version_file")
	mustBeNonEmpty(input.Params.ReleaseTypeFile, "release_type_file")
	mustBeNonEmpty(input.Params.EulaSlugFile, "eula_slug_file")

	skipUpload := input.Params.FileGlob == "" && input.Params.FilepathPrefix == ""

	if !skipUpload {
		mustBeNonEmpty(input.Source.AccessKeyID, "access_key_id")
		mustBeNonEmpty(input.Source.SecretAccessKey, "secret_access_key")
		mustBeNonEmpty(input.Params.FileGlob, "file glob")
		mustBeNonEmpty(input.Params.FilepathPrefix, "s3_filepath_prefix")
	}

	l.Debugf("Received input: %+v\n", input)

	clientConfig := pivnet.NewClientConfig{
		URL:       pivnet.URL,
		Token:     input.Source.APIToken,
		UserAgent: fmt.Sprintf("pivnet-resource/%s", version),
	}
	pivnetClient := pivnet.NewClient(
		clientConfig,
		l,
	)

	productSlug := input.Source.ProductSlug

	config := pivnet.CreateReleaseConfig{
		ProductSlug:    productSlug,
		ReleaseType:    readStringContents(sourcesDir, input.Params.ReleaseTypeFile),
		EulaSlug:       readStringContents(sourcesDir, input.Params.EulaSlugFile),
		ProductVersion: readStringContents(sourcesDir, input.Params.VersionFile),
		Description:    readStringContents(sourcesDir, input.Params.DescriptionFile),
		ReleaseDate:    readStringContents(sourcesDir, input.Params.ReleaseDateFile),
	}

	release, err := pivnetClient.CreateRelease(config)
	if err != nil {
		log.Fatalln(err)
	}

	if skipUpload {
		l.Debugf("File glob and s3_filepath_prefix not provided - skipping upload to s3")
	} else {
		s3Client := s3.NewClient(s3.NewClientConfig{
			AccessKeyID:     input.Source.AccessKeyID,
			SecretAccessKey: input.Source.SecretAccessKey,
			RegionName:      "eu-west-1",
			Bucket:          "pivotalnetwork",

			Logger: l,

			Stdout: os.Stdout,
			Stderr: logFile,

			OutBinaryPath: filepath.Join(myDir, s3OutBinaryName),
		})

		uploaderClient := uploader.NewClient(uploader.Config{
			FileGlob:       input.Params.FileGlob,
			FilepathPrefix: input.Params.FilepathPrefix,
			SourcesDir:     sourcesDir,

			Logger: l,

			Transport: s3Client,
		})

		files, err := uploaderClient.Upload()
		for filename, remotePath := range files {
			product, err := pivnetClient.FindProductForSlug(productSlug)
			if err != nil {
				log.Fatalln(err)
			}

			l.Debugf(
				"Creating product file: {product_slug: %s, filename: %s, aws_object_key: %s, file_version: %s}\n",
				productSlug,
				filename,
				remotePath,
				release.Version,
			)

			productFile, err := pivnetClient.CreateProductFile(pivnet.CreateProductFileConfig{
				ProductSlug:  productSlug,
				Name:         filename,
				AWSObjectKey: remotePath,
				FileVersion:  release.Version,
			})
			if err != nil {
				log.Fatalln(err)
			}

			l.Debugf(
				"Adding product file: {product_slug: %s, product_id: %d, filename: %s, product_file_id: %d}\n",
				productSlug,
				product.ID,
				filename,
				productFile.ID,
			)

			err = pivnetClient.AddProductFile(product.ID, release.ID, productFile.ID)
			if err != nil {
				log.Fatalln(err)
			}
		}

		if err != nil {
			log.Fatal(err)
		}
	}

	out := concourse.OutResponse{
		Version: concourse.Version{
			ProductVersion: release.Version,
		},
		Metadata: []concourse.Metadata{
			{Name: "release_type", Value: release.ReleaseType},
			{Name: "release_date", Value: release.ReleaseDate},
			{Name: "description", Value: release.Description},
			{Name: "eula_slug", Value: release.Eula.Slug},
		},
	}

	l.Debugf("Returning output: %+v\n", out)

	err = json.NewEncoder(os.Stdout).Encode(out)
	if err != nil {
		log.Fatalln(err)
	}
}
Example #5
0
func main() {
	if version == "" {
		version = "dev"
	}

	var input concourse.InRequest
	if len(os.Args) < 2 {
		log.Fatalln(fmt.Sprintf(
			"not enough args - usage: %s <sources directory>", os.Args[0]))
	}

	downloadDir := os.Args[1]

	err := json.NewDecoder(os.Stdin).Decode(&input)
	if err != nil {
		log.Fatalln(err)
	}

	logFile, err := ioutil.TempFile("", "pivnet-resource-in.log")
	if err != nil {
		log.Fatalln(err)
	}
	fmt.Fprintf(logFile, "PivNet Resource version: %s\n", version)

	fmt.Fprintf(os.Stderr, "logging to %s\n", logFile.Name())

	sanitized := concourse.SanitizedSource(input.Source)
	sanitizer := sanitizer.NewSanitizer(sanitized, logFile)

	l := logger.NewLogger(sanitizer)

	token := input.Source.APIToken
	mustBeNonEmpty(token, "api_token")

	l.Debugf("Received input: %+v\n", input)

	clientConfig := pivnet.NewClientConfig{
		URL:       pivnet.URL,
		Token:     input.Source.APIToken,
		UserAgent: fmt.Sprintf("pivnet-resource/%s", version),
	}
	client := pivnet.NewClient(
		clientConfig,
		l,
	)

	productVersion := input.Version.ProductVersion
	productSlug := input.Source.ProductSlug

	l.Debugf(
		"Getting release: {product_slug: %s, product_version: %s}\n",
		productSlug,
		productVersion,
	)

	release, err := client.GetRelease(productSlug, productVersion)
	if err != nil {
		log.Fatalf("Failed to get Release: %s\n", err.Error())
	}

	l.Debugf(
		"Accepting EULA: {product_slug: %s, release_id: %d}\n",
		productSlug,
		release.ID,
	)

	err = client.AcceptEULA(productSlug, release.ID)
	if err != nil {
		log.Fatalf("EULA acceptance failed for the release: %s\n", err.Error())
	}

	l.Debugf(
		"Getting product files: {release_id: %d}\n",
		release.ID,
	)

	productFiles, err := client.GetProductFiles(release)
	if err != nil {
		log.Fatalf("Failed to get Product Files: %s\n", err.Error())
	}

	l.Debugf(
		"Getting download links: {product_files: %+v}\n",
		productFiles,
	)

	downloadLinks := filter.DownloadLinks(productFiles)

	if len(input.Params.Globs) > 0 {
		l.Debugf(
			"Filtering download links with globs: {globs: %+v}\n",
			input.Params.Globs,
		)

		var err error
		downloadLinks, err = filter.DownloadLinksByGlob(downloadLinks, input.Params.Globs)
		if err != nil {
			log.Fatalf("Failed to filter Product Files: %s\n", err.Error())
		}

		l.Debugf(
			"Downloading files: {download_links: %+v, download_dir: %s}\n",
			downloadLinks,
			downloadDir,
		)

		err = downloader.Download(downloadDir, downloadLinks, token)
		if err != nil {
			log.Fatalf("Failed to Download Files: %s\n", err.Error())
		}
	}

	versionFilepath := filepath.Join(downloadDir, "version")

	l.Debugf(
		"Writing version to file: {version: %s, version_filepath: %s}\n",
		version,
		versionFilepath,
	)

	err = ioutil.WriteFile(versionFilepath, []byte(productVersion), os.ModePerm)
	if err != nil {
		log.Fatalln(err)
	}

	out := concourse.InResponse{
		Version: concourse.Version{
			ProductVersion: productVersion,
		},
		Metadata: []concourse.Metadata{
			{Name: "release_type", Value: release.ReleaseType},
			{Name: "release_date", Value: release.ReleaseDate},
			{Name: "description", Value: release.Description},
			{Name: "eula_slug", Value: release.Eula.Slug},
		},
	}

	l.Debugf("Returning output: %+v\n", out)

	err = json.NewEncoder(os.Stdout).Encode(out)
	if err != nil {
		log.Fatalln(err)
	}
}