├── .gitignore ├── CONTRIBUTING.adoc ├── LICENSE ├── NOTICE ├── PULL_REQUEST_TEMPLATE.md ├── README.md ├── auth ├── auth.go ├── auth_test.go ├── authfakes │ └── fake_auth_client.go └── init_test.go ├── bin └── test ├── commands ├── access_tokens_service.go ├── access_tokens_service_test.go ├── artifact_reference.go ├── artifact_reference_test.go ├── artifactreference │ ├── artifact_reference_client.go │ ├── artifact_reference_client_test.go │ ├── artifactreferencefakes │ │ └── fake_pivnet_client.go │ └── init_test.go ├── commandsfakes │ ├── fake_artifact_reference_client.go │ ├── fake_authenticator.go │ ├── fake_curl_client.go │ ├── fake_dependency_specifier_client.go │ ├── fake_eulaclient.go │ ├── fake_file_group_client.go │ ├── fake_login_client.go │ ├── fake_logout_client.go │ ├── fake_pivnet_versions_client.go │ ├── fake_product_client.go │ ├── fake_product_file_client.go │ ├── fake_rchandler.go │ ├── fake_release_client.go │ ├── fake_release_dependency_client.go │ ├── fake_release_type_client.go │ ├── fake_release_upgrade_path_client.go │ ├── fake_subscription_group_client.go │ └── fake_user_group_client.go ├── curl.go ├── curl │ ├── curl_client.go │ ├── curl_client_test.go │ ├── curlfakes │ │ └── fake_pivnet_client.go │ └── init_test.go ├── curl_test.go ├── dependency_specifiers.go ├── dependency_specifiers_test.go ├── dependencyspecifier │ ├── dependency_specifier_client.go │ ├── dependency_specifier_client_test.go │ ├── dependencyspecifierfakes │ │ └── fake_pivnet_client.go │ └── init_test.go ├── eula.go ├── eula │ ├── eula_client.go │ ├── eula_client_test.go │ ├── eulafakes │ │ └── fake_pivnet_client.go │ └── init_test.go ├── eula_test.go ├── file_group.go ├── file_group_test.go ├── filegroup │ ├── file_group_client.go │ ├── file_group_client_test.go │ ├── filegroupfakes │ │ └── fake_pivnet_client.go │ └── init_test.go ├── help.go ├── init_test.go ├── login.go ├── login │ ├── init_test.go │ ├── login_client.go │ ├── login_client_test.go │ └── loginfakes │ │ ├── fake_pivnet_client.go │ │ └── fake_rchandler.go ├── login_test.go ├── logout.go ├── logout │ ├── init_test.go │ ├── logout_client.go │ ├── logout_client_test.go │ └── logoutfakes │ │ └── fake_rchandler.go ├── logout_test.go ├── pivnet.go ├── pivnet_test.go ├── pivnet_versions.go ├── pivnet_versions_test.go ├── pivnetversions │ ├── init_test.go │ ├── pivnet_versions_client.go │ ├── pivnet_versions_client_test.go │ └── pivnetversionsfakes │ │ └── fake_pivnet_client.go ├── product.go ├── product │ ├── init_test.go │ ├── product_client.go │ ├── product_client_test.go │ └── productfakes │ │ └── fake_pivnet_client.go ├── product_file.go ├── product_file_test.go ├── product_test.go ├── productfile │ ├── init_test.go │ ├── product_file_client.go │ ├── product_file_client_test.go │ └── productfilefakes │ │ ├── fake_file_summer.go │ │ ├── fake_filter.go │ │ └── fake_pivnet_client.go ├── release.go ├── release │ ├── init_test.go │ ├── release_client.go │ ├── release_client_test.go │ └── releasefakes │ │ └── fake_pivnet_client.go ├── release_dependency.go ├── release_dependency_test.go ├── release_test.go ├── release_type.go ├── release_type_test.go ├── release_upgrade_path.go ├── release_upgrade_path_test.go ├── releasedependency │ ├── init_test.go │ ├── release_dependency_client.go │ ├── release_dependency_client_test.go │ └── releasedependencyfakes │ │ └── fake_pivnet_client.go ├── releasetype │ ├── init_test.go │ ├── release_type_client.go │ ├── release_type_client_test.go │ └── releasetypefakes │ │ └── fake_pivnet_client.go ├── releaseupgradepath │ ├── init_test.go │ ├── release_upgrade_path_client.go │ ├── release_upgrade_path_client_test.go │ └── releaseupgradepathfakes │ │ ├── fake_filter.go │ │ └── fake_pivnet_client.go ├── subscription_group.go ├── subscription_group_test.go ├── subscriptiongroup │ ├── init_test.go │ ├── subscription_group_client.go │ ├── subscription_group_client_test.go │ └── subscriptiongroupfakes │ │ └── fake_pivnet_client.go ├── user_group.go ├── user_group_test.go ├── usergroup │ ├── init_test.go │ ├── user_group_client.go │ ├── user_group_client_test.go │ └── usergroupfakes │ │ └── fake_pivnet_client.go └── version.go ├── docs ├── content │ ├── about │ │ ├── license.md │ │ └── project-management.md │ ├── development │ │ ├── contributing.md │ │ ├── dependencies.md │ │ ├── prerequisites.md │ │ └── testing.md │ ├── examples │ │ └── usage.md │ ├── index.md │ ├── installation │ │ └── installing-the-cli.md │ └── reference │ │ ├── accept-eula.md │ │ ├── add-file-group.md │ │ ├── add-product-file.md │ │ ├── add-release-dependency.md │ │ ├── add-release-upgrade-path.md │ │ ├── add-user-group-member.md │ │ ├── add-user-group.md │ │ ├── create-dependency-specifier.md │ │ ├── create-file-group.md │ │ ├── create-product-file.md │ │ ├── create-release.md │ │ ├── create-user-group.md │ │ ├── curl.md │ │ ├── delete-dependency-specifier.md │ │ ├── delete-file-group.md │ │ ├── delete-product-file.md │ │ ├── delete-release.md │ │ ├── delete-user-group.md │ │ ├── dependency-specifier.md │ │ ├── dependency-specifiers.md │ │ ├── download-product-files.md │ │ ├── eula.md │ │ ├── eulas.md │ │ ├── file-group.md │ │ ├── file-groups.md │ │ ├── help.md │ │ ├── login.md │ │ ├── logout.md │ │ ├── product-file.md │ │ ├── product-files.md │ │ ├── product.md │ │ ├── products.md │ │ ├── release-dependencies.md │ │ ├── release-types.md │ │ ├── release-upgrade-paths.md │ │ ├── release.md │ │ ├── releases.md │ │ ├── remove-file-group.md │ │ ├── remove-product-file.md │ │ ├── remove-release-dependency.md │ │ ├── remove-release-upgrade-path.md │ │ ├── remove-user-group-member.md │ │ ├── remove-user-group.md │ │ ├── update-file-group.md │ │ ├── update-product-file.md │ │ ├── update-release.md │ │ ├── update-user-group.md │ │ ├── user-group.md │ │ ├── user-groups.md │ │ └── version.md ├── mkdocs.yml ├── readme.md └── theme │ └── material │ ├── 404.html │ ├── __init__.py │ ├── assets │ ├── images │ │ ├── favicon.png │ │ └── icons │ │ │ ├── bitbucket.4ebea66e.svg │ │ │ ├── github.a4034fb1.svg │ │ │ └── gitlab.348cdb3a.svg │ ├── javascripts │ │ ├── application.0cf9b500.js │ │ ├── lunr │ │ │ ├── lunr.da.js │ │ │ ├── lunr.de.js │ │ │ ├── lunr.du.js │ │ │ ├── lunr.es.js │ │ │ ├── lunr.fi.js │ │ │ ├── lunr.fr.js │ │ │ ├── lunr.hu.js │ │ │ ├── lunr.it.js │ │ │ ├── lunr.jp.js │ │ │ ├── lunr.multi.js │ │ │ ├── lunr.no.js │ │ │ ├── lunr.pt.js │ │ │ ├── lunr.ro.js │ │ │ ├── lunr.ru.js │ │ │ ├── lunr.stemmer.support.js │ │ │ ├── lunr.sv.js │ │ │ ├── lunr.tr.js │ │ │ └── tinyseg.js │ │ └── modernizr.1aa3b519.js │ └── stylesheets │ │ ├── application-palette.6079476c.css │ │ └── application.8d40d89b.css │ ├── base.html │ ├── main.html │ ├── mkdocs_theme.yml │ └── partials │ ├── footer.html │ ├── header.html │ ├── hero.html │ ├── integrations │ ├── analytics.html │ └── disqus.html │ ├── language.html │ ├── language │ ├── ar.html │ ├── ca.html │ ├── da.html │ ├── de.html │ ├── en.html │ ├── es.html │ ├── fa.html │ ├── fi.html │ ├── fr.html │ ├── gl.html │ ├── he.html │ ├── hu.html │ ├── it.html │ ├── ja.html │ ├── kr.html │ ├── nl.html │ ├── no.html │ ├── pl.html │ ├── pt.html │ ├── ru.html │ ├── sv.html │ ├── tr.html │ ├── uk.html │ ├── vi.html │ ├── zh-Hant.html │ └── zh.html │ ├── nav-item.html │ ├── nav.html │ ├── search.html │ ├── social.html │ ├── source.html │ ├── tabs-item.html │ ├── tabs.html │ ├── toc-item.html │ └── toc.html ├── errorhandler ├── error_handler.go ├── error_handler_test.go ├── errorhandlerfakes │ └── fake_error_handler.go └── init_test.go ├── filter ├── filter.go ├── filter_suite_test.go └── filter_test.go ├── go.mod ├── go.sum ├── gp ├── gp.go ├── gp_test.go ├── gpfakes │ └── fake_access_token_service.go └── init_test.go ├── hostwarning ├── host_warning.go ├── host_warning_suit_test.go └── host_warning_test.go ├── init_test.go ├── main.go ├── main_test.go ├── open_source_licenses.txt ├── printer ├── init_test.go ├── printer.go ├── printer_test.go └── printerfakes │ └── fake_printer.go ├── rc ├── filesystem │ ├── filesystem.go │ ├── filesystem_test.go │ ├── filesystem_unix_test.go │ └── init_test.go ├── init_test.go ├── profile.go ├── profile_test.go ├── rc.go ├── rc_test.go └── rcfakes │ └── fake_pivnet_rcread_writer.go ├── semver ├── init_test.go ├── semver.go └── semver_test.go ├── ui └── color.go └── version └── version.go /.gitignore: -------------------------------------------------------------------------------- 1 | pivnet-cli 2 | docs/site/ 3 | vendor 4 | .idea 5 | .gobincache 6 | 7 | -------------------------------------------------------------------------------- /CONTRIBUTING.adoc: -------------------------------------------------------------------------------- 1 | If you have not previously done so, please fill out and 2 | submit the https://cla.pivotal.io/sign/pivotal[Contributor License Agreement]. 3 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Pivotal Network CLI 2 | 3 | Copyright (c) 2015-2016 Pivotal, Inc. All Rights Reserved. 4 | 5 | This product is licensed to you under the Apache License, Version 2.0 (the "License"). 6 | You may not use this product except in compliance with the License. 7 | 8 | This product may include a number of subcomponents with separate copyright notices 9 | and license terms. Your use of these subcomponents is subject to the terms and 10 | conditions of the subcomponent's license, as noted in the LICENSE file. 11 | -------------------------------------------------------------------------------- /PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Thank you for contributing to the Pivnet CLI! 2 | 3 | - Have you made this pull request to the `master` branch? 4 | - Have you [run the tests locally](https://github.com/pivotal-cf/pivnet-cli#running-the-tests)? 5 | -------------------------------------------------------------------------------- /auth/auth.go: -------------------------------------------------------------------------------- 1 | package auth 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/pivotal-cf/pivnet-cli/v3/errorhandler" 7 | ) 8 | 9 | //go:generate counterfeiter . AuthClient 10 | type AuthClient interface { 11 | Auth() (bool, error) 12 | } 13 | 14 | type Authenticator struct { 15 | eh errorhandler.ErrorHandler 16 | } 17 | 18 | func NewAuthenticator(eh errorhandler.ErrorHandler) *Authenticator { 19 | return &Authenticator{ 20 | eh: eh, 21 | } 22 | } 23 | 24 | func (a *Authenticator) AuthenticateClient(client AuthClient) error { 25 | ok, err := client.Auth() 26 | if err != nil { 27 | return a.eh.HandleError(err) 28 | } 29 | 30 | if !ok { 31 | err = fmt.Errorf("Credentials rejected - please login again") 32 | return a.eh.HandleError(err) 33 | } 34 | 35 | return nil 36 | } 37 | -------------------------------------------------------------------------------- /auth/auth_test.go: -------------------------------------------------------------------------------- 1 | package auth_test 2 | 3 | import ( 4 | "fmt" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | "github.com/pivotal-cf/pivnet-cli/v3/auth" 9 | "github.com/pivotal-cf/pivnet-cli/v3/auth/authfakes" 10 | "github.com/pivotal-cf/pivnet-cli/v3/errorhandler/errorhandlerfakes" 11 | ) 12 | 13 | var _ = Describe("Authenticator", func() { 14 | var ( 15 | fakeErrorHandler *errorhandlerfakes.FakeErrorHandler 16 | 17 | authenticator *auth.Authenticator 18 | ) 19 | 20 | BeforeEach(func() { 21 | fakeErrorHandler = &errorhandlerfakes.FakeErrorHandler{} 22 | authenticator = auth.NewAuthenticator(fakeErrorHandler) 23 | }) 24 | 25 | Describe("AuthenticateClient", func() { 26 | var ( 27 | fakeAuthClient *authfakes.FakeAuthClient 28 | 29 | authOk bool 30 | authError error 31 | ) 32 | 33 | BeforeEach(func() { 34 | fakeAuthClient = &authfakes.FakeAuthClient{} 35 | 36 | authOk = true 37 | authError = nil 38 | }) 39 | 40 | JustBeforeEach(func() { 41 | fakeAuthClient.AuthReturns(authOk, authError) 42 | }) 43 | 44 | It("invokes the provided client", func() { 45 | err := authenticator.AuthenticateClient(fakeAuthClient) 46 | Expect(err).NotTo(HaveOccurred()) 47 | 48 | Expect(fakeAuthClient.AuthCallCount()).To(Equal(1)) 49 | }) 50 | 51 | Context("when client auth returns an error", func() { 52 | BeforeEach(func() { 53 | authError = fmt.Errorf("auth error") 54 | }) 55 | 56 | It("handles the error", func() { 57 | err := authenticator.AuthenticateClient(fakeAuthClient) 58 | Expect(err).NotTo(HaveOccurred()) 59 | 60 | Expect(fakeErrorHandler.HandleErrorCallCount()).To(Equal(1)) 61 | Expect(fakeErrorHandler.HandleErrorArgsForCall(0)).To(Equal(authError)) 62 | }) 63 | }) 64 | 65 | Context("when client auth returns not ok", func() { 66 | BeforeEach(func() { 67 | authOk = false 68 | }) 69 | 70 | It("handles an error", func() { 71 | err := authenticator.AuthenticateClient(fakeAuthClient) 72 | Expect(err).NotTo(HaveOccurred()) 73 | 74 | Expect(fakeErrorHandler.HandleErrorCallCount()).To(Equal(1)) 75 | Expect(fakeErrorHandler.HandleErrorArgsForCall(0).Error()).To(ContainSubstring("login again")) 76 | }) 77 | }) 78 | }) 79 | }) 80 | -------------------------------------------------------------------------------- /auth/authfakes/fake_auth_client.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package authfakes 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/pivotal-cf/pivnet-cli/v3/auth" 8 | ) 9 | 10 | type FakeAuthClient struct { 11 | AuthStub func() (bool, error) 12 | authMutex sync.RWMutex 13 | authArgsForCall []struct { 14 | } 15 | authReturns struct { 16 | result1 bool 17 | result2 error 18 | } 19 | authReturnsOnCall map[int]struct { 20 | result1 bool 21 | result2 error 22 | } 23 | invocations map[string][][]interface{} 24 | invocationsMutex sync.RWMutex 25 | } 26 | 27 | func (fake *FakeAuthClient) Auth() (bool, error) { 28 | fake.authMutex.Lock() 29 | ret, specificReturn := fake.authReturnsOnCall[len(fake.authArgsForCall)] 30 | fake.authArgsForCall = append(fake.authArgsForCall, struct { 31 | }{}) 32 | fake.recordInvocation("Auth", []interface{}{}) 33 | fake.authMutex.Unlock() 34 | if fake.AuthStub != nil { 35 | return fake.AuthStub() 36 | } 37 | if specificReturn { 38 | return ret.result1, ret.result2 39 | } 40 | fakeReturns := fake.authReturns 41 | return fakeReturns.result1, fakeReturns.result2 42 | } 43 | 44 | func (fake *FakeAuthClient) AuthCallCount() int { 45 | fake.authMutex.RLock() 46 | defer fake.authMutex.RUnlock() 47 | return len(fake.authArgsForCall) 48 | } 49 | 50 | func (fake *FakeAuthClient) AuthCalls(stub func() (bool, error)) { 51 | fake.authMutex.Lock() 52 | defer fake.authMutex.Unlock() 53 | fake.AuthStub = stub 54 | } 55 | 56 | func (fake *FakeAuthClient) AuthReturns(result1 bool, result2 error) { 57 | fake.authMutex.Lock() 58 | defer fake.authMutex.Unlock() 59 | fake.AuthStub = nil 60 | fake.authReturns = struct { 61 | result1 bool 62 | result2 error 63 | }{result1, result2} 64 | } 65 | 66 | func (fake *FakeAuthClient) AuthReturnsOnCall(i int, result1 bool, result2 error) { 67 | fake.authMutex.Lock() 68 | defer fake.authMutex.Unlock() 69 | fake.AuthStub = nil 70 | if fake.authReturnsOnCall == nil { 71 | fake.authReturnsOnCall = make(map[int]struct { 72 | result1 bool 73 | result2 error 74 | }) 75 | } 76 | fake.authReturnsOnCall[i] = struct { 77 | result1 bool 78 | result2 error 79 | }{result1, result2} 80 | } 81 | 82 | func (fake *FakeAuthClient) Invocations() map[string][][]interface{} { 83 | fake.invocationsMutex.RLock() 84 | defer fake.invocationsMutex.RUnlock() 85 | fake.authMutex.RLock() 86 | defer fake.authMutex.RUnlock() 87 | copiedInvocations := map[string][][]interface{}{} 88 | for key, value := range fake.invocations { 89 | copiedInvocations[key] = value 90 | } 91 | return copiedInvocations 92 | } 93 | 94 | func (fake *FakeAuthClient) recordInvocation(key string, args []interface{}) { 95 | fake.invocationsMutex.Lock() 96 | defer fake.invocationsMutex.Unlock() 97 | if fake.invocations == nil { 98 | fake.invocations = map[string][][]interface{}{} 99 | } 100 | if fake.invocations[key] == nil { 101 | fake.invocations[key] = [][]interface{}{} 102 | } 103 | fake.invocations[key] = append(fake.invocations[key], args) 104 | } 105 | 106 | var _ auth.AuthClient = new(FakeAuthClient) 107 | -------------------------------------------------------------------------------- /auth/init_test.go: -------------------------------------------------------------------------------- 1 | package auth_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestAuth(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Auth Suite") 13 | } 14 | -------------------------------------------------------------------------------- /bin/test: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eu 4 | 5 | # In seconds 6 | SLOW_SPEC_THRESHOLD="${SLOW_SPEC_THRESHOLD:-60}" 7 | 8 | my_dir="$( cd "$( dirname "${0}" )" && pwd )" 9 | base_dir="$( cd "${my_dir}/.." && pwd )" 10 | 11 | pushd "${base_dir}" > /dev/null 12 | CGO_ENABLED=1 ginkgo \ 13 | -r \ 14 | -race \ 15 | -p \ 16 | -randomizeAllSpecs \ 17 | -randomizeSuites \ 18 | -keepGoing \ 19 | -slowSpecThreshold="${SLOW_SPEC_THRESHOLD}" \ 20 | "$@" 21 | popd > /dev/null 22 | 23 | -------------------------------------------------------------------------------- /commands/access_tokens_service.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "fmt" 5 | "github.com/pivotal-cf/go-pivnet/v7" 6 | "github.com/pivotal-cf/pivnet-cli/v3/gp" 7 | "github.com/pivotal-cf/pivnet-cli/v3/rc" 8 | "time" 9 | ) 10 | 11 | var CreateAccessTokenService = func( 12 | rc RCHandler, 13 | profileName string, 14 | refreshToken string, 15 | host string, 16 | skipSSLValidation bool, 17 | ) gp.AccessTokenService { 18 | tokenService := pivnet.NewAccessTokenOrLegacyToken(refreshToken, host, skipSSLValidation, "Pivnet CLI") 19 | serviceThatSavesRc := CreateSaveTokenDecorator(rc, tokenService, profileName, refreshToken, host) 20 | return serviceThatSavesRc 21 | } 22 | 23 | type SaveTokenDecorator struct { 24 | WrappedService gp.AccessTokenService 25 | ProfileName string 26 | RefreshToken string 27 | Host string 28 | Rc RCHandler 29 | } 30 | 31 | func (o SaveTokenDecorator) AccessToken() (string, error) { 32 | pivnetProfile, err := o.Rc.ProfileForName(o.ProfileName) 33 | 34 | if err == nil && pivnetProfile != nil && validAccessToken(pivnetProfile) && o.notDuringLogin(pivnetProfile) { 35 | return pivnetProfile.AccessToken, nil 36 | } 37 | 38 | accessToken, err := o.WrappedService.AccessToken() 39 | if err != nil { 40 | return "", fmt.Errorf("could not get access token %s", err) 41 | } 42 | 43 | err = o.Rc.SaveProfile(o.ProfileName, o.RefreshToken, o.Host, accessToken, o.accessTokenExpiry()) 44 | if err != nil { 45 | return "", fmt.Errorf("failed to save profile %s", err) 46 | } 47 | 48 | return accessToken, nil 49 | } 50 | 51 | func (o SaveTokenDecorator) accessTokenExpiry() int64 { 52 | return time.Now().Add(time.Hour).Unix() 53 | } 54 | 55 | func (o SaveTokenDecorator) notDuringLogin(pivnetProfile *rc.PivnetProfile) bool { 56 | return pivnetProfile.Host == o.Host && pivnetProfile.APIToken == o.RefreshToken 57 | } 58 | 59 | func CreateSaveTokenDecorator(rc RCHandler, accessTokenService gp.AccessTokenService, profileName string, refreshToken string, host string) gp.AccessTokenService { 60 | return SaveTokenDecorator { 61 | WrappedService: accessTokenService, 62 | ProfileName: profileName, 63 | RefreshToken: refreshToken, 64 | Host: host, 65 | Rc: rc, 66 | } 67 | } 68 | 69 | func validAccessToken(pivnetProfile *rc.PivnetProfile) bool { 70 | return pivnetProfile.AccessToken != "" && pivnetProfile.AccessTokenExpiry > time.Now().Unix() 71 | } 72 | -------------------------------------------------------------------------------- /commands/artifactreference/init_test.go: -------------------------------------------------------------------------------- 1 | package artifactreference_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestCommands(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "ArtifactReference suite") 13 | } 14 | -------------------------------------------------------------------------------- /commands/commandsfakes/fake_logout_client.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package commandsfakes 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/pivotal-cf/pivnet-cli/v3/commands" 8 | ) 9 | 10 | type FakeLogoutClient struct { 11 | LogoutStub func(string) error 12 | logoutMutex sync.RWMutex 13 | logoutArgsForCall []struct { 14 | arg1 string 15 | } 16 | logoutReturns struct { 17 | result1 error 18 | } 19 | logoutReturnsOnCall map[int]struct { 20 | result1 error 21 | } 22 | invocations map[string][][]interface{} 23 | invocationsMutex sync.RWMutex 24 | } 25 | 26 | func (fake *FakeLogoutClient) Logout(arg1 string) error { 27 | fake.logoutMutex.Lock() 28 | ret, specificReturn := fake.logoutReturnsOnCall[len(fake.logoutArgsForCall)] 29 | fake.logoutArgsForCall = append(fake.logoutArgsForCall, struct { 30 | arg1 string 31 | }{arg1}) 32 | fake.recordInvocation("Logout", []interface{}{arg1}) 33 | fake.logoutMutex.Unlock() 34 | if fake.LogoutStub != nil { 35 | return fake.LogoutStub(arg1) 36 | } 37 | if specificReturn { 38 | return ret.result1 39 | } 40 | fakeReturns := fake.logoutReturns 41 | return fakeReturns.result1 42 | } 43 | 44 | func (fake *FakeLogoutClient) LogoutCallCount() int { 45 | fake.logoutMutex.RLock() 46 | defer fake.logoutMutex.RUnlock() 47 | return len(fake.logoutArgsForCall) 48 | } 49 | 50 | func (fake *FakeLogoutClient) LogoutCalls(stub func(string) error) { 51 | fake.logoutMutex.Lock() 52 | defer fake.logoutMutex.Unlock() 53 | fake.LogoutStub = stub 54 | } 55 | 56 | func (fake *FakeLogoutClient) LogoutArgsForCall(i int) string { 57 | fake.logoutMutex.RLock() 58 | defer fake.logoutMutex.RUnlock() 59 | argsForCall := fake.logoutArgsForCall[i] 60 | return argsForCall.arg1 61 | } 62 | 63 | func (fake *FakeLogoutClient) LogoutReturns(result1 error) { 64 | fake.logoutMutex.Lock() 65 | defer fake.logoutMutex.Unlock() 66 | fake.LogoutStub = nil 67 | fake.logoutReturns = struct { 68 | result1 error 69 | }{result1} 70 | } 71 | 72 | func (fake *FakeLogoutClient) LogoutReturnsOnCall(i int, result1 error) { 73 | fake.logoutMutex.Lock() 74 | defer fake.logoutMutex.Unlock() 75 | fake.LogoutStub = nil 76 | if fake.logoutReturnsOnCall == nil { 77 | fake.logoutReturnsOnCall = make(map[int]struct { 78 | result1 error 79 | }) 80 | } 81 | fake.logoutReturnsOnCall[i] = struct { 82 | result1 error 83 | }{result1} 84 | } 85 | 86 | func (fake *FakeLogoutClient) Invocations() map[string][][]interface{} { 87 | fake.invocationsMutex.RLock() 88 | defer fake.invocationsMutex.RUnlock() 89 | fake.logoutMutex.RLock() 90 | defer fake.logoutMutex.RUnlock() 91 | copiedInvocations := map[string][][]interface{}{} 92 | for key, value := range fake.invocations { 93 | copiedInvocations[key] = value 94 | } 95 | return copiedInvocations 96 | } 97 | 98 | func (fake *FakeLogoutClient) recordInvocation(key string, args []interface{}) { 99 | fake.invocationsMutex.Lock() 100 | defer fake.invocationsMutex.Unlock() 101 | if fake.invocations == nil { 102 | fake.invocations = map[string][][]interface{}{} 103 | } 104 | if fake.invocations[key] == nil { 105 | fake.invocations[key] = [][]interface{}{} 106 | } 107 | fake.invocations[key] = append(fake.invocations[key], args) 108 | } 109 | 110 | var _ commands.LogoutClient = new(FakeLogoutClient) 111 | -------------------------------------------------------------------------------- /commands/commandsfakes/fake_release_type_client.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package commandsfakes 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/pivotal-cf/pivnet-cli/v3/commands" 8 | ) 9 | 10 | type FakeReleaseTypeClient struct { 11 | ListStub func() error 12 | listMutex sync.RWMutex 13 | listArgsForCall []struct { 14 | } 15 | listReturns struct { 16 | result1 error 17 | } 18 | listReturnsOnCall map[int]struct { 19 | result1 error 20 | } 21 | invocations map[string][][]interface{} 22 | invocationsMutex sync.RWMutex 23 | } 24 | 25 | func (fake *FakeReleaseTypeClient) List() error { 26 | fake.listMutex.Lock() 27 | ret, specificReturn := fake.listReturnsOnCall[len(fake.listArgsForCall)] 28 | fake.listArgsForCall = append(fake.listArgsForCall, struct { 29 | }{}) 30 | fake.recordInvocation("List", []interface{}{}) 31 | fake.listMutex.Unlock() 32 | if fake.ListStub != nil { 33 | return fake.ListStub() 34 | } 35 | if specificReturn { 36 | return ret.result1 37 | } 38 | fakeReturns := fake.listReturns 39 | return fakeReturns.result1 40 | } 41 | 42 | func (fake *FakeReleaseTypeClient) ListCallCount() int { 43 | fake.listMutex.RLock() 44 | defer fake.listMutex.RUnlock() 45 | return len(fake.listArgsForCall) 46 | } 47 | 48 | func (fake *FakeReleaseTypeClient) ListCalls(stub func() error) { 49 | fake.listMutex.Lock() 50 | defer fake.listMutex.Unlock() 51 | fake.ListStub = stub 52 | } 53 | 54 | func (fake *FakeReleaseTypeClient) ListReturns(result1 error) { 55 | fake.listMutex.Lock() 56 | defer fake.listMutex.Unlock() 57 | fake.ListStub = nil 58 | fake.listReturns = struct { 59 | result1 error 60 | }{result1} 61 | } 62 | 63 | func (fake *FakeReleaseTypeClient) ListReturnsOnCall(i int, result1 error) { 64 | fake.listMutex.Lock() 65 | defer fake.listMutex.Unlock() 66 | fake.ListStub = nil 67 | if fake.listReturnsOnCall == nil { 68 | fake.listReturnsOnCall = make(map[int]struct { 69 | result1 error 70 | }) 71 | } 72 | fake.listReturnsOnCall[i] = struct { 73 | result1 error 74 | }{result1} 75 | } 76 | 77 | func (fake *FakeReleaseTypeClient) Invocations() map[string][][]interface{} { 78 | fake.invocationsMutex.RLock() 79 | defer fake.invocationsMutex.RUnlock() 80 | fake.listMutex.RLock() 81 | defer fake.listMutex.RUnlock() 82 | copiedInvocations := map[string][][]interface{}{} 83 | for key, value := range fake.invocations { 84 | copiedInvocations[key] = value 85 | } 86 | return copiedInvocations 87 | } 88 | 89 | func (fake *FakeReleaseTypeClient) recordInvocation(key string, args []interface{}) { 90 | fake.invocationsMutex.Lock() 91 | defer fake.invocationsMutex.Unlock() 92 | if fake.invocations == nil { 93 | fake.invocations = map[string][][]interface{}{} 94 | } 95 | if fake.invocations[key] == nil { 96 | fake.invocations[key] = [][]interface{}{} 97 | } 98 | fake.invocations[key] = append(fake.invocations[key], args) 99 | } 100 | 101 | var _ commands.ReleaseTypeClient = new(FakeReleaseTypeClient) 102 | -------------------------------------------------------------------------------- /commands/curl.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import "github.com/pivotal-cf/pivnet-cli/v3/commands/curl" 4 | 5 | type Args struct { 6 | URL string `positional-arg-name:"URL" description:"URL without host or API prefix e.g. /products/p-mysql/releases/3451"` 7 | } 8 | 9 | type CurlCommand struct { 10 | Method string `long:"request" short:"X" description:"Custom method e.g. PATCH"` 11 | Data string `long:"data" short:"d" description:"Request data e.g. '{\"foo\":\"bar\"}'"` 12 | Args Args `positional-args:"yes" required:"true"` 13 | } 14 | 15 | //go:generate counterfeiter . CurlClient 16 | type CurlClient interface { 17 | MakeRequest(method string, body string, url string) error 18 | } 19 | 20 | var NewCurlClient = func(client curl.PivnetClient) CurlClient { 21 | return curl.NewCurlClient( 22 | client, 23 | ErrorHandler, 24 | Pivnet.Format, 25 | OutputWriter, 26 | Printer, 27 | ) 28 | } 29 | 30 | func (command *CurlCommand) Execute(args []string) error { 31 | err := Init(true) 32 | if err != nil { 33 | return err 34 | } 35 | 36 | client := NewPivnetClient() 37 | err = Auth.AuthenticateClient(client) 38 | if err != nil { 39 | return err 40 | } 41 | 42 | return NewCurlClient(client).MakeRequest(command.Method, command.Data, command.Args.URL) 43 | } 44 | -------------------------------------------------------------------------------- /commands/curl/curl_client.go: -------------------------------------------------------------------------------- 1 | package curl 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io/ioutil" 7 | 8 | "io" 9 | "net/http" 10 | "strings" 11 | 12 | "github.com/pivotal-cf/pivnet-cli/v3/errorhandler" 13 | "github.com/pivotal-cf/pivnet-cli/v3/printer" 14 | ) 15 | 16 | //go:generate counterfeiter . PivnetClient 17 | type PivnetClient interface { 18 | MakeRequest(method string, url string, expectedResponseCode int, body io.Reader) (*http.Response, error) 19 | } 20 | 21 | type CurlClient struct { 22 | pivnetClient PivnetClient 23 | eh errorhandler.ErrorHandler 24 | format string 25 | outputWriter io.Writer 26 | printer printer.Printer 27 | } 28 | 29 | func NewCurlClient( 30 | pivnetClient PivnetClient, 31 | eh errorhandler.ErrorHandler, 32 | format string, 33 | outputWriter io.Writer, 34 | printer printer.Printer, 35 | ) *CurlClient { 36 | return &CurlClient{ 37 | pivnetClient: pivnetClient, 38 | eh: eh, 39 | format: format, 40 | outputWriter: outputWriter, 41 | printer: printer, 42 | } 43 | } 44 | 45 | func (c *CurlClient) MakeRequest( 46 | method string, 47 | data string, 48 | url string, 49 | ) error { 50 | expectedResponseCode := 0 51 | var body io.Reader 52 | if data != "" { 53 | body = strings.NewReader(data) 54 | } 55 | 56 | var output interface{} 57 | resp, err := c.pivnetClient.MakeRequest( 58 | method, 59 | url, 60 | expectedResponseCode, 61 | body, 62 | ) 63 | if err != nil { 64 | return c.eh.HandleError(err) 65 | } 66 | defer resp.Body.Close() 67 | 68 | contentType := resp.Header.Get("Content-Type") 69 | 70 | if strings.ToLower(contentType) == "text/csv" { 71 | bodyBytes, err := ioutil.ReadAll(resp.Body) 72 | if err != nil { 73 | return c.eh.HandleError(err) 74 | } 75 | 76 | fmt.Println(string(bodyBytes)) 77 | 78 | return nil 79 | } 80 | 81 | err = json.NewDecoder(resp.Body).Decode(&output) 82 | if err != nil { 83 | return c.eh.HandleError(err) 84 | } 85 | 86 | c.printInterface(output) 87 | 88 | return nil 89 | } 90 | 91 | func (c *CurlClient) printInterface(object interface{}) error { 92 | if c.format == printer.PrintAsYAML { 93 | return c.printer.PrintYAML(object) 94 | } 95 | 96 | return c.printer.PrintJSON(object) 97 | } 98 | -------------------------------------------------------------------------------- /commands/curl/init_test.go: -------------------------------------------------------------------------------- 1 | package curl_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestCommands(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Curl commands suite") 13 | } 14 | -------------------------------------------------------------------------------- /commands/curl_test.go: -------------------------------------------------------------------------------- 1 | package commands_test 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "reflect" 7 | 8 | . "github.com/onsi/ginkgo" 9 | . "github.com/onsi/gomega" 10 | "github.com/pivotal-cf/pivnet-cli/v3/commands" 11 | "github.com/pivotal-cf/pivnet-cli/v3/commands/commandsfakes" 12 | "github.com/pivotal-cf/pivnet-cli/v3/commands/curl" 13 | ) 14 | 15 | var _ = Describe("curl commands", func() { 16 | var ( 17 | field reflect.StructField 18 | 19 | fakeCurlClient *commandsfakes.FakeCurlClient 20 | ) 21 | 22 | BeforeEach(func() { 23 | fakeCurlClient = &commandsfakes.FakeCurlClient{} 24 | 25 | commands.NewCurlClient = func(curl.PivnetClient) commands.CurlClient { 26 | return fakeCurlClient 27 | } 28 | }) 29 | 30 | Describe("CurlCommand", func() { 31 | var ( 32 | cmd *commands.CurlCommand 33 | ) 34 | 35 | BeforeEach(func() { 36 | cmd = &commands.CurlCommand{} 37 | }) 38 | 39 | It("invokes the curl client", func() { 40 | err := cmd.Execute(nil) 41 | 42 | Expect(err).NotTo(HaveOccurred()) 43 | 44 | Expect(fakeCurlClient.MakeRequestCallCount()).To(Equal(1)) 45 | }) 46 | 47 | Context("when the curl client returns an error", func() { 48 | var ( 49 | expectedErr error 50 | ) 51 | 52 | BeforeEach(func() { 53 | expectedErr = errors.New("expected error") 54 | fakeCurlClient.MakeRequestReturns(expectedErr) 55 | }) 56 | 57 | It("forwards the error", func() { 58 | err := cmd.Execute(nil) 59 | 60 | Expect(err).To(Equal(expectedErr)) 61 | }) 62 | }) 63 | 64 | Context("when Init returns an error", func() { 65 | BeforeEach(func() { 66 | initErr = fmt.Errorf("init error") 67 | }) 68 | 69 | It("forwards the error", func() { 70 | err := cmd.Execute(nil) 71 | 72 | Expect(err).To(Equal(initErr)) 73 | }) 74 | }) 75 | 76 | Context("when Authentication returns an error", func() { 77 | BeforeEach(func() { 78 | authErr = fmt.Errorf("auth error") 79 | }) 80 | 81 | It("forwards the error", func() { 82 | err := cmd.Execute(nil) 83 | 84 | Expect(err).To(Equal(authErr)) 85 | }) 86 | }) 87 | 88 | Describe("Method flag", func() { 89 | BeforeEach(func() { 90 | field = fieldFor(commands.CurlCommand{}, "Method") 91 | }) 92 | 93 | It("is not required", func() { 94 | Expect(isRequired(field)).To(BeFalse()) 95 | }) 96 | 97 | It("contains long name", func() { 98 | Expect(longTag(field)).To(Equal("request")) 99 | }) 100 | 101 | It("contains short name", func() { 102 | Expect(shortTag(field)).To(Equal("X")) 103 | }) 104 | }) 105 | 106 | Describe("Data flag", func() { 107 | BeforeEach(func() { 108 | field = fieldFor(commands.CurlCommand{}, "Data") 109 | }) 110 | 111 | It("is not required", func() { 112 | Expect(isRequired(field)).To(BeFalse()) 113 | }) 114 | 115 | It("contains long name", func() { 116 | Expect(longTag(field)).To(Equal("data")) 117 | }) 118 | 119 | It("contains short name", func() { 120 | Expect(shortTag(field)).To(Equal("d")) 121 | }) 122 | }) 123 | }) 124 | }) 125 | -------------------------------------------------------------------------------- /commands/dependencyspecifier/init_test.go: -------------------------------------------------------------------------------- 1 | package dependencyspecifier_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestCommands(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "DependencySpecifier commands suite") 13 | } 14 | -------------------------------------------------------------------------------- /commands/eula.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import "github.com/pivotal-cf/pivnet-cli/v3/commands/eula" 4 | 5 | type EULAsCommand struct { 6 | } 7 | 8 | type EULACommand struct { 9 | EULASlug string `long:"eula-slug" description:"EULA slug e.g. pivotal_software_eula" required:"true"` 10 | } 11 | 12 | type AcceptEULACommand struct { 13 | ProductSlug string `long:"product-slug" short:"p" description:"Product slug e.g. p-mysql" required:"true"` 14 | ReleaseVersion string `long:"release-version" short:"r" description:"Release version e.g. 0.1.2-rc1" required:"true"` 15 | } 16 | 17 | //go:generate counterfeiter . EULAClient 18 | type EULAClient interface { 19 | List() error 20 | Get(eulaSlug string) error 21 | AcceptEULA(productSlug string, releaseVersion string) error 22 | } 23 | 24 | var NewEULAClient = func(client eula.PivnetClient) EULAClient { 25 | return eula.NewEULAClient( 26 | client, 27 | ErrorHandler, 28 | Pivnet.Format, 29 | OutputWriter, 30 | Printer, 31 | ) 32 | } 33 | 34 | func (command *EULAsCommand) Execute(args []string) error { 35 | err := Init(true) 36 | if err != nil { 37 | return err 38 | } 39 | 40 | client := NewPivnetClient() 41 | err = Auth.AuthenticateClient(client) 42 | if err != nil { 43 | return err 44 | } 45 | 46 | return NewEULAClient(client).List() 47 | } 48 | 49 | func (command *EULACommand) Execute(args []string) error { 50 | err := Init(true) 51 | if err != nil { 52 | return err 53 | } 54 | 55 | client := NewPivnetClient() 56 | err = Auth.AuthenticateClient(client) 57 | if err != nil { 58 | return err 59 | } 60 | 61 | return NewEULAClient(client).Get(command.EULASlug) 62 | } 63 | 64 | func (command *AcceptEULACommand) Execute(args []string) error { 65 | err := Init(true) 66 | if err != nil { 67 | return err 68 | } 69 | 70 | client := NewPivnetClient() 71 | err = Auth.AuthenticateClient(client) 72 | if err != nil { 73 | return err 74 | } 75 | 76 | return NewEULAClient(client).AcceptEULA(command.ProductSlug, command.ReleaseVersion) 77 | } 78 | -------------------------------------------------------------------------------- /commands/eula/init_test.go: -------------------------------------------------------------------------------- 1 | package eula_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestCommands(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "EULA commands suite") 13 | } 14 | -------------------------------------------------------------------------------- /commands/filegroup/init_test.go: -------------------------------------------------------------------------------- 1 | package filegroup_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestCommands(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "FileGroup commands suite") 13 | } 14 | -------------------------------------------------------------------------------- /commands/help.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import "errors" 4 | 5 | var ErrShowHelpMessage = errors.New("help command invoked") 6 | 7 | type HelpCommand struct{} 8 | 9 | func (command *HelpCommand) Execute(args []string) error { 10 | // Reset flags to avoid overriding defaults 11 | Pivnet.ProfileName = "" 12 | 13 | return ErrShowHelpMessage 14 | } 15 | -------------------------------------------------------------------------------- /commands/init_test.go: -------------------------------------------------------------------------------- 1 | package commands_test 2 | 3 | import ( 4 | "github.com/pivotal-cf/pivnet-cli/v3/gp" 5 | "github.com/pivotal-cf/pivnet-cli/v3/gp/gpfakes" 6 | "reflect" 7 | "testing" 8 | 9 | . "github.com/onsi/ginkgo" 10 | . "github.com/onsi/gomega" 11 | "github.com/pivotal-cf/pivnet-cli/v3/commands" 12 | "github.com/pivotal-cf/pivnet-cli/v3/commands/commandsfakes" 13 | "github.com/pivotal-cf/pivnet-cli/v3/printer" 14 | ) 15 | 16 | const ( 17 | apiPrefix = "/api/v2" 18 | apiToken = "some-api-token" 19 | ) 20 | 21 | func TestCommands(t *testing.T) { 22 | RegisterFailHandler(Fail) 23 | RunSpecs(t, "Commands Suite") 24 | } 25 | 26 | var ( 27 | fakeAuthenticator *commandsfakes.FakeAuthenticator 28 | fakeAccessTokenService *gpfakes.FakeAccessTokenService 29 | authErr error 30 | 31 | initInvocationArg bool 32 | initErr error 33 | 34 | origInitFunc func(bool) error 35 | ) 36 | 37 | var _ = BeforeSuite(func() { 38 | origInitFunc = commands.Init 39 | 40 | commands.Pivnet = commands.PivnetCommand{ 41 | Format: printer.PrintAsJSON, 42 | } 43 | }) 44 | 45 | var _ = BeforeEach(func() { 46 | fakeAuthenticator = &commandsfakes.FakeAuthenticator{} 47 | fakeAccessTokenService = &gpfakes.FakeAccessTokenService{} 48 | commands.Auth = fakeAuthenticator 49 | authErr = nil 50 | 51 | initErr = nil 52 | 53 | commands.CreateAccessTokenService = func(rc commands.RCHandler, 54 | profileName string, 55 | refreshToken string, 56 | host string, 57 | skipSSLValidation bool, 58 | ) gp.AccessTokenService { 59 | return fakeAccessTokenService 60 | } 61 | }) 62 | 63 | var _ = JustBeforeEach(func() { 64 | commands.Init = func(arg bool) error { 65 | initInvocationArg = arg 66 | return initErr 67 | } 68 | 69 | fakeAuthenticator.AuthenticateClientReturns(authErr) 70 | }) 71 | 72 | func fieldFor(command interface{}, name string) reflect.StructField { 73 | field, success := reflect.TypeOf(command).FieldByName(name) 74 | Expect(success).To(BeTrue(), "Expected %s field to exist on command", name) 75 | return field 76 | } 77 | 78 | func longTag(f reflect.StructField) string { 79 | return f.Tag.Get("long") 80 | } 81 | 82 | func shortTag(f reflect.StructField) string { 83 | return f.Tag.Get("short") 84 | } 85 | 86 | var alias = func(f reflect.StructField) string { 87 | return f.Tag.Get("alias") 88 | } 89 | 90 | var command = func(f reflect.StructField) string { 91 | return f.Tag.Get("command") 92 | } 93 | 94 | var isRequired = func(f reflect.StructField) bool { 95 | return f.Tag.Get("required") == "true" 96 | } 97 | 98 | var defaultVal = func(f reflect.StructField) string { 99 | return f.Tag.Get("default") 100 | } 101 | -------------------------------------------------------------------------------- /commands/login.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "github.com/pivotal-cf/pivnet-cli/v3/commands/login" 5 | ) 6 | 7 | type LoginCommand struct { 8 | APIToken string `long:"api-token" description:"Pivnet API Token (Pivnet legacy token or UAA refresh token)" required:"true"` 9 | Host string `long:"host" description:"Pivnet API Host" default:"https://network.tanzu.vmware.com"` 10 | } 11 | 12 | //go:generate counterfeiter . LoginClient 13 | type LoginClient interface { 14 | Login(name string, apiToken string, host string) error 15 | } 16 | 17 | var NewLoginClient = func(client login.PivnetClient) LoginClient { 18 | return login.NewLoginClient( 19 | client, 20 | RC, 21 | ErrorHandler, 22 | Pivnet.Format, 23 | OutputWriter, 24 | Printer, 25 | ) 26 | } 27 | 28 | func (command *LoginCommand) Execute([]string) error { 29 | err := Init(false) 30 | if err != nil { 31 | return err 32 | } 33 | 34 | sanitizeWriters(command.APIToken) 35 | 36 | accessTokenService := CreateAccessTokenService(RC, Pivnet.ProfileName, command.APIToken, command.Host, Pivnet.SkipSSLValidation) 37 | 38 | client := NewPivnetClientWithToken(accessTokenService, command.Host) 39 | 40 | return NewLoginClient(client).Login( 41 | Pivnet.ProfileName, 42 | command.APIToken, 43 | command.Host, 44 | ) 45 | } 46 | -------------------------------------------------------------------------------- /commands/login/init_test.go: -------------------------------------------------------------------------------- 1 | package login_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestCommands(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Login commands suite") 13 | } 14 | -------------------------------------------------------------------------------- /commands/login/login_client.go: -------------------------------------------------------------------------------- 1 | package login 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | 7 | "github.com/pivotal-cf/pivnet-cli/v3/errorhandler" 8 | "github.com/pivotal-cf/pivnet-cli/v3/printer" 9 | "github.com/pivotal-cf/pivnet-cli/v3/ui" 10 | ) 11 | 12 | //go:generate counterfeiter . PivnetClient 13 | type PivnetClient interface { 14 | Auth() (bool, error) 15 | } 16 | 17 | //go:generate counterfeiter . RCHandler 18 | type RCHandler interface { 19 | SaveProfile(profileName string, apiToken string, host string, accessToken string, accessTokenExpiry int64) error 20 | } 21 | 22 | type LoginClient struct { 23 | pivnetClient PivnetClient 24 | rcHandler RCHandler 25 | eh errorhandler.ErrorHandler 26 | format string 27 | outputWriter io.Writer 28 | printer printer.Printer 29 | } 30 | 31 | func NewLoginClient( 32 | pivnetClient PivnetClient, 33 | rcHandler RCHandler, 34 | eh errorhandler.ErrorHandler, 35 | format string, 36 | outputWriter io.Writer, 37 | printer printer.Printer, 38 | ) *LoginClient { 39 | return &LoginClient{ 40 | pivnetClient: pivnetClient, 41 | rcHandler: rcHandler, 42 | eh: eh, 43 | format: format, 44 | outputWriter: outputWriter, 45 | printer: printer, 46 | } 47 | } 48 | 49 | func (c *LoginClient) Login( 50 | profileName string, 51 | apiToken string, 52 | host string, 53 | ) error { 54 | const legacyAPITokenLength = 20 55 | if len(apiToken) <= legacyAPITokenLength { 56 | message := "Warning: The use of static Pivnet API tokens is deprecated and will be removed. Please see https://network.tanzu.vmware.com/docs/api#how-to-authenticate for details on the new UAA API Token mechanism." 57 | coloredMessage := ui.ErrorColor.SprintFunc()(message) 58 | fmt.Fprintln(c.outputWriter, coloredMessage) 59 | } 60 | 61 | ok, err := c.pivnetClient.Auth() 62 | if err != nil { 63 | return c.eh.HandleError(err) 64 | } 65 | 66 | if !ok { 67 | err := fmt.Errorf("Failed to login") 68 | return c.eh.HandleError(err) 69 | } 70 | 71 | return c.printLogin() 72 | } 73 | 74 | func (c *LoginClient) printLogin() error { 75 | switch c.format { 76 | 77 | case printer.PrintAsTable: 78 | message := "Logged-in successfully" 79 | coloredMessage := ui.SuccessColor.SprintFunc()(message) 80 | 81 | _, err := fmt.Fprintln(c.outputWriter, coloredMessage) 82 | 83 | return err 84 | } 85 | 86 | return nil 87 | } 88 | -------------------------------------------------------------------------------- /commands/login/login_client_test.go: -------------------------------------------------------------------------------- 1 | package login_test 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | "github.com/pivotal-cf/pivnet-cli/v3/commands/login" 9 | "github.com/pivotal-cf/pivnet-cli/v3/commands/login/loginfakes" 10 | "github.com/pivotal-cf/pivnet-cli/v3/errorhandler/errorhandlerfakes" 11 | "github.com/pivotal-cf/pivnet-cli/v3/printer" 12 | ) 13 | 14 | var _ = Describe("login commands", func() { 15 | var ( 16 | fakePivnetClient *loginfakes.FakePivnetClient 17 | fakeRCHandler *loginfakes.FakeRCHandler 18 | fakeErrorHandler *errorhandlerfakes.FakeErrorHandler 19 | 20 | outBuffer bytes.Buffer 21 | 22 | client *login.LoginClient 23 | ) 24 | 25 | BeforeEach(func() { 26 | fakePivnetClient = &loginfakes.FakePivnetClient{} 27 | fakeRCHandler = &loginfakes.FakeRCHandler{} 28 | 29 | outBuffer = bytes.Buffer{} 30 | 31 | fakeErrorHandler = &errorhandlerfakes.FakeErrorHandler{} 32 | 33 | client = login.NewLoginClient( 34 | fakePivnetClient, 35 | fakeRCHandler, 36 | fakeErrorHandler, 37 | printer.PrintAsJSON, 38 | &outBuffer, 39 | printer.NewPrinter(&outBuffer), 40 | ) 41 | }) 42 | 43 | Describe("Login", func() { 44 | var ( 45 | profileName string 46 | apiToken string 47 | host string 48 | 49 | authResult bool 50 | authErr error 51 | 52 | saveProfileErr error 53 | ) 54 | 55 | BeforeEach(func() { 56 | profileName = "some-login-slug" 57 | apiToken = "some-api-token" 58 | host = "some-host" 59 | 60 | authResult = true 61 | authErr = nil 62 | 63 | saveProfileErr = nil 64 | }) 65 | 66 | JustBeforeEach(func() { 67 | fakePivnetClient.AuthReturns(authResult, authErr) 68 | fakeRCHandler.SaveProfileReturns(saveProfileErr) 69 | }) 70 | 71 | It("authenticates", func() { 72 | err := client.Login( 73 | profileName, 74 | apiToken, 75 | host, 76 | ) 77 | Expect(err).NotTo(HaveOccurred()) 78 | 79 | Expect(fakePivnetClient.AuthCallCount()).To(Equal(1)) 80 | }) 81 | 82 | Context("when there is an error authenticating", func() { 83 | BeforeEach(func() { 84 | authErr = fmt.Errorf("auth error") 85 | }) 86 | 87 | It("invokes the error handler", func() { 88 | err := client.Login( 89 | profileName, 90 | apiToken, 91 | host, 92 | ) 93 | Expect(err).NotTo(HaveOccurred()) 94 | 95 | Expect(fakeErrorHandler.HandleErrorCallCount()).To(Equal(1)) 96 | Expect(fakeErrorHandler.HandleErrorArgsForCall(0)).To(Equal(authErr)) 97 | }) 98 | }) 99 | 100 | Context("when authenticating fails", func() { 101 | BeforeEach(func() { 102 | authResult = false 103 | }) 104 | 105 | It("invokes the error handler", func() { 106 | err := client.Login( 107 | profileName, 108 | apiToken, 109 | host, 110 | ) 111 | Expect(err).NotTo(HaveOccurred()) 112 | 113 | Expect(fakeErrorHandler.HandleErrorCallCount()).To(Equal(1)) 114 | Expect(fakeErrorHandler.HandleErrorArgsForCall(0).Error()).To(ContainSubstring("login")) 115 | }) 116 | }) 117 | }) 118 | }) 119 | -------------------------------------------------------------------------------- /commands/login/loginfakes/fake_pivnet_client.go: -------------------------------------------------------------------------------- 1 | // Code generated by counterfeiter. DO NOT EDIT. 2 | package loginfakes 3 | 4 | import ( 5 | "sync" 6 | 7 | "github.com/pivotal-cf/pivnet-cli/v3/commands/login" 8 | ) 9 | 10 | type FakePivnetClient struct { 11 | AuthStub func() (bool, error) 12 | authMutex sync.RWMutex 13 | authArgsForCall []struct { 14 | } 15 | authReturns struct { 16 | result1 bool 17 | result2 error 18 | } 19 | authReturnsOnCall map[int]struct { 20 | result1 bool 21 | result2 error 22 | } 23 | invocations map[string][][]interface{} 24 | invocationsMutex sync.RWMutex 25 | } 26 | 27 | func (fake *FakePivnetClient) Auth() (bool, error) { 28 | fake.authMutex.Lock() 29 | ret, specificReturn := fake.authReturnsOnCall[len(fake.authArgsForCall)] 30 | fake.authArgsForCall = append(fake.authArgsForCall, struct { 31 | }{}) 32 | fake.recordInvocation("Auth", []interface{}{}) 33 | fake.authMutex.Unlock() 34 | if fake.AuthStub != nil { 35 | return fake.AuthStub() 36 | } 37 | if specificReturn { 38 | return ret.result1, ret.result2 39 | } 40 | fakeReturns := fake.authReturns 41 | return fakeReturns.result1, fakeReturns.result2 42 | } 43 | 44 | func (fake *FakePivnetClient) AuthCallCount() int { 45 | fake.authMutex.RLock() 46 | defer fake.authMutex.RUnlock() 47 | return len(fake.authArgsForCall) 48 | } 49 | 50 | func (fake *FakePivnetClient) AuthCalls(stub func() (bool, error)) { 51 | fake.authMutex.Lock() 52 | defer fake.authMutex.Unlock() 53 | fake.AuthStub = stub 54 | } 55 | 56 | func (fake *FakePivnetClient) AuthReturns(result1 bool, result2 error) { 57 | fake.authMutex.Lock() 58 | defer fake.authMutex.Unlock() 59 | fake.AuthStub = nil 60 | fake.authReturns = struct { 61 | result1 bool 62 | result2 error 63 | }{result1, result2} 64 | } 65 | 66 | func (fake *FakePivnetClient) AuthReturnsOnCall(i int, result1 bool, result2 error) { 67 | fake.authMutex.Lock() 68 | defer fake.authMutex.Unlock() 69 | fake.AuthStub = nil 70 | if fake.authReturnsOnCall == nil { 71 | fake.authReturnsOnCall = make(map[int]struct { 72 | result1 bool 73 | result2 error 74 | }) 75 | } 76 | fake.authReturnsOnCall[i] = struct { 77 | result1 bool 78 | result2 error 79 | }{result1, result2} 80 | } 81 | 82 | func (fake *FakePivnetClient) Invocations() map[string][][]interface{} { 83 | fake.invocationsMutex.RLock() 84 | defer fake.invocationsMutex.RUnlock() 85 | fake.authMutex.RLock() 86 | defer fake.authMutex.RUnlock() 87 | copiedInvocations := map[string][][]interface{}{} 88 | for key, value := range fake.invocations { 89 | copiedInvocations[key] = value 90 | } 91 | return copiedInvocations 92 | } 93 | 94 | func (fake *FakePivnetClient) recordInvocation(key string, args []interface{}) { 95 | fake.invocationsMutex.Lock() 96 | defer fake.invocationsMutex.Unlock() 97 | if fake.invocations == nil { 98 | fake.invocations = map[string][][]interface{}{} 99 | } 100 | if fake.invocations[key] == nil { 101 | fake.invocations[key] = [][]interface{}{} 102 | } 103 | fake.invocations[key] = append(fake.invocations[key], args) 104 | } 105 | 106 | var _ login.PivnetClient = new(FakePivnetClient) 107 | -------------------------------------------------------------------------------- /commands/login_test.go: -------------------------------------------------------------------------------- 1 | package commands_test 2 | 3 | import ( 4 | "bytes" 5 | "errors" 6 | "fmt" 7 | "reflect" 8 | 9 | . "github.com/onsi/ginkgo" 10 | . "github.com/onsi/gomega" 11 | "github.com/pivotal-cf/pivnet-cli/v3/commands" 12 | "github.com/pivotal-cf/pivnet-cli/v3/commands/commandsfakes" 13 | "github.com/pivotal-cf/pivnet-cli/v3/commands/login" 14 | ) 15 | 16 | var _ = Describe("login commands", func() { 17 | var ( 18 | field reflect.StructField 19 | 20 | fakeLoginClient *commandsfakes.FakeLoginClient 21 | ) 22 | 23 | BeforeEach(func() { 24 | fakeLoginClient = &commandsfakes.FakeLoginClient{} 25 | 26 | commands.NewLoginClient = func(login.PivnetClient) commands.LoginClient { 27 | return fakeLoginClient 28 | } 29 | }) 30 | 31 | Describe("LoginCommand", func() { 32 | var ( 33 | cmd commands.LoginCommand 34 | ) 35 | 36 | BeforeEach(func() { 37 | cmd.APIToken = "some-api-token" 38 | }) 39 | 40 | It("invokes the Login client", func() { 41 | err := cmd.Execute(nil) 42 | 43 | Expect(err).NotTo(HaveOccurred()) 44 | 45 | Expect(fakeLoginClient.LoginCallCount()).To(Equal(1)) 46 | }) 47 | 48 | It("invokes the Init function with 'false'", func() { 49 | err := cmd.Execute(nil) 50 | 51 | Expect(err).NotTo(HaveOccurred()) 52 | 53 | Expect(initInvocationArg).To(BeFalse()) 54 | }) 55 | 56 | Context("when the Login client returns an error", func() { 57 | var ( 58 | expectedErr error 59 | ) 60 | 61 | BeforeEach(func() { 62 | expectedErr = errors.New("expected error") 63 | fakeLoginClient.LoginReturns(expectedErr) 64 | }) 65 | 66 | It("forwards the error", func() { 67 | err := cmd.Execute(nil) 68 | 69 | Expect(err).To(Equal(expectedErr)) 70 | }) 71 | }) 72 | 73 | Context("when Init returns an error", func() { 74 | BeforeEach(func() { 75 | initErr = fmt.Errorf("init error") 76 | }) 77 | 78 | It("forwards the error", func() { 79 | err := cmd.Execute(nil) 80 | 81 | Expect(err).To(Equal(initErr)) 82 | }) 83 | }) 84 | 85 | It("sanitizes new api token", func() { 86 | outBuffer := bytes.Buffer{} 87 | commands.OutputWriter = &outBuffer 88 | 89 | err := cmd.Execute(nil) 90 | Expect(err).NotTo(HaveOccurred()) 91 | 92 | _, err = fmt.Fprintf(commands.OutputWriter, apiToken) 93 | Expect(err).NotTo(HaveOccurred()) 94 | 95 | Expect(outBuffer.String()).Should(ContainSubstring("*** redacted api token ***")) 96 | Expect(outBuffer.String()).ShouldNot(ContainSubstring(apiToken)) 97 | }) 98 | 99 | Describe("APIToken flag", func() { 100 | BeforeEach(func() { 101 | field = fieldFor(cmd, "APIToken") 102 | }) 103 | 104 | It("is required", func() { 105 | Expect(isRequired(field)).To(BeTrue()) 106 | }) 107 | 108 | It("contains long name", func() { 109 | Expect(longTag(field)).To(Equal("api-token")) 110 | }) 111 | }) 112 | 113 | Describe("Host flag", func() { 114 | BeforeEach(func() { 115 | field = fieldFor(cmd, "Host") 116 | }) 117 | 118 | It("contains long flag", func() { 119 | Expect(longTag(field)).To(Equal("host")) 120 | }) 121 | 122 | It("is not required", func() { 123 | Expect(isRequired(field)).To(BeFalse()) 124 | }) 125 | 126 | It("has a default value", func() { 127 | Expect(defaultVal(field)).To(Equal("https://network.tanzu.vmware.com")) 128 | }) 129 | }) 130 | 131 | }) 132 | }) 133 | -------------------------------------------------------------------------------- /commands/logout.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import "github.com/pivotal-cf/pivnet-cli/v3/commands/logout" 4 | 5 | type LogoutCommand struct { 6 | } 7 | 8 | //go:generate counterfeiter . LogoutClient 9 | type LogoutClient interface { 10 | Logout(profileName string) error 11 | } 12 | 13 | var NewLogoutClient = func() LogoutClient { 14 | return logout.NewLogoutClient( 15 | RC, 16 | ErrorHandler, 17 | Pivnet.Format, 18 | OutputWriter, 19 | Printer, 20 | ) 21 | } 22 | 23 | func (command *LogoutCommand) Execute([]string) error { 24 | err := Init(false) 25 | if err != nil { 26 | return err 27 | } 28 | 29 | return NewLogoutClient().Logout( 30 | Pivnet.ProfileName, 31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /commands/logout/init_test.go: -------------------------------------------------------------------------------- 1 | package logout_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestCommands(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Logout commands suite") 13 | } 14 | -------------------------------------------------------------------------------- /commands/logout/logout_client.go: -------------------------------------------------------------------------------- 1 | package logout 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | 7 | "github.com/pivotal-cf/pivnet-cli/v3/errorhandler" 8 | "github.com/pivotal-cf/pivnet-cli/v3/printer" 9 | "github.com/pivotal-cf/pivnet-cli/v3/ui" 10 | ) 11 | 12 | //go:generate counterfeiter . RCHandler 13 | type RCHandler interface { 14 | RemoveProfileWithName(profileName string) error 15 | } 16 | 17 | type LogoutClient struct { 18 | rcHandler RCHandler 19 | eh errorhandler.ErrorHandler 20 | format string 21 | outputWriter io.Writer 22 | printer printer.Printer 23 | } 24 | 25 | func NewLogoutClient( 26 | rcHandler RCHandler, 27 | eh errorhandler.ErrorHandler, 28 | format string, 29 | outputWriter io.Writer, 30 | printer printer.Printer, 31 | ) *LogoutClient { 32 | return &LogoutClient{ 33 | rcHandler: rcHandler, 34 | eh: eh, 35 | format: format, 36 | outputWriter: outputWriter, 37 | printer: printer, 38 | } 39 | } 40 | 41 | func (c *LogoutClient) Logout(profileName string) error { 42 | err := c.rcHandler.RemoveProfileWithName(profileName) 43 | if err != nil { 44 | return c.eh.HandleError(err) 45 | } 46 | 47 | return c.printLogout() 48 | } 49 | 50 | func (c *LogoutClient) printLogout() error { 51 | switch c.format { 52 | 53 | case printer.PrintAsTable: 54 | message := "Logged-out successfully" 55 | coloredMessage := ui.SuccessColor.SprintFunc()(message) 56 | 57 | _, err := fmt.Fprintln(c.outputWriter, coloredMessage) 58 | 59 | return err 60 | } 61 | 62 | return nil 63 | } 64 | -------------------------------------------------------------------------------- /commands/logout/logout_client_test.go: -------------------------------------------------------------------------------- 1 | package logout_test 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | 7 | . "github.com/onsi/ginkgo" 8 | . "github.com/onsi/gomega" 9 | "github.com/pivotal-cf/pivnet-cli/v3/commands/logout" 10 | "github.com/pivotal-cf/pivnet-cli/v3/commands/logout/logoutfakes" 11 | "github.com/pivotal-cf/pivnet-cli/v3/errorhandler/errorhandlerfakes" 12 | "github.com/pivotal-cf/pivnet-cli/v3/printer" 13 | ) 14 | 15 | var _ = Describe("logout commands", func() { 16 | var ( 17 | fakeRCHandler *logoutfakes.FakeRCHandler 18 | fakeErrorHandler *errorhandlerfakes.FakeErrorHandler 19 | 20 | outBuffer bytes.Buffer 21 | 22 | client *logout.LogoutClient 23 | ) 24 | 25 | BeforeEach(func() { 26 | fakeRCHandler = &logoutfakes.FakeRCHandler{} 27 | 28 | outBuffer = bytes.Buffer{} 29 | 30 | fakeErrorHandler = &errorhandlerfakes.FakeErrorHandler{} 31 | 32 | client = logout.NewLogoutClient( 33 | fakeRCHandler, 34 | fakeErrorHandler, 35 | printer.PrintAsJSON, 36 | &outBuffer, 37 | printer.NewPrinter(&outBuffer), 38 | ) 39 | }) 40 | 41 | Describe("Logout", func() { 42 | var ( 43 | profileName string 44 | 45 | removeProfileErr error 46 | ) 47 | 48 | BeforeEach(func() { 49 | profileName = "some-logout-slug" 50 | 51 | removeProfileErr = nil 52 | }) 53 | 54 | JustBeforeEach(func() { 55 | fakeRCHandler.RemoveProfileWithNameReturns(removeProfileErr) 56 | }) 57 | 58 | It("removes profile", func() { 59 | err := client.Logout(profileName) 60 | Expect(err).NotTo(HaveOccurred()) 61 | 62 | Expect(fakeRCHandler.RemoveProfileWithNameCallCount()).To(Equal(1)) 63 | invokedProfileName := fakeRCHandler.RemoveProfileWithNameArgsForCall(0) 64 | 65 | Expect(invokedProfileName).To(Equal(profileName)) 66 | }) 67 | 68 | Context("when removing profile returns an error", func() { 69 | BeforeEach(func() { 70 | removeProfileErr = fmt.Errorf("remove profile error") 71 | }) 72 | 73 | It("invokes the error handler", func() { 74 | err := client.Logout(profileName) 75 | Expect(err).NotTo(HaveOccurred()) 76 | 77 | Expect(fakeErrorHandler.HandleErrorCallCount()).To(Equal(1)) 78 | Expect(fakeErrorHandler.HandleErrorArgsForCall(0)).To(Equal(removeProfileErr)) 79 | }) 80 | }) 81 | }) 82 | }) 83 | -------------------------------------------------------------------------------- /commands/logout_test.go: -------------------------------------------------------------------------------- 1 | package commands_test 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | 7 | . "github.com/onsi/ginkgo" 8 | . "github.com/onsi/gomega" 9 | "github.com/pivotal-cf/pivnet-cli/v3/commands" 10 | "github.com/pivotal-cf/pivnet-cli/v3/commands/commandsfakes" 11 | ) 12 | 13 | var _ = Describe("logout commands", func() { 14 | var ( 15 | fakeLogoutClient *commandsfakes.FakeLogoutClient 16 | ) 17 | 18 | BeforeEach(func() { 19 | fakeLogoutClient = &commandsfakes.FakeLogoutClient{} 20 | 21 | commands.NewLogoutClient = func() commands.LogoutClient { 22 | return fakeLogoutClient 23 | } 24 | }) 25 | 26 | Describe("LogoutCommand", func() { 27 | var ( 28 | cmd commands.LogoutCommand 29 | ) 30 | 31 | It("invokes the Logout client", func() { 32 | err := cmd.Execute(nil) 33 | 34 | Expect(err).NotTo(HaveOccurred()) 35 | 36 | Expect(fakeLogoutClient.LogoutCallCount()).To(Equal(1)) 37 | }) 38 | 39 | It("invokes the Init function with 'false'", func() { 40 | err := cmd.Execute(nil) 41 | 42 | Expect(err).NotTo(HaveOccurred()) 43 | 44 | Expect(initInvocationArg).To(BeFalse()) 45 | }) 46 | 47 | Context("when the Logout client returns an error", func() { 48 | var ( 49 | expectedErr error 50 | ) 51 | 52 | BeforeEach(func() { 53 | expectedErr = errors.New("expected error") 54 | fakeLogoutClient.LogoutReturns(expectedErr) 55 | }) 56 | 57 | It("forwards the error", func() { 58 | err := cmd.Execute(nil) 59 | 60 | Expect(err).To(Equal(expectedErr)) 61 | }) 62 | }) 63 | 64 | Context("when Init returns an error", func() { 65 | BeforeEach(func() { 66 | initErr = fmt.Errorf("init error") 67 | }) 68 | 69 | It("forwards the error", func() { 70 | err := cmd.Execute(nil) 71 | 72 | Expect(err).To(Equal(initErr)) 73 | }) 74 | }) 75 | }) 76 | }) 77 | -------------------------------------------------------------------------------- /commands/pivnet_versions.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "github.com/pivotal-cf/pivnet-cli/v3/commands/pivnetversions" 5 | ) 6 | 7 | type PivnetVersionsCommand struct { 8 | } 9 | 10 | //go:generate counterfeiter . PivnetVersionsClient 11 | type PivnetVersionsClient interface { 12 | List() error 13 | Warn(currentVersion string) string 14 | } 15 | 16 | var NewPivnetVersionsClient = func(client pivnetversions.PivnetClient) PivnetVersionsClient { 17 | return pivnetversions.NewPivnetVersionsClient( 18 | client, 19 | ErrorHandler, 20 | Pivnet.Format, 21 | OutputWriter, 22 | Printer, 23 | ) 24 | } 25 | 26 | func (command *PivnetVersionsCommand) Execute(args []string) error { 27 | err := Init(true) 28 | if err != nil { 29 | return err 30 | } 31 | 32 | client := NewPivnetClient() 33 | err = Auth.AuthenticateClient(client) 34 | if err != nil { 35 | return err 36 | } 37 | 38 | return NewPivnetVersionsClient(client).List() 39 | } 40 | -------------------------------------------------------------------------------- /commands/pivnet_versions_test.go: -------------------------------------------------------------------------------- 1 | package commands_test 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | "github.com/pivotal-cf/pivnet-cli/v3/commands" 9 | "github.com/pivotal-cf/pivnet-cli/v3/commands/commandsfakes" 10 | "github.com/pivotal-cf/pivnet-cli/v3/commands/pivnetversions" 11 | ) 12 | 13 | var _ = Describe("pivnet versions command", func() { 14 | var ( 15 | fakePivnetVersionsClient *commandsfakes.FakePivnetVersionsClient 16 | ) 17 | 18 | BeforeEach(func() { 19 | fakePivnetVersionsClient = &commandsfakes.FakePivnetVersionsClient{} 20 | 21 | commands.NewPivnetVersionsClient = func(pivnetversions.PivnetClient) commands.PivnetVersionsClient { 22 | return fakePivnetVersionsClient 23 | } 24 | }) 25 | 26 | Describe("PivnetVersionsCommand", func() { 27 | var ( 28 | cmd *commands.PivnetVersionsCommand 29 | ) 30 | 31 | BeforeEach(func() { 32 | cmd = &commands.PivnetVersionsCommand{} 33 | }) 34 | 35 | It("invokes the PivnetVersions client", func() { 36 | err := cmd.Execute(nil) 37 | 38 | Expect(err).NotTo(HaveOccurred()) 39 | 40 | Expect(fakePivnetVersionsClient.ListCallCount()).To(Equal(1)) 41 | }) 42 | 43 | Context("when the PivnetVersions client returns an error", func() { 44 | var ( 45 | expectedErr error 46 | ) 47 | 48 | BeforeEach(func() { 49 | expectedErr = errors.New("expected error") 50 | fakePivnetVersionsClient.ListReturns(expectedErr) 51 | }) 52 | 53 | It("forwards the error", func() { 54 | err := cmd.Execute(nil) 55 | 56 | Expect(err).To(Equal(expectedErr)) 57 | }) 58 | }) 59 | 60 | Context("when Init returns an error", func() { 61 | BeforeEach(func() { 62 | initErr = fmt.Errorf("init error") 63 | }) 64 | 65 | It("forwards the error", func() { 66 | err := cmd.Execute(nil) 67 | 68 | Expect(err).To(Equal(initErr)) 69 | }) 70 | }) 71 | 72 | Context("when Authentication returns an error", func() { 73 | BeforeEach(func() { 74 | authErr = fmt.Errorf("auth error") 75 | }) 76 | 77 | It("forwards the error", func() { 78 | err := cmd.Execute(nil) 79 | 80 | Expect(err).To(Equal(authErr)) 81 | }) 82 | }) 83 | }) 84 | }) 85 | -------------------------------------------------------------------------------- /commands/pivnetversions/init_test.go: -------------------------------------------------------------------------------- 1 | package pivnetversions_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestCommands(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "PivnetVersions commands suite") 13 | } 14 | -------------------------------------------------------------------------------- /commands/pivnetversions/pivnet_versions_client.go: -------------------------------------------------------------------------------- 1 | package pivnetversions 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | 7 | "github.com/olekukonko/tablewriter" 8 | "github.com/pivotal-cf/go-pivnet/v7" 9 | "github.com/pivotal-cf/pivnet-cli/v3/errorhandler" 10 | "github.com/pivotal-cf/pivnet-cli/v3/printer" 11 | "github.com/pivotal-cf/pivnet-cli/v3/semver" 12 | ) 13 | 14 | //go:generate counterfeiter . PivnetClient 15 | type PivnetClient interface { 16 | PivnetVersions() (pivnet.PivnetVersions, error) 17 | } 18 | 19 | type PivnetVersionsClient struct { 20 | pivnetClient PivnetClient 21 | eh errorhandler.ErrorHandler 22 | format string 23 | outputWriter io.Writer 24 | printer printer.Printer 25 | } 26 | 27 | func NewPivnetVersionsClient( 28 | pivnetClient PivnetClient, 29 | eh errorhandler.ErrorHandler, 30 | format string, 31 | outputWriter io.Writer, 32 | printer printer.Printer, 33 | ) *PivnetVersionsClient { 34 | return &PivnetVersionsClient{ 35 | pivnetClient: pivnetClient, 36 | eh: eh, 37 | format: format, 38 | outputWriter: outputWriter, 39 | printer: printer, 40 | } 41 | } 42 | 43 | func (c *PivnetVersionsClient) List() error { 44 | pivnetVersions, err := c.pivnetClient.PivnetVersions() 45 | if err != nil { 46 | return c.eh.HandleError(err) 47 | } 48 | 49 | switch c.format { 50 | case printer.PrintAsTable: 51 | table := tablewriter.NewWriter(c.outputWriter) 52 | table.SetHeader([]string{"Pivnet Component", "Latest Release Version"}) 53 | table.Append([]string{"Pivnet CLI", pivnetVersions.PivnetCliVersion}) 54 | table.Append([]string{"Pivnet Resource", pivnetVersions.PivnetResourceVersion}) 55 | table.Render() 56 | return nil 57 | case printer.PrintAsJSON: 58 | return c.printer.PrintJSON(pivnetVersions) 59 | case printer.PrintAsYAML: 60 | return c.printer.PrintYAML(pivnetVersions) 61 | } 62 | 63 | return nil 64 | } 65 | 66 | func (c *PivnetVersionsClient) Warn(currentVersion string) string { 67 | pivnetVersions, err := c.pivnetClient.PivnetVersions() 68 | if err == nil { 69 | comparison, err := semver.Compare(currentVersion, pivnetVersions.PivnetCliVersion) 70 | if err == nil && comparison < 0 { 71 | return fmt.Sprintf("Warning: Your version of Pivnet CLI (%s) does not match the currently released version (%s).", currentVersion, pivnetVersions.PivnetCliVersion) 72 | } else { 73 | return "" 74 | } 75 | } else { 76 | return "" 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /commands/pivnetversions/pivnet_versions_client_test.go: -------------------------------------------------------------------------------- 1 | package pivnetversions_test 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "errors" 7 | 8 | . "github.com/onsi/ginkgo" 9 | . "github.com/onsi/gomega" 10 | pivnet "github.com/pivotal-cf/go-pivnet/v7" 11 | "github.com/pivotal-cf/pivnet-cli/v3/commands/pivnetversions" 12 | "github.com/pivotal-cf/pivnet-cli/v3/commands/pivnetversions/pivnetversionsfakes" 13 | "github.com/pivotal-cf/pivnet-cli/v3/errorhandler/errorhandlerfakes" 14 | "github.com/pivotal-cf/pivnet-cli/v3/printer" 15 | ) 16 | 17 | var _ = Describe("pivnetversions commands", func() { 18 | var ( 19 | fakePivnetClient *pivnetversionsfakes.FakePivnetClient 20 | 21 | fakeErrorHandler *errorhandlerfakes.FakeErrorHandler 22 | 23 | outBuffer bytes.Buffer 24 | 25 | pivnetVersions pivnet.PivnetVersions 26 | 27 | client *pivnetversions.PivnetVersionsClient 28 | ) 29 | 30 | BeforeEach(func() { 31 | fakePivnetClient = &pivnetversionsfakes.FakePivnetClient{} 32 | 33 | outBuffer = bytes.Buffer{} 34 | 35 | fakeErrorHandler = &errorhandlerfakes.FakeErrorHandler{} 36 | 37 | pivnetVersions = pivnet.PivnetVersions{"1.2.3", "3.2.1"} 38 | 39 | fakePivnetClient.PivnetVersionsReturns(pivnetVersions, nil) 40 | 41 | client = pivnetversions.NewPivnetVersionsClient( 42 | fakePivnetClient, 43 | fakeErrorHandler, 44 | printer.PrintAsJSON, 45 | &outBuffer, 46 | printer.NewPrinter(&outBuffer), 47 | ) 48 | }) 49 | 50 | Describe("PivnetVersions.List", func() { 51 | It("lists all PivnetVersions", func() { 52 | err := client.List() 53 | Expect(err).NotTo(HaveOccurred()) 54 | 55 | var returnedPivnetVersions pivnet.PivnetVersions 56 | err = json.Unmarshal(outBuffer.Bytes(), &returnedPivnetVersions) 57 | Expect(err).NotTo(HaveOccurred()) 58 | 59 | Expect(returnedPivnetVersions).To(Equal(pivnetVersions)) 60 | }) 61 | 62 | Context("when there is an error", func() { 63 | var ( 64 | expectedErr error 65 | ) 66 | 67 | BeforeEach(func() { 68 | expectedErr = errors.New("pivnetversions error") 69 | fakePivnetClient.PivnetVersionsReturns(pivnet.PivnetVersions{}, expectedErr) 70 | }) 71 | 72 | It("invokes the error handler", func() { 73 | err := client.List() 74 | Expect(err).NotTo(HaveOccurred()) 75 | 76 | Expect(fakeErrorHandler.HandleErrorCallCount()).To(Equal(1)) 77 | Expect(fakeErrorHandler.HandleErrorArgsForCall(0)).To(Equal(expectedErr)) 78 | }) 79 | }) 80 | }) 81 | 82 | Describe("PivnetVersions.Warn", func() { 83 | It("returns a warning if the current Pivnet CLI version is out of date", func() { 84 | result := client.Warn("1.2.2") 85 | Expect(result).NotTo(BeEmpty()) 86 | }) 87 | 88 | It("returns empty if the current Pivnet CLI version is up to date", func() { 89 | result := client.Warn("1.2.3") 90 | Expect(result).To(BeEmpty()) 91 | }) 92 | 93 | It("returns empty if the current Pivnet CLI version is newer", func() { 94 | result := client.Warn("1.2.4") 95 | Expect(result).To(BeEmpty()) 96 | }) 97 | 98 | It("returns empty if there is an error getting the latest Pivnet CLI version", func() { 99 | expectedErr := errors.New("pivnetversions error") 100 | fakePivnetClient.PivnetVersionsReturns(pivnet.PivnetVersions{}, expectedErr) 101 | 102 | result := client.Warn("1.2.3") 103 | Expect(result).To(BeEmpty()) 104 | }) 105 | }) 106 | }) 107 | -------------------------------------------------------------------------------- /commands/product.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import "github.com/pivotal-cf/pivnet-cli/v3/commands/product" 4 | 5 | type ProductCommand struct { 6 | ProductSlug string `long:"product-slug" short:"p" description:"Product slug e.g. p-mysql" required:"true"` 7 | } 8 | 9 | type ProductsCommand struct { 10 | } 11 | 12 | type ProductSlugsCommand struct { 13 | ProductSlug string `long:"product-slug" short:"p" description:"Product slug e.g. p-mysql" required:"true"` 14 | } 15 | 16 | //go:generate counterfeiter . ProductClient 17 | type ProductClient interface { 18 | List() error 19 | Get(productSlug string) error 20 | SlugAlias(productSlug string) error 21 | } 22 | 23 | var NewProductClient = func(client product.PivnetClient) ProductClient { 24 | return product.NewProductClient( 25 | client, 26 | ErrorHandler, 27 | Pivnet.Format, 28 | OutputWriter, 29 | Printer, 30 | ) 31 | } 32 | 33 | func (command *ProductsCommand) Execute([]string) error { 34 | err := Init(true) 35 | if err != nil { 36 | return err 37 | } 38 | 39 | client := NewPivnetClient() 40 | err = Auth.AuthenticateClient(client) 41 | if err != nil { 42 | return err 43 | } 44 | 45 | return NewProductClient(client).List() 46 | } 47 | 48 | func (command *ProductCommand) Execute([]string) error { 49 | err := Init(true) 50 | if err != nil { 51 | return err 52 | } 53 | 54 | client := NewPivnetClient() 55 | err = Auth.AuthenticateClient(client) 56 | if err != nil { 57 | return err 58 | } 59 | 60 | return NewProductClient(client).Get(command.ProductSlug) 61 | } 62 | 63 | func (command *ProductSlugsCommand) Execute([]string) error { 64 | err := Init(true) 65 | if err != nil { 66 | return err 67 | } 68 | 69 | client := NewPivnetClient() 70 | err = Auth.AuthenticateClient(client) 71 | if err != nil { 72 | return err 73 | } 74 | 75 | return NewProductClient(client).SlugAlias(command.ProductSlug) 76 | } 77 | -------------------------------------------------------------------------------- /commands/product/init_test.go: -------------------------------------------------------------------------------- 1 | package product_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestCommands(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Product commands suite") 13 | } 14 | -------------------------------------------------------------------------------- /commands/productfile/init_test.go: -------------------------------------------------------------------------------- 1 | package productfile_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestCommands(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "ProductFile suite") 13 | } 14 | -------------------------------------------------------------------------------- /commands/release/init_test.go: -------------------------------------------------------------------------------- 1 | package release_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestCommands(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "Release suite") 13 | } 14 | -------------------------------------------------------------------------------- /commands/release_type.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import "github.com/pivotal-cf/pivnet-cli/v3/commands/releasetype" 4 | 5 | type ReleaseTypesCommand struct { 6 | } 7 | 8 | //go:generate counterfeiter . ReleaseTypeClient 9 | type ReleaseTypeClient interface { 10 | List() error 11 | } 12 | 13 | var NewReleaseTypeClient = func(client releasetype.PivnetClient) ReleaseTypeClient { 14 | return releasetype.NewReleaseTypeClient( 15 | client, 16 | ErrorHandler, 17 | Pivnet.Format, 18 | OutputWriter, 19 | Printer, 20 | ) 21 | } 22 | 23 | func (command *ReleaseTypesCommand) Execute(args []string) error { 24 | err := Init(true) 25 | if err != nil { 26 | return err 27 | } 28 | 29 | client := NewPivnetClient() 30 | err = Auth.AuthenticateClient(client) 31 | if err != nil { 32 | return err 33 | } 34 | 35 | return NewReleaseTypeClient(client).List() 36 | } 37 | -------------------------------------------------------------------------------- /commands/release_type_test.go: -------------------------------------------------------------------------------- 1 | package commands_test 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | 7 | . "github.com/onsi/ginkgo" 8 | . "github.com/onsi/gomega" 9 | "github.com/pivotal-cf/pivnet-cli/v3/commands" 10 | "github.com/pivotal-cf/pivnet-cli/v3/commands/commandsfakes" 11 | "github.com/pivotal-cf/pivnet-cli/v3/commands/releasetype" 12 | ) 13 | 14 | var _ = Describe("release types commands", func() { 15 | var ( 16 | fakeReleaseTypeClient *commandsfakes.FakeReleaseTypeClient 17 | ) 18 | 19 | BeforeEach(func() { 20 | fakeReleaseTypeClient = &commandsfakes.FakeReleaseTypeClient{} 21 | 22 | commands.NewReleaseTypeClient = func(releasetype.PivnetClient) commands.ReleaseTypeClient { 23 | return fakeReleaseTypeClient 24 | } 25 | }) 26 | 27 | Describe("ReleaseTypesCommand", func() { 28 | var ( 29 | cmd *commands.ReleaseTypesCommand 30 | ) 31 | 32 | BeforeEach(func() { 33 | cmd = &commands.ReleaseTypesCommand{} 34 | }) 35 | 36 | It("invokes the ReleaseType client", func() { 37 | err := cmd.Execute(nil) 38 | 39 | Expect(err).NotTo(HaveOccurred()) 40 | 41 | Expect(fakeReleaseTypeClient.ListCallCount()).To(Equal(1)) 42 | }) 43 | 44 | Context("when the ReleaseType client returns an error", func() { 45 | var ( 46 | expectedErr error 47 | ) 48 | 49 | BeforeEach(func() { 50 | expectedErr = errors.New("expected error") 51 | fakeReleaseTypeClient.ListReturns(expectedErr) 52 | }) 53 | 54 | It("forwards the error", func() { 55 | err := cmd.Execute(nil) 56 | 57 | Expect(err).To(Equal(expectedErr)) 58 | }) 59 | }) 60 | 61 | Context("when Init returns an error", func() { 62 | BeforeEach(func() { 63 | initErr = fmt.Errorf("init error") 64 | }) 65 | 66 | It("forwards the error", func() { 67 | err := cmd.Execute(nil) 68 | 69 | Expect(err).To(Equal(initErr)) 70 | }) 71 | }) 72 | 73 | Context("when Authentication returns an error", func() { 74 | BeforeEach(func() { 75 | authErr = fmt.Errorf("auth error") 76 | }) 77 | 78 | It("forwards the error", func() { 79 | err := cmd.Execute(nil) 80 | 81 | Expect(err).To(Equal(authErr)) 82 | }) 83 | }) 84 | 85 | }) 86 | }) 87 | -------------------------------------------------------------------------------- /commands/release_upgrade_path.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import "github.com/pivotal-cf/pivnet-cli/v3/commands/releaseupgradepath" 4 | 5 | type ReleaseUpgradePathsCommand struct { 6 | ProductSlug string `long:"product-slug" short:"p" description:"Product slug e.g. p-mysql" required:"true"` 7 | ReleaseVersion string `long:"release-version" short:"r" description:"Release version e.g. 0.1.2-rc1" required:"true"` 8 | } 9 | 10 | type AddReleaseUpgradePathCommand struct { 11 | ProductSlug string `long:"product-slug" short:"p" description:"Product slug e.g. p-mysql" required:"true"` 12 | ReleaseVersion string `long:"release-version" short:"r" description:"Release version e.g. 0.1.2-rc1" required:"true"` 13 | PreviousReleaseVersion string `long:"previous-release-version" short:"u" description:"Regex for previous release version e.g. 0.1.*" required:"true"` 14 | } 15 | 16 | type RemoveReleaseUpgradePathCommand struct { 17 | ProductSlug string `long:"product-slug" short:"p" description:"Product slug e.g. p-mysql" required:"true"` 18 | ReleaseVersion string `long:"release-version" short:"r" description:"Release version e.g. 0.1.2-rc1" required:"true"` 19 | PreviousReleaseVersion string `long:"previous-release-version" short:"u" description:"Regex for previous release version e.g. 0.1.*" required:"true"` 20 | } 21 | 22 | //go:generate counterfeiter . ReleaseUpgradePathClient 23 | type ReleaseUpgradePathClient interface { 24 | List(productSlug string, releaseVersion string) error 25 | Add(productSlug string, releaseVersion string, previousReleaseVersion string) error 26 | Remove(productSlug string, releaseVersion string, previousReleaseVersion string) error 27 | } 28 | 29 | var NewReleaseUpgradePathClient = func(client releaseupgradepath.PivnetClient) ReleaseUpgradePathClient { 30 | return releaseupgradepath.NewReleaseUpgradePathClient( 31 | client, 32 | ErrorHandler, 33 | Pivnet.Format, 34 | OutputWriter, 35 | Printer, 36 | Filter, 37 | Pivnet.Logger, 38 | ) 39 | } 40 | 41 | func (command *ReleaseUpgradePathsCommand) Execute([]string) error { 42 | err := Init(true) 43 | if err != nil { 44 | return err 45 | } 46 | 47 | client := NewPivnetClient() 48 | err = Auth.AuthenticateClient(client) 49 | if err != nil { 50 | return err 51 | } 52 | 53 | return NewReleaseUpgradePathClient(client).List(command.ProductSlug, command.ReleaseVersion) 54 | } 55 | 56 | func (command *AddReleaseUpgradePathCommand) Execute([]string) error { 57 | err := Init(true) 58 | if err != nil { 59 | return err 60 | } 61 | 62 | client := NewPivnetClient() 63 | err = Auth.AuthenticateClient(client) 64 | if err != nil { 65 | return err 66 | } 67 | 68 | return NewReleaseUpgradePathClient(client).Add( 69 | command.ProductSlug, 70 | command.ReleaseVersion, 71 | command.PreviousReleaseVersion, 72 | ) 73 | } 74 | 75 | func (command *RemoveReleaseUpgradePathCommand) Execute([]string) error { 76 | err := Init(true) 77 | if err != nil { 78 | return err 79 | } 80 | 81 | client := NewPivnetClient() 82 | err = Auth.AuthenticateClient(client) 83 | if err != nil { 84 | return err 85 | } 86 | 87 | return NewReleaseUpgradePathClient(client).Remove( 88 | command.ProductSlug, 89 | command.ReleaseVersion, 90 | command.PreviousReleaseVersion, 91 | ) 92 | } 93 | -------------------------------------------------------------------------------- /commands/releasedependency/init_test.go: -------------------------------------------------------------------------------- 1 | package releasedependency_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestCommands(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "ReleaseDependency commands suite") 13 | } 14 | -------------------------------------------------------------------------------- /commands/releasetype/init_test.go: -------------------------------------------------------------------------------- 1 | package releasetype_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestCommands(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "ReleaseType commands suite") 13 | } 14 | -------------------------------------------------------------------------------- /commands/releasetype/release_type_client.go: -------------------------------------------------------------------------------- 1 | package releasetype 2 | 3 | import ( 4 | "io" 5 | 6 | "github.com/olekukonko/tablewriter" 7 | pivnet "github.com/pivotal-cf/go-pivnet/v7" 8 | "github.com/pivotal-cf/pivnet-cli/v3/errorhandler" 9 | "github.com/pivotal-cf/pivnet-cli/v3/printer" 10 | ) 11 | 12 | //go:generate counterfeiter . PivnetClient 13 | type PivnetClient interface { 14 | ReleaseTypes() ([]pivnet.ReleaseType, error) 15 | } 16 | 17 | type ReleaseTypeClient struct { 18 | pivnetClient PivnetClient 19 | eh errorhandler.ErrorHandler 20 | format string 21 | outputWriter io.Writer 22 | printer printer.Printer 23 | } 24 | 25 | func NewReleaseTypeClient( 26 | pivnetClient PivnetClient, 27 | eh errorhandler.ErrorHandler, 28 | format string, 29 | outputWriter io.Writer, 30 | printer printer.Printer, 31 | ) *ReleaseTypeClient { 32 | return &ReleaseTypeClient{ 33 | pivnetClient: pivnetClient, 34 | eh: eh, 35 | format: format, 36 | outputWriter: outputWriter, 37 | printer: printer, 38 | } 39 | } 40 | 41 | func (c *ReleaseTypeClient) List() error { 42 | releaseTypes, err := c.pivnetClient.ReleaseTypes() 43 | if err != nil { 44 | return c.eh.HandleError(err) 45 | } 46 | 47 | switch c.format { 48 | case printer.PrintAsTable: 49 | table := tablewriter.NewWriter(c.outputWriter) 50 | table.SetHeader([]string{"Release Types"}) 51 | 52 | for _, r := range releaseTypes { 53 | table.Append([]string{string(r)}) 54 | } 55 | table.Render() 56 | return nil 57 | case printer.PrintAsJSON: 58 | return c.printer.PrintJSON(releaseTypes) 59 | case printer.PrintAsYAML: 60 | return c.printer.PrintYAML(releaseTypes) 61 | } 62 | 63 | return nil 64 | } 65 | -------------------------------------------------------------------------------- /commands/releasetype/release_type_client_test.go: -------------------------------------------------------------------------------- 1 | package releasetype_test 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "errors" 7 | 8 | . "github.com/onsi/ginkgo" 9 | . "github.com/onsi/gomega" 10 | pivnet "github.com/pivotal-cf/go-pivnet/v7" 11 | "github.com/pivotal-cf/pivnet-cli/v3/commands/releasetype" 12 | "github.com/pivotal-cf/pivnet-cli/v3/commands/releasetype/releasetypefakes" 13 | "github.com/pivotal-cf/pivnet-cli/v3/errorhandler/errorhandlerfakes" 14 | "github.com/pivotal-cf/pivnet-cli/v3/printer" 15 | ) 16 | 17 | var _ = Describe("releasetype commands", func() { 18 | var ( 19 | fakePivnetClient *releasetypefakes.FakePivnetClient 20 | 21 | fakeErrorHandler *errorhandlerfakes.FakeErrorHandler 22 | 23 | outBuffer bytes.Buffer 24 | 25 | releasetypes []pivnet.ReleaseType 26 | 27 | client *releasetype.ReleaseTypeClient 28 | ) 29 | 30 | BeforeEach(func() { 31 | fakePivnetClient = &releasetypefakes.FakePivnetClient{} 32 | 33 | outBuffer = bytes.Buffer{} 34 | 35 | fakeErrorHandler = &errorhandlerfakes.FakeErrorHandler{} 36 | 37 | releasetypes = []pivnet.ReleaseType{ 38 | pivnet.ReleaseType("release-type-A"), 39 | pivnet.ReleaseType("release-type-B"), 40 | } 41 | 42 | fakePivnetClient.ReleaseTypesReturns(releasetypes, nil) 43 | 44 | client = releasetype.NewReleaseTypeClient( 45 | fakePivnetClient, 46 | fakeErrorHandler, 47 | printer.PrintAsJSON, 48 | &outBuffer, 49 | printer.NewPrinter(&outBuffer), 50 | ) 51 | }) 52 | 53 | Describe("ReleaseTypes", func() { 54 | It("lists all ReleaseTypes", func() { 55 | err := client.List() 56 | Expect(err).NotTo(HaveOccurred()) 57 | 58 | var returnedReleaseTypes []pivnet.ReleaseType 59 | err = json.Unmarshal(outBuffer.Bytes(), &returnedReleaseTypes) 60 | Expect(err).NotTo(HaveOccurred()) 61 | 62 | Expect(returnedReleaseTypes).To(Equal(releasetypes)) 63 | }) 64 | 65 | Context("when there is an error", func() { 66 | var ( 67 | expectedErr error 68 | ) 69 | 70 | BeforeEach(func() { 71 | expectedErr = errors.New("releasetypes error") 72 | fakePivnetClient.ReleaseTypesReturns(nil, expectedErr) 73 | }) 74 | 75 | It("invokes the error handler", func() { 76 | err := client.List() 77 | Expect(err).NotTo(HaveOccurred()) 78 | 79 | Expect(fakeErrorHandler.HandleErrorCallCount()).To(Equal(1)) 80 | Expect(fakeErrorHandler.HandleErrorArgsForCall(0)).To(Equal(expectedErr)) 81 | }) 82 | }) 83 | }) 84 | }) 85 | -------------------------------------------------------------------------------- /commands/releaseupgradepath/init_test.go: -------------------------------------------------------------------------------- 1 | package releaseupgradepath_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestCommands(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "ReleaseUpgradePath suite") 13 | } 14 | -------------------------------------------------------------------------------- /commands/subscription_group.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | import ( 4 | "github.com/pivotal-cf/pivnet-cli/v3/commands/subscriptiongroup" 5 | ) 6 | 7 | type SubscriptionGroupsCommand struct{} 8 | 9 | type SubscriptionGroupCommand struct { 10 | SubscriptionGroupID int `long:"subscription-group-id" short:"i" description:"Subscription group ID e.g. 1234" required:"true"` 11 | } 12 | 13 | type AddSubscriptionGroupMemberCommand struct { 14 | SubscriptionGroupID int `long:"subscription-group-id" short:"i" description:"Subscription group ID e.g. 1234" required:"true"` 15 | MemberEmail string `long:"member-email" description:"Email of member to add e.g. example@example.net" required:"true"` 16 | IsAdmin string `long:"admin" description:"Whether the user should be an admin e.g. --admin=[true|false]"` 17 | } 18 | 19 | type RemoveSubscriptionGroupMemberCommand struct { 20 | SubscriptionGroupID int `long:"subscription-group-id" short:"i" description:"Subscription group ID e.g. 1234" required:"true"` 21 | MemberEmail string `long:"member-email" description:"Email of member to add e.g. example@example.net" required:"true"` 22 | } 23 | 24 | //go:generate counterfeiter . SubscriptionGroupClient 25 | type SubscriptionGroupClient interface { 26 | List() error 27 | Get(subscriptionGroupID int) error 28 | AddMember(subscriptionGroupID int, memberEmail string, isAdmin string) error 29 | RemoveMember(subscriptionGroupID int, memberEmail string) error 30 | } 31 | 32 | var NewSubscriptionGroupClient = func(client subscriptiongroup.PivnetClient) SubscriptionGroupClient { 33 | return subscriptiongroup.NewSubscriptionGroupClient( 34 | client, 35 | ErrorHandler, 36 | Pivnet.Format, 37 | OutputWriter, 38 | Printer, 39 | ) 40 | } 41 | 42 | func (command *SubscriptionGroupsCommand) Execute([]string) error { 43 | err := Init(true) 44 | if err != nil { 45 | return err 46 | } 47 | 48 | client := NewPivnetClient() 49 | err = Auth.AuthenticateClient(client) 50 | if err != nil { 51 | return err 52 | } 53 | 54 | return NewSubscriptionGroupClient(client).List() 55 | } 56 | 57 | func (command *SubscriptionGroupCommand) Execute([]string) error { 58 | err := Init(true) 59 | if err != nil { 60 | return err 61 | } 62 | 63 | client := NewPivnetClient() 64 | err = Auth.AuthenticateClient(client) 65 | if err != nil { 66 | return err 67 | } 68 | 69 | return NewSubscriptionGroupClient(client).Get(command.SubscriptionGroupID) 70 | } 71 | 72 | func (command *AddSubscriptionGroupMemberCommand) Execute([]string) error { 73 | err := Init(true) 74 | if err != nil { 75 | return err 76 | } 77 | 78 | client := NewPivnetClient() 79 | err = Auth.AuthenticateClient(client) 80 | if err != nil { 81 | return err 82 | } 83 | 84 | return NewSubscriptionGroupClient(client).AddMember(command.SubscriptionGroupID, command.MemberEmail, command.IsAdmin) 85 | } 86 | 87 | func (command *RemoveSubscriptionGroupMemberCommand) Execute([]string) error { 88 | err := Init(true) 89 | if err != nil { 90 | return err 91 | } 92 | 93 | client := NewPivnetClient() 94 | err = Auth.AuthenticateClient(client) 95 | if err != nil { 96 | return err 97 | } 98 | 99 | return NewSubscriptionGroupClient(client).RemoveMember(command.SubscriptionGroupID, command.MemberEmail) 100 | } 101 | -------------------------------------------------------------------------------- /commands/subscriptiongroup/init_test.go: -------------------------------------------------------------------------------- 1 | package subscriptiongroup_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestCommands(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "SubscriptionGroup suite") 13 | } 14 | -------------------------------------------------------------------------------- /commands/usergroup/init_test.go: -------------------------------------------------------------------------------- 1 | package usergroup_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/onsi/ginkgo" 7 | . "github.com/onsi/gomega" 8 | ) 9 | 10 | func TestCommands(t *testing.T) { 11 | RegisterFailHandler(Fail) 12 | RunSpecs(t, "UserGroup suite") 13 | } 14 | -------------------------------------------------------------------------------- /commands/version.go: -------------------------------------------------------------------------------- 1 | package commands 2 | 3 | type VersionCommand struct{} 4 | 5 | func (command *VersionCommand) Execute(args []string) error { 6 | Pivnet.VersionFunc() 7 | return nil 8 | } 9 | -------------------------------------------------------------------------------- /docs/content/about/project-management.md: -------------------------------------------------------------------------------- 1 | # Project Management 2 | 3 | The CI for this project can be found 4 | [here](https://pivnet.ci.cf-app.com/teams/main/pipelines/pivnet-cli) 5 | and the scripts can be found in the 6 | [pivnet-ci repo](https://github.com/pivotal-cf/pivnet-ci). 7 | 8 | The roadmap is captured in [Pivotal Tracker](https://www.pivotaltracker.com/projects/1474244). 9 | -------------------------------------------------------------------------------- /docs/content/development/contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | If you have not previously done so, please fill out and 4 | submit the https://cla.pivotal.io/sign/pivotal[Contributor License Agreement]. 5 | 6 | Please make all pull requests to the `develop` branch, and 7 | [ensure the tests pass locally](https://github.com/pivotal-cf/pivnet-cli#running-the-tests). 8 | -------------------------------------------------------------------------------- /docs/content/development/dependencies.md: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | 3 | Dependencies are vendored in the `vendor` directory, according to the 4 | [golang 1.5 vendor experiment](https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0ahUKEwi7puWg7ZrLAhUN1WMKHeT4A7oQFggdMAA&url=https%3A%2F%2Fgolang.org%2Fs%2Fgo15vendor&usg=AFQjCNEPCAjj1lnni5apHdA7rW0crWs7Zw). 5 | 6 | No action is require to fetch the vendored dependencies. 7 | -------------------------------------------------------------------------------- /docs/content/development/prerequisites.md: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | 3 | A valid install of golang >= 1.6 is required. 4 | -------------------------------------------------------------------------------- /docs/content/development/testing.md: -------------------------------------------------------------------------------- 1 | # Testing 2 | 3 | Install the ginkgo executable with: 4 | 5 | ``` 6 | go get -u github.com/onsi/ginkgo/ginkgo 7 | ``` 8 | 9 | The tests require a valid Pivotal Network API token and host. 10 | 11 | Refer to the 12 | [official docs](https://network.tanzu.vmware.com/docs/api#how-to-authenticate) 13 | for more details on obtaining a Pivotal Network API token. 14 | 15 | It is advised to run the acceptance tests against the Pivotal Network integration 16 | environment endpoint i.e. `HOST='https://pivnet-integration.cfapps.io'`. 17 | 18 | Run the tests with the following command: 19 | 20 | ``` 21 | API_TOKEN=my-token \ 22 | HOST='https://pivnet-integration.cfapps.io' \ 23 | ./bin/test_all 24 | ``` 25 | -------------------------------------------------------------------------------- /docs/content/examples/usage.md: -------------------------------------------------------------------------------- 1 | # Usage 2 | 3 | Using the Pivnet CLI requires a valid `Pivotal Network API token` or `UAA Refresh Token`. 4 | 5 | Refer to the 6 | [official docs](https://network.tanzu.vmware.com/docs/api#how-to-authenticate) 7 | for more details on obtaining a Pivotal Network API token. 8 | 9 | Example usage: 10 | 11 | ```sh 12 | $ pivnet login --api-token='my-api-token' 13 | $ pivnet products 14 | 15 | +-----+------------------------------------------------------+--------------------------------+ 16 | | ID | SLUG | NAME | 17 | +-----+------------------------------------------------------+--------------------------------+ 18 | | 60 | elastic-runtime | Pivotal Cloud Foundry Elastic | 19 | | | | Runtime | 20 | +-----+------------------------------------------------------+--------------------------------+ 21 | 22 | $ pivnet release --product-slug=elastic-runtime --release-version=1.8.8 --format json \ 23 | | jq '{"id": .id, "release_date": .release_date, "release_type": .release_type}' 24 | 25 | { 26 | "id": 2555, 27 | "release_date": "2016-10-13", 28 | "release_type": "Security Release" 29 | } 30 | ``` 31 | 32 | # Batch Command Examples 33 | 34 | The Pivnet UI has few places to edit content in batches. Batch processing is relegated to the [Pivnet Resource](https://github.com/pivotal-cf/pivnet-resource) and Pivnet CLI. 35 | 36 | Many commands require release versions. You could use the following pipeline to product a list of release versions: 37 | 38 | ```sh 39 | $ pivnet --format=json releases --product-slug=MY_PRODUCT_SLUG | jq '.[].version' 40 | "1.10.5" 41 | "1.10.4" 42 | "1.10.3" 43 | "1.10.2" 44 | "1.10.1" 45 | "1.10.0" 46 | ... 47 | ``` 48 | 49 | If you wanted to, for example, a remove a user group from all releases, you could use a pipeline similar to the following: 50 | 51 | ```sh 52 | $ pivnet --format=json releases --product-slug=MY_PRODUCT_SLUG | jq '.[].version' | xargs -I{} pivnet remove-user-group --product-slug=MY_PRODUCT_SLUG --release-version={} --user-group-id=USER_GROUP_ID_TO_REMOVE 53 | ``` 54 | 55 | Similarly, you could, for example, add an Elastic Runtime 2.0.0 release dependency to all "1.10.*" releases for a product with a pipeline similar to the following: 56 | 57 | ```sh 58 | $ pivnet --format=json releases --product-slug=MY_PRODUCT_SLUG | jq -r '.[].version' | grep '^1\.10\.' | xargs -I{} pivnet add-release-dependency --product-slug=MY_PRODUCT_SLUG --release-version={} --dependent-product-slug=elastic-runtime --dependent-release-version=2.0.0 59 | ``` 60 | 61 | -------------------------------------------------------------------------------- /docs/content/index.md: -------------------------------------------------------------------------------- 1 | # Pivnet CLI 2 | 3 | Interact with [Pivotal Network](https://network.tanzu.vmware.com) from the command-line. 4 | -------------------------------------------------------------------------------- /docs/content/installation/installing-the-cli.md: -------------------------------------------------------------------------------- 1 | # Installing The CLI 2 | 3 | Binaries for various operating systems are provided with each release on the 4 | [releases page](https://github.com/pivotal-cf/pivnet-cli/releases). 5 | 6 | Install for OSX via [homebrew](http://brew.sh/) as follows: 7 | 8 | ```sh 9 | brew install pivotal/tap/pivnet-cli 10 | ``` 11 | 12 | To install on linux, download the latest binary 13 | (see [latest release](https://github.com/pivotal-cf/pivnet-cli/releases/latest)) 14 | and ensure the file is executable and on the path. 15 | -------------------------------------------------------------------------------- /docs/content/reference/accept-eula.md: -------------------------------------------------------------------------------- 1 | # Accept EULA (aliases: ae) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] accept-eula [accept-eula-OPTIONS] 6 | 7 | Note: 8 | Available to select users only. Some users may be required to accept the EULA through the provided link 9 | 10 | Application Options: 11 | -v, --version Print the version of this CLI and exit 12 | --format=[table|json|yaml] Format to print as (default: table) 13 | --verbose Display verbose output 14 | --profile= Name of profile (default: default) 15 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 16 | 17 | Help Options: 18 | -h, --help Show this help message 19 | 20 | [accept-eula command options] 21 | -p, --product-slug= Product slug e.g. p-mysql 22 | -r, --release-version= Release version e.g. 0.1.2-rc1 23 | 24 | ``` 25 | -------------------------------------------------------------------------------- /docs/content/reference/add-file-group.md: -------------------------------------------------------------------------------- 1 | # Add file group to release (aliases: afg) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] add-file-group [add-file-group-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [add-file-group command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -i, --file-group-id= Filegroup ID e.g. 1234 20 | -r, --release-version= Release version e.g. 0.1.2-rc1 21 | 22 | ``` 23 | -------------------------------------------------------------------------------- /docs/content/reference/add-product-file.md: -------------------------------------------------------------------------------- 1 | # Add product file to release (aliases: apf) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] add-product-file [add-product-file-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [add-product-file command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | -i, --product-file-id= Product file ID e.g. 1234 21 | -f, --file-group-id= File group ID e.g. 1234 22 | 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/content/reference/add-release-dependency.md: -------------------------------------------------------------------------------- 1 | # Add release dependency (aliases: ard) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] add-release-dependency [add-release-dependency-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [add-release-dependency command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | -s, --dependent-product-slug= Dependent product slug e.g. p-mysql 21 | -u, --dependent-release-version= Dependent release version e.g. 0.1.2-rc1 22 | 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/content/reference/add-release-upgrade-path.md: -------------------------------------------------------------------------------- 1 | # Add release upgrade path (aliases: arup) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] add-release-upgrade-path [add-release-upgrade-path-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [add-release-upgrade-path command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | -u, --previous-release-version= Regex for previous release version e.g. 0.1.* 21 | 22 | ``` 23 | -------------------------------------------------------------------------------- /docs/content/reference/add-user-group-member.md: -------------------------------------------------------------------------------- 1 | # Add user group member to group (aliases: augm) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] add-user-group-member [add-user-group-member-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [add-user-group-member command options] 18 | -i, --user-group-id= User group ID e.g. 1234 19 | --member-email= Member email address e.g. 1234 20 | --admin Whether the user should be an admin 21 | 22 | ``` 23 | -------------------------------------------------------------------------------- /docs/content/reference/add-user-group.md: -------------------------------------------------------------------------------- 1 | # Add user group to release (aliases: aug) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] add-user-group [add-user-group-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [add-user-group command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | -i, --user-group-id= User Group ID e.g. 1234 21 | 22 | ``` 23 | -------------------------------------------------------------------------------- /docs/content/reference/create-dependency-specifier.md: -------------------------------------------------------------------------------- 1 | # Create dependency specifier (aliases: cds) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] create-dependency-specifier [create-dependency-specifier-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [create-dependency-specifier command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | -s, --dependent-product-slug= Dependent product slug e.g. p-mysql 21 | -u, --specifier= Specifier e.g. 1.2.* 22 | 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/content/reference/create-file-group.md: -------------------------------------------------------------------------------- 1 | # Create file group (aliases: cfg) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] create-file-group [create-file-group-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [create-file-group command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | --name= Name e.g. my_file_group 20 | 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/content/reference/create-product-file.md: -------------------------------------------------------------------------------- 1 | # Create product file (aliases: cpf) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] create-product-file [create-product-file-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [create-product-file command options] 18 | -p, --product-slug= Product slug e.g. 'p-mysql' 19 | --name= Name e.g. 'p-mysql 1.7.13' 20 | --aws-object-key= AWS Object Key e.g. 'product_files/P-MySQL/p-mysql-1.7.13.pivotal' 21 | --file-type= File Type e.g. 'Software' 22 | --file-version= File Version e.g. '1.7.13' 23 | --md5= MD5 of file 24 | --description= Description of file 25 | --docs-url= URL of docs for file 26 | --included-file= Name of included file 27 | --platform= Platform of file 28 | --released-at= When file is marked for release e.g. '2016/01/16' 29 | --system-requirement= System-requirement of file 30 | 31 | ``` 32 | -------------------------------------------------------------------------------- /docs/content/reference/create-release.md: -------------------------------------------------------------------------------- 1 | # Create release (aliases: cr) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] create-release [create-release-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [create-release command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | -t, --release-type= Release type e.g. 'Minor Release' 21 | -e, --eula-slug= EULA slug e.g. pivotal_software_eula 22 | 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/content/reference/create-user-group.md: -------------------------------------------------------------------------------- 1 | # Create user group (aliases: cug) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] create-user-group [create-user-group-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [create-user-group command options] 18 | --name= Name e.g. all_users 19 | --description= Description e.g. 'All users in the world' 20 | --member= Email addresses of members to be added 21 | 22 | ``` 23 | -------------------------------------------------------------------------------- /docs/content/reference/curl.md: -------------------------------------------------------------------------------- 1 | # Curl an endpoint (aliases: c) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] curl [curl-OPTIONS] URL 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [curl command options] 18 | -X, --request= Custom method e.g. PATCH 19 | -d, --data= Request data e.g. '{"foo":"bar"}' 20 | 21 | [curl command arguments] 22 | URL: URL without host or API prefix e.g. /products/p-mysql/releases/3451 23 | 24 | ``` 25 | -------------------------------------------------------------------------------- /docs/content/reference/delete-dependency-specifier.md: -------------------------------------------------------------------------------- 1 | # Delete dependency specifier (aliases: dds) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] delete-dependency-specifier [delete-dependency-specifier-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [delete-dependency-specifier command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | -i, --dependency-specifier-id= Dependency specifier ID e.g. 1234 21 | 22 | ``` 23 | -------------------------------------------------------------------------------- /docs/content/reference/delete-file-group.md: -------------------------------------------------------------------------------- 1 | # Delete file group (aliases: dfg) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] delete-file-group [delete-file-group-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [delete-file-group command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -i, --file-group-id= File group ID e.g. 1234 20 | 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/content/reference/delete-product-file.md: -------------------------------------------------------------------------------- 1 | # Delete product file (aliases: dpf) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] delete-product-file [delete-product-file-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [delete-product-file command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -i, --product-file-id= Product file ID e.g. 1234 20 | 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/content/reference/delete-release.md: -------------------------------------------------------------------------------- 1 | # Delete release (aliases: dr) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] delete-release [delete-release-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [delete-release command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/content/reference/delete-user-group.md: -------------------------------------------------------------------------------- 1 | # Delete user group (aliases: dug) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] delete-user-group [delete-user-group-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [delete-user-group command options] 18 | -i, --user-group-id= User group ID e.g. 1234 19 | 20 | ``` 21 | -------------------------------------------------------------------------------- /docs/content/reference/dependency-specifier.md: -------------------------------------------------------------------------------- 1 | # Get dependency specifier (aliases: ds) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] dependency-specifier [dependency-specifier-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [dependency-specifier command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | -i, --dependency-specifier-id= Dependency specifier ID e.g. 1234 21 | 22 | ``` 23 | -------------------------------------------------------------------------------- /docs/content/reference/dependency-specifiers.md: -------------------------------------------------------------------------------- 1 | # List dependency specifiers (aliases: dss) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] dependency-specifiers [dependency-specifiers-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [dependency-specifiers command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/content/reference/download-product-files.md: -------------------------------------------------------------------------------- 1 | # Download product files (aliases: dlpf) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] download-product-files [download-product-files-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [download-product-files command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | -i, --product-file-id= Product file ID e.g. 1234 21 | -g, --glob= Glob to match product name e.g. *aws* 22 | -d, --download-dir= Local existing directory to download files to e.g. /tmp/my-file/ (default: .) 23 | --accept-eula Automatically accept EULA if necessary (available to pivots only) 24 | 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/content/reference/eula.md: -------------------------------------------------------------------------------- 1 | # Show EULA (aliases: e) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] eula [eula-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [eula command options] 18 | --eula-slug= EULA slug e.g. pivotal_software_eula 19 | 20 | ``` 21 | -------------------------------------------------------------------------------- /docs/content/reference/eulas.md: -------------------------------------------------------------------------------- 1 | # List EULAs (aliases: es) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] eulas 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | ``` 18 | -------------------------------------------------------------------------------- /docs/content/reference/file-group.md: -------------------------------------------------------------------------------- 1 | # Show file group (aliases: fg) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] file-group [file-group-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [file-group command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -i, --file-group-id= Filegroup ID e.g. 1234 20 | 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/content/reference/file-groups.md: -------------------------------------------------------------------------------- 1 | # List file groups (aliases: fgs) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] file-groups [file-groups-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [file-groups command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/content/reference/login.md: -------------------------------------------------------------------------------- 1 | # Log in to Pivotal Network. (aliases: l) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] login [login-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [login command options] 18 | --api-token= Pivnet API Token (Pivnet legacy token or UAA refresh token) 19 | --host= Pivnet API Host (default: https://network.tanzu.vmware.com) 20 | 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/content/reference/logout.md: -------------------------------------------------------------------------------- 1 | # Log out from Pivotal Network. 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] logout 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | ``` 18 | -------------------------------------------------------------------------------- /docs/content/reference/product-file.md: -------------------------------------------------------------------------------- 1 | # Show product file (aliases: pf) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] product-file [product-file-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [product-file command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | -i, --product-file-id= Product file ID e.g. 1234 21 | 22 | ``` 23 | -------------------------------------------------------------------------------- /docs/content/reference/product-files.md: -------------------------------------------------------------------------------- 1 | # List product files (aliases: pfs) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] product-files [product-files-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [product-files command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/content/reference/product.md: -------------------------------------------------------------------------------- 1 | # Show product (aliases: p) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] product [product-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [product command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | 20 | ``` 21 | -------------------------------------------------------------------------------- /docs/content/reference/products.md: -------------------------------------------------------------------------------- 1 | # List products (aliases: ps) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] products 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | ``` 18 | -------------------------------------------------------------------------------- /docs/content/reference/release-dependencies.md: -------------------------------------------------------------------------------- 1 | # List release dependencies (aliases: rds) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] release-dependencies [release-dependencies-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [release-dependencies command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/content/reference/release-types.md: -------------------------------------------------------------------------------- 1 | # List release types (aliases: rts) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] release-types 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | ``` 18 | -------------------------------------------------------------------------------- /docs/content/reference/release-upgrade-paths.md: -------------------------------------------------------------------------------- 1 | # List release upgrade paths (aliases: rups) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] release-upgrade-paths [release-upgrade-paths-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [release-upgrade-paths command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/content/reference/release.md: -------------------------------------------------------------------------------- 1 | # Show release (aliases: r) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] release [release-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [release command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/content/reference/releases.md: -------------------------------------------------------------------------------- 1 | # List releases (aliases: rs) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] releases [releases-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [releases command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | 20 | ``` 21 | -------------------------------------------------------------------------------- /docs/content/reference/remove-file-group.md: -------------------------------------------------------------------------------- 1 | # Remove file group from release (aliases: rfg) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] remove-file-group [remove-file-group-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [remove-file-group command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -i, --file-group-id= Filegroup ID e.g. 1234 20 | -r, --release-version= Release version e.g. 0.1.2-rc1 21 | 22 | ``` 23 | -------------------------------------------------------------------------------- /docs/content/reference/remove-product-file.md: -------------------------------------------------------------------------------- 1 | # Remove product file from release (aliases: rpf) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] remove-product-file [remove-product-file-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [remove-product-file command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | -i, --product-file-id= Product file ID e.g. 1234 21 | -f, --file-group-id= File group ID e.g. 1234 22 | 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/content/reference/remove-release-dependency.md: -------------------------------------------------------------------------------- 1 | # Remove release dependency (aliases: rrd) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] remove-release-dependency [remove-release-dependency-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [remove-release-dependency command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | -s, --dependent-product-slug= Dependent product slug e.g. p-mysql 21 | -u, --dependent-release-version= Dependent release version e.g. 0.1.2-rc1 22 | 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/content/reference/remove-release-upgrade-path.md: -------------------------------------------------------------------------------- 1 | # Remove release upgrade path (aliases: rrup) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] remove-release-upgrade-path [remove-release-upgrade-path-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [remove-release-upgrade-path command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | -u, --previous-release-version= Regex for previous release version e.g. 0.1.* 21 | 22 | ``` 23 | -------------------------------------------------------------------------------- /docs/content/reference/remove-user-group-member.md: -------------------------------------------------------------------------------- 1 | # Remove user group member from group (aliases: rugm) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] remove-user-group-member [remove-user-group-member-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [remove-user-group-member command options] 18 | -i, --user-group-id= User group ID e.g. 1234 19 | --member-email= Member email address e.g. 1234 20 | 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/content/reference/remove-user-group.md: -------------------------------------------------------------------------------- 1 | # Remove user group from release (aliases: rug) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] remove-user-group [remove-user-group-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [remove-user-group command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | -i, --user-group-id= User Group ID e.g. 1234 21 | 22 | ``` 23 | -------------------------------------------------------------------------------- /docs/content/reference/update-file-group.md: -------------------------------------------------------------------------------- 1 | # Update file group (aliases: ufg) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] update-file-group [update-file-group-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [update-file-group command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -i, --file-group-id= Filegroup ID e.g. 1234 20 | --name= Name e.g. my_file_group 21 | 22 | ``` 23 | -------------------------------------------------------------------------------- /docs/content/reference/update-product-file.md: -------------------------------------------------------------------------------- 1 | # Update product file (aliases: upf) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] update-product-file [update-product-file-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [update-product-file command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -i, --product-file-id= Product file ID e.g. 1234 20 | --name= Name e.g. p-mysql 1.7.13 21 | --file-version= File Version e.g. '1.7.13' 22 | --md5= MD5 of file 23 | --description= File description e.g. 'This is a file description.' 24 | 25 | ``` 26 | -------------------------------------------------------------------------------- /docs/content/reference/update-release.md: -------------------------------------------------------------------------------- 1 | # Update release (aliases: ur) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] update-release [update-release-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [update-release command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | --availability=[admins|selected-user-groups|all] Release availability. Optional. 21 | --release-type=[all-in-one|major|minor|service|maintenance|security|alpha|beta|edge] Release type. Optional. 22 | 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/content/reference/update-user-group.md: -------------------------------------------------------------------------------- 1 | # Update user group (aliases: uug) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] update-user-group [update-user-group-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [update-user-group command options] 18 | -i, --user-group-id= User group ID e.g. 1234 19 | --name= Name e.g. all_users 20 | --description= Description e.g. 'All users in the world' 21 | 22 | ``` 23 | -------------------------------------------------------------------------------- /docs/content/reference/user-group.md: -------------------------------------------------------------------------------- 1 | # Show user group (aliases: ug) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] user-group [user-group-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [user-group command options] 18 | -i, --user-group-id= User group ID e.g. 1234 19 | 20 | ``` 21 | -------------------------------------------------------------------------------- /docs/content/reference/user-groups.md: -------------------------------------------------------------------------------- 1 | # List user groups (aliases: ugs) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] user-groups [user-groups-OPTIONS] 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | [user-groups command options] 18 | -p, --product-slug= Product slug e.g. p-mysql 19 | -r, --release-version= Release version e.g. 0.1.2-rc1 20 | 21 | ``` 22 | -------------------------------------------------------------------------------- /docs/content/reference/version.md: -------------------------------------------------------------------------------- 1 | # Print the version of this CLI and exit (aliases: v) 2 | 3 | ``` 4 | Usage: 5 | pivnet [OPTIONS] version 6 | 7 | Application Options: 8 | -v, --version Print the version of this CLI and exit 9 | --format=[table|json|yaml] Format to print as (default: table) 10 | --verbose Display verbose output 11 | --profile= Name of profile (default: default) 12 | --config= Path to config file (default: /Users/pivotal/.pivnetrc) 13 | 14 | Help Options: 15 | -h, --help Show this help message 16 | 17 | ``` 18 | -------------------------------------------------------------------------------- /docs/readme.md: -------------------------------------------------------------------------------- 1 | ### Development 2 | 3 | For local development, use the following Docker command to build docs and preview on localhost:8000: 4 | 5 | `$ docker run --rm -it -p 8000:8000 -v "${PWD}:/docs" squidfunk/mkdocs-material:2.7.2` 6 | 7 | 8 | For building the site in the `site` folder, use the following Docker command: 9 | 10 | `$ docker run --rm -it -v "${PWD}:/docs" squidfunk/mkdocs-material:2.7.2 build` 11 | 12 | 13 | For publishing the site in the `site` folder, use the following command (prerequisite: `npm install -g gh-pages`): 14 | 15 | `gh-pages -d site --message 'Auto-generated commit [#157322604]'` 16 | -------------------------------------------------------------------------------- /docs/theme/material/404.html: -------------------------------------------------------------------------------- 1 | {% extends "base.html" %} 2 | {% block content %} 3 |