diff --git a/cmd/plural/clusters.go b/cmd/plural/clusters.go new file mode 100644 index 00000000..2553d9ea --- /dev/null +++ b/cmd/plural/clusters.go @@ -0,0 +1,133 @@ +package main + +import ( + "fmt" + + "github.com/pluralsh/plural/pkg/api" + "github.com/pluralsh/plural/pkg/manifest" + "github.com/pluralsh/plural/pkg/utils" + "github.com/urfave/cli" +) + +func (p *Plural) clusterCommands() []cli.Command { + return []cli.Command{ + { + Name: "list", + Usage: "lists clusters accessible to your user", + Action: latestVersion(p.listClusters), + }, + { + Name: "view", + Usage: "shows info for a cluster", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "id", + Usage: "the id of the source cluster", + }, + }, + Action: latestVersion(p.showCluster), + }, + { + Name: "depend", + Usage: "have a cluster wait for promotion on another cluster", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "source-id", + Usage: "the id of the source cluster", + }, + cli.StringFlag{ + Name: "dest-id", + Usage: "the id of the cluster waiting for promotion", + }, + }, + Action: latestVersion(p.dependCluster), + }, + { + Name: "promote", + Usage: "promote pending upgrades to your cluster", + Action: latestVersion(p.promoteCluster), + }, + } +} + +func (p *Plural) listClusters(c *cli.Context) error { + p.InitPluralClient() + clusters, err := p.Client.Clusters() + if err != nil { + return err + } + + headers := []string{"ID", "Name", "Provider", "Git Url", "Owner"} + return utils.PrintTable(clusters, headers, func(c *api.Cluster) ([]string, error) { + return []string{c.Id, c.Name, c.Provider, c.GitUrl, c.Owner.Email}, nil + }) +} + +func (p *Plural) showCluster(c *cli.Context) error { + p.InitPluralClient() + id := c.String("id") + if id == "" { + clusters, err := p.Client.Clusters() + if err != nil { + return err + } + + project, err := manifest.FetchProject() + if err != nil { + return err + } + for _, cluster := range clusters { + if cluster.Name == project.Cluster && cluster.Owner.Email == project.Owner.Email { + id = cluster.Id + break + } + } + } + cluster, err := p.Client.Cluster(id) + if err != nil { + return err + } + + fmt.Printf("Cluster %s:\n\n", cluster.Id) + + utils.PrintAttributes(map[string]string{ + "Id": cluster.Id, + "Name": cluster.Name, + "Provider": cluster.Provider, + "Git Url": cluster.GitUrl, + "Owner": cluster.Owner.Email, + }) + + fmt.Println("") + if len(cluster.UpgradeInfo) > 0 { + fmt.Printf("Pending Upgrades:\n\n") + headers := []string{"Repository", "Count"} + return utils.PrintTable(cluster.UpgradeInfo, headers, func(c *api.UpgradeInfo) ([]string, error) { + return []string{c.Installation.Repository.Name, fmt.Sprintf("%d", c.Count)}, nil + }) + } + + fmt.Println("No pending upgrades") + return nil +} + +func (p *Plural) dependCluster(c *cli.Context) error { + p.InitPluralClient() + source, dest := c.String("source-id"), c.String("dest-id") + if err := p.Client.CreateDependency(source, dest); err != nil { + return err + } + + utils.Highlight("Cluster %s will now delegate upgrades to %s", dest, source) + return nil +} + +func (p *Plural) promoteCluster(c *cli.Context) error { + p.InitPluralClient() + if err := p.Client.PromoteCluster(); err != nil { + return err + } + + utils.Success("Upgrades promoted!") + return nil +} diff --git a/cmd/plural/plural.go b/cmd/plural/plural.go index 3539b330..2bb8a662 100644 --- a/cmd/plural/plural.go +++ b/cmd/plural/plural.go @@ -306,6 +306,11 @@ func (p *Plural) getCommands() []cli.Command { Subcommands: shellCommands(), Category: "Workspace", }, + { + Name: "clusters", + Usage: "commands related to managing plural clusters", + Subcommands: p.clusterCommands(), + }, { Name: "repos", Usage: "view and manage plural repositories", diff --git a/go.mod b/go.mod index 0f6bfa5f..f8670ef6 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,7 @@ require ( github.com/olekukonko/tablewriter v0.0.5 github.com/packethost/packngo v0.29.0 github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 - github.com/pluralsh/gqlclient v1.3.9 + github.com/pluralsh/gqlclient v1.3.10 github.com/pluralsh/plural-operator v0.5.3 github.com/pluralsh/polly v0.0.6 github.com/rodaine/hclencoder v0.0.1 @@ -55,7 +55,7 @@ require ( github.com/yuin/gopher-lua v0.0.0-20220504180219-658193537a64 go.mercari.io/hcledit v0.0.8 golang.org/x/crypto v0.5.0 - golang.org/x/mod v0.6.0 + golang.org/x/mod v0.9.0 golang.org/x/oauth2 v0.5.0 gopkg.in/yaml.v2 v2.4.0 helm.sh/helm/v3 v3.11.0 @@ -250,9 +250,9 @@ require ( go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect golang.org/x/net v0.6.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.5.0 // indirect + golang.org/x/sys v0.6.0 // indirect golang.org/x/term v0.5.0 - golang.org/x/text v0.7.0 + golang.org/x/text v0.8.0 golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/api v0.110.0 diff --git a/go.sum b/go.sum index 270dabcf..09212d17 100644 --- a/go.sum +++ b/go.sum @@ -897,8 +897,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pluralsh/controller-reconcile-helper v0.0.4 h1:1o+7qYSyoeqKFjx+WgQTxDz4Q2VMpzprJIIKShxqG0E= github.com/pluralsh/controller-reconcile-helper v0.0.4/go.mod h1:AfY0gtteD6veBjmB6jiRx/aR4yevEf6K0M13/pGan/s= -github.com/pluralsh/gqlclient v1.3.9 h1:cJ6Vu+N1pI5z46JS2o13fh4Oc9CbnTljwu3HTTQCPN8= -github.com/pluralsh/gqlclient v1.3.9/go.mod h1:VHjVCSOaD9lzOI3u7tOuaQY7vrLdiAKPSbeihaWYX28= +github.com/pluralsh/gqlclient v1.3.10 h1:B5Rd4cjAfTllMc4oPMR/PEebxdVb0gIyPm+VT3lvzEM= +github.com/pluralsh/gqlclient v1.3.10/go.mod h1:z1qHnvPeqIN/a+5OzFs40e6HI6tDxzh1+yJuEpvqGy4= github.com/pluralsh/oauth v0.9.2 h1:tM9hBK4tCnJUeCOgX0ctxBBCS3hiCDPoxkJLODtedmQ= github.com/pluralsh/oauth v0.9.2/go.mod h1:aTUw/75rzcsbvW+/TLvWtHVDXFIdtFrDtUncOq9vHyM= github.com/pluralsh/plural-operator v0.5.3 h1:GaPL3LgimfzKZNHt7zXzqYZpb0hgyW9noHYnkA+rqNs= @@ -1190,8 +1190,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= -golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180112015858-5ccada7d0a7b/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1375,8 +1375,8 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1395,8 +1395,8 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= -golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/pkg/api/client.go b/pkg/api/client.go index ba75c725..c3259897 100644 --- a/pkg/api/client.go +++ b/pkg/api/client.go @@ -79,6 +79,10 @@ type Client interface { ListKeyBackups() ([]*KeyBackup, error) GetHelp(prompt string) (string, error) DestroyCluster(domain, name, provider string) error + CreateDependency(source, dest string) error + PromoteCluster() error + Clusters() ([]*Cluster, error) + Cluster(id string) (*Cluster, error) } type client struct { diff --git a/pkg/api/cluster.go b/pkg/api/cluster.go index cf956a18..7e896de8 100644 --- a/pkg/api/cluster.go +++ b/pkg/api/cluster.go @@ -2,6 +2,7 @@ package api import ( "github.com/pluralsh/gqlclient" + "github.com/samber/lo" ) func (client *client) DestroyCluster(domain, name, provider string) error { @@ -12,3 +13,69 @@ func (client *client) DestroyCluster(domain, name, provider string) error { return nil } + +func (client *client) CreateDependency(source, dest string) error { + _, err := client.pluralClient.CreateDependency(client.ctx, source, dest) + return err +} + +func (client *client) PromoteCluster() error { + _, err := client.pluralClient.PromoteCluster(client.ctx) + return err +} + +func (client *client) Clusters() ([]*Cluster, error) { + resp, err := client.pluralClient.Clusters(client.ctx, nil) + if err != nil { + return nil, err + } + clusters := make([]*Cluster, 0) + for _, edge := range resp.Clusters.Edges { + node := edge.Node + clusters = append(clusters, &Cluster{ + Id: node.ID, + Name: node.Name, + Provider: string(node.Provider), + GitUrl: lo.FromPtr(node.GitURL), + Owner: &User{ + Id: node.Owner.ID, + Name: node.Owner.Name, + Email: node.Owner.Email, + }, + }) + } + + return clusters, nil +} + +func (client *client) Cluster(id string) (*Cluster, error) { + resp, err := client.pluralClient.ClusterInfo(client.ctx, id) + if err != nil { + return nil, err + } + + node := resp.Cluster + upgradeInfo := make([]*UpgradeInfo, 0) + for _, info := range node.UpgradeInfo { + upgradeInfo = append(upgradeInfo, &UpgradeInfo{ + Count: lo.FromPtr(info.Count), + Installation: &Installation{ + Repository: convertRepository(info.Installation.Repository), + }, + }) + } + + cluster := &Cluster{ + Id: node.ID, + Name: node.Name, + Provider: string(node.Provider), + GitUrl: lo.FromPtr(node.GitURL), + Owner: &User{ + Id: node.Owner.ID, + Name: node.Owner.Name, + Email: node.Owner.Email, + }, + UpgradeInfo: upgradeInfo, + } + return cluster, nil +} diff --git a/pkg/api/models.go b/pkg/api/models.go index 06d6f7f4..196474c9 100644 --- a/pkg/api/models.go +++ b/pkg/api/models.go @@ -332,6 +332,21 @@ type KeyBackup struct { InsertedAt string } +type Cluster struct { + Id string + Name string + Provider string + UpgradeInfo []*UpgradeInfo + Source string + GitUrl string + Owner *User +} + +type UpgradeInfo struct { + Count int64 + Installation *Installation +} + const CrdFragment = ` fragment CrdFragment on Crd { id diff --git a/pkg/api/recipes.go b/pkg/api/recipes.go index 35494c42..f55e3d08 100644 --- a/pkg/api/recipes.go +++ b/pkg/api/recipes.go @@ -14,6 +14,7 @@ type RecipeInput struct { Description string Provider string Restricted bool + Primary bool Tests []RecipeTestInput `yaml:"tests" json:"tests,omitempty"` Sections []RecipeSectionInput Dependencies []DependencyInput diff --git a/pkg/api/repos.go b/pkg/api/repos.go index 5612f386..bdd5d945 100644 --- a/pkg/api/repos.go +++ b/pkg/api/repos.go @@ -76,17 +76,21 @@ func (client *client) GetRepository(repo string) (*Repository, error) { return nil, err } + return convertRepository(resp.Repository), nil +} + +func convertRepository(repo *gqlclient.RepositoryFragment) *Repository { return &Repository{ - Id: resp.Repository.ID, - Name: resp.Repository.Name, - Description: utils.ConvertStringPointer(resp.Repository.Description), - Icon: utils.ConvertStringPointer(resp.Repository.Icon), - DarkIcon: utils.ConvertStringPointer(resp.Repository.DarkIcon), - Notes: utils.ConvertStringPointer(resp.Repository.Notes), + Id: repo.ID, + Name: repo.Name, + Description: utils.ConvertStringPointer(repo.Description), + Icon: utils.ConvertStringPointer(repo.Icon), + DarkIcon: utils.ConvertStringPointer(repo.DarkIcon), + Notes: utils.ConvertStringPointer(repo.Notes), Publisher: &Publisher{ - Name: resp.Repository.Publisher.Name, + Name: repo.Publisher.Name, }, - }, nil + } } func (client *client) CreateRepository(name, publisher string, input *gqlclient.RepositoryAttributes) error { diff --git a/pkg/bundle/configuration.go b/pkg/bundle/configuration.go index 154c4779..fc029a44 100644 --- a/pkg/bundle/configuration.go +++ b/pkg/bundle/configuration.go @@ -178,11 +178,15 @@ func Configure(ctx map[string]interface{}, item *api.ConfigurationItem, context if value := getEnvVar(repo, item.Name); value != "" { res = value } else { - prompt, opts := fileSurvey(def) + prompt, opts := fileSurvey(def, item) if err := survey.AskOne(prompt, &res, opts...); err != nil { return err } } + if res == "" { + return + } + path, err := homedir.Expand(res) if err != nil { return err diff --git a/pkg/bundle/surveys.go b/pkg/bundle/surveys.go index c9308e15..64a42750 100644 --- a/pkg/bundle/surveys.go +++ b/pkg/bundle/surveys.go @@ -87,8 +87,13 @@ func domainSurvey(def string, item *api.ConfigurationItem, proj *manifest.Projec return &survey.Input{Message: msg, Default: def}, opts } -func fileSurvey(def string) (survey.Prompt, []survey.AskOpt) { - return &survey.Input{ +func fileSurvey(def string, item *api.ConfigurationItem) (prompt survey.Prompt, opts []survey.AskOpt) { + opts = []survey.AskOpt{} + if !item.Optional { + opts = append(opts, survey.WithValidator(survey.Required)) + } + + prompt = &survey.Input{ Message: "select a file (use tab to list files in the directory):", Default: def, Suggest: func(toComplete string) []string { @@ -99,7 +104,8 @@ func fileSurvey(def string) (survey.Prompt, []survey.AskOpt) { files, _ := filepath.Glob(cleanPath(path) + "*") return files }, - }, []survey.AskOpt{survey.WithValidator(survey.Required)} + } + return } func cleanPath(path string) string { diff --git a/pkg/test/mocks/Client.go b/pkg/test/mocks/Client.go index dd5d3491..28700bd2 100644 --- a/pkg/test/mocks/Client.go +++ b/pkg/test/mocks/Client.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.18.0. DO NOT EDIT. +// Code generated by mockery v2.21.4. DO NOT EDIT. package mocks @@ -19,6 +19,10 @@ func (_m *Client) AcquireLock(repo string) (*api.ApplyLock, error) { ret := _m.Called(repo) var r0 *api.ApplyLock + var r1 error + if rf, ok := ret.Get(0).(func(string) (*api.ApplyLock, error)); ok { + return rf(repo) + } if rf, ok := ret.Get(0).(func(string) *api.ApplyLock); ok { r0 = rf(repo) } else { @@ -27,7 +31,6 @@ func (_m *Client) AcquireLock(repo string) (*api.ApplyLock, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(repo) } else { @@ -37,18 +40,73 @@ func (_m *Client) AcquireLock(repo string) (*api.ApplyLock, error) { return r0, r1 } +// Cluster provides a mock function with given fields: id +func (_m *Client) Cluster(id string) (*api.Cluster, error) { + ret := _m.Called(id) + + var r0 *api.Cluster + var r1 error + if rf, ok := ret.Get(0).(func(string) (*api.Cluster, error)); ok { + return rf(id) + } + if rf, ok := ret.Get(0).(func(string) *api.Cluster); ok { + r0 = rf(id) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*api.Cluster) + } + } + + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(id) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Clusters provides a mock function with given fields: +func (_m *Client) Clusters() ([]*api.Cluster, error) { + ret := _m.Called() + + var r0 []*api.Cluster + var r1 error + if rf, ok := ret.Get(0).(func() ([]*api.Cluster, error)); ok { + return rf() + } + if rf, ok := ret.Get(0).(func() []*api.Cluster); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*api.Cluster) + } + } + + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // CreateAccessToken provides a mock function with given fields: func (_m *Client) CreateAccessToken() (string, error) { ret := _m.Called() var r0 string + var r1 error + if rf, ok := ret.Get(0).(func() (string, error)); ok { + return rf() + } if rf, ok := ret.Get(0).(func() string); ok { r0 = rf() } else { r0 = ret.Get(0).(string) } - var r1 error if rf, ok := ret.Get(1).(func() error); ok { r1 = rf() } else { @@ -63,13 +121,16 @@ func (_m *Client) CreateArtifact(repo string, attrs api.ArtifactAttributes) (api ret := _m.Called(repo, attrs) var r0 api.Artifact + var r1 error + if rf, ok := ret.Get(0).(func(string, api.ArtifactAttributes) (api.Artifact, error)); ok { + return rf(repo, attrs) + } if rf, ok := ret.Get(0).(func(string, api.ArtifactAttributes) api.Artifact); ok { r0 = rf(repo, attrs) } else { r0 = ret.Get(0).(api.Artifact) } - var r1 error if rf, ok := ret.Get(1).(func(string, api.ArtifactAttributes) error); ok { r1 = rf(repo, attrs) } else { @@ -93,6 +154,20 @@ func (_m *Client) CreateCrd(repo string, chart string, file string) error { return r0 } +// CreateDependency provides a mock function with given fields: source, dest +func (_m *Client) CreateDependency(source string, dest string) error { + ret := _m.Called(source, dest) + + var r0 error + if rf, ok := ret.Get(0).(func(string, string) error); ok { + r0 = rf(source, dest) + } else { + r0 = ret.Error(0) + } + + return r0 +} + // CreateDomain provides a mock function with given fields: name func (_m *Client) CreateDomain(name string) error { ret := _m.Called(name) @@ -154,13 +229,16 @@ func (_m *Client) CreateRecipe(repoName string, attrs gqlclient.RecipeAttributes ret := _m.Called(repoName, attrs) var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string, gqlclient.RecipeAttributes) (string, error)); ok { + return rf(repoName, attrs) + } if rf, ok := ret.Get(0).(func(string, gqlclient.RecipeAttributes) string); ok { r0 = rf(repoName, attrs) } else { r0 = ret.Get(0).(string) } - var r1 error if rf, ok := ret.Get(1).(func(string, gqlclient.RecipeAttributes) error); ok { r1 = rf(repoName, attrs) } else { @@ -189,13 +267,16 @@ func (_m *Client) CreateStack(attributes gqlclient.StackAttributes) (string, err ret := _m.Called(attributes) var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(gqlclient.StackAttributes) (string, error)); ok { + return rf(attributes) + } if rf, ok := ret.Get(0).(func(gqlclient.StackAttributes) string); ok { r0 = rf(attributes) } else { r0 = ret.Get(0).(string) } - var r1 error if rf, ok := ret.Get(1).(func(gqlclient.StackAttributes) error); ok { r1 = rf(attributes) } else { @@ -266,6 +347,10 @@ func (_m *Client) DeviceLogin() (*api.DeviceLogin, error) { ret := _m.Called() var r0 *api.DeviceLogin + var r1 error + if rf, ok := ret.Get(0).(func() (*api.DeviceLogin, error)); ok { + return rf() + } if rf, ok := ret.Get(0).(func() *api.DeviceLogin); ok { r0 = rf() } else { @@ -274,7 +359,6 @@ func (_m *Client) DeviceLogin() (*api.DeviceLogin, error) { } } - var r1 error if rf, ok := ret.Get(1).(func() error); ok { r1 = rf() } else { @@ -289,6 +373,10 @@ func (_m *Client) GetChartInstallations(repoId string) ([]*api.ChartInstallation ret := _m.Called(repoId) var r0 []*api.ChartInstallation + var r1 error + if rf, ok := ret.Get(0).(func(string) ([]*api.ChartInstallation, error)); ok { + return rf(repoId) + } if rf, ok := ret.Get(0).(func(string) []*api.ChartInstallation); ok { r0 = rf(repoId) } else { @@ -297,7 +385,6 @@ func (_m *Client) GetChartInstallations(repoId string) ([]*api.ChartInstallation } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(repoId) } else { @@ -312,6 +399,10 @@ func (_m *Client) GetCharts(repoId string) ([]*api.Chart, error) { ret := _m.Called(repoId) var r0 []*api.Chart + var r1 error + if rf, ok := ret.Get(0).(func(string) ([]*api.Chart, error)); ok { + return rf(repoId) + } if rf, ok := ret.Get(0).(func(string) []*api.Chart); ok { r0 = rf(repoId) } else { @@ -320,7 +411,6 @@ func (_m *Client) GetCharts(repoId string) ([]*api.Chart, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(repoId) } else { @@ -335,6 +425,10 @@ func (_m *Client) GetEabCredential(cluster string, provider string) (*api.EabCre ret := _m.Called(cluster, provider) var r0 *api.EabCredential + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (*api.EabCredential, error)); ok { + return rf(cluster, provider) + } if rf, ok := ret.Get(0).(func(string, string) *api.EabCredential); ok { r0 = rf(cluster, provider) } else { @@ -343,7 +437,6 @@ func (_m *Client) GetEabCredential(cluster string, provider string) (*api.EabCre } } - var r1 error if rf, ok := ret.Get(1).(func(string, string) error); ok { r1 = rf(cluster, provider) } else { @@ -358,13 +451,16 @@ func (_m *Client) GetHelp(prompt string) (string, error) { ret := _m.Called(prompt) var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string) (string, error)); ok { + return rf(prompt) + } if rf, ok := ret.Get(0).(func(string) string); ok { r0 = rf(prompt) } else { r0 = ret.Get(0).(string) } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(prompt) } else { @@ -379,6 +475,10 @@ func (_m *Client) GetInstallation(name string) (*api.Installation, error) { ret := _m.Called(name) var r0 *api.Installation + var r1 error + if rf, ok := ret.Get(0).(func(string) (*api.Installation, error)); ok { + return rf(name) + } if rf, ok := ret.Get(0).(func(string) *api.Installation); ok { r0 = rf(name) } else { @@ -387,7 +487,6 @@ func (_m *Client) GetInstallation(name string) (*api.Installation, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(name) } else { @@ -402,6 +501,10 @@ func (_m *Client) GetInstallationById(id string) (*api.Installation, error) { ret := _m.Called(id) var r0 *api.Installation + var r1 error + if rf, ok := ret.Get(0).(func(string) (*api.Installation, error)); ok { + return rf(id) + } if rf, ok := ret.Get(0).(func(string) *api.Installation); ok { r0 = rf(id) } else { @@ -410,7 +513,6 @@ func (_m *Client) GetInstallationById(id string) (*api.Installation, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(id) } else { @@ -425,6 +527,10 @@ func (_m *Client) GetInstallations() ([]*api.Installation, error) { ret := _m.Called() var r0 []*api.Installation + var r1 error + if rf, ok := ret.Get(0).(func() ([]*api.Installation, error)); ok { + return rf() + } if rf, ok := ret.Get(0).(func() []*api.Installation); ok { r0 = rf() } else { @@ -433,7 +539,6 @@ func (_m *Client) GetInstallations() ([]*api.Installation, error) { } } - var r1 error if rf, ok := ret.Get(1).(func() error); ok { r1 = rf() } else { @@ -448,6 +553,10 @@ func (_m *Client) GetKeyBackup(name string) (*api.KeyBackup, error) { ret := _m.Called(name) var r0 *api.KeyBackup + var r1 error + if rf, ok := ret.Get(0).(func(string) (*api.KeyBackup, error)); ok { + return rf(name) + } if rf, ok := ret.Get(0).(func(string) *api.KeyBackup); ok { r0 = rf(name) } else { @@ -456,7 +565,6 @@ func (_m *Client) GetKeyBackup(name string) (*api.KeyBackup, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(name) } else { @@ -471,6 +579,11 @@ func (_m *Client) GetPackageInstallations(repoId string) ([]*api.ChartInstallati ret := _m.Called(repoId) var r0 []*api.ChartInstallation + var r1 []*api.TerraformInstallation + var r2 error + if rf, ok := ret.Get(0).(func(string) ([]*api.ChartInstallation, []*api.TerraformInstallation, error)); ok { + return rf(repoId) + } if rf, ok := ret.Get(0).(func(string) []*api.ChartInstallation); ok { r0 = rf(repoId) } else { @@ -479,7 +592,6 @@ func (_m *Client) GetPackageInstallations(repoId string) ([]*api.ChartInstallati } } - var r1 []*api.TerraformInstallation if rf, ok := ret.Get(1).(func(string) []*api.TerraformInstallation); ok { r1 = rf(repoId) } else { @@ -488,7 +600,6 @@ func (_m *Client) GetPackageInstallations(repoId string) ([]*api.ChartInstallati } } - var r2 error if rf, ok := ret.Get(2).(func(string) error); ok { r2 = rf(repoId) } else { @@ -503,6 +614,10 @@ func (_m *Client) GetRecipe(repo string, name string) (*api.Recipe, error) { ret := _m.Called(repo, name) var r0 *api.Recipe + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (*api.Recipe, error)); ok { + return rf(repo, name) + } if rf, ok := ret.Get(0).(func(string, string) *api.Recipe); ok { r0 = rf(repo, name) } else { @@ -511,7 +626,6 @@ func (_m *Client) GetRecipe(repo string, name string) (*api.Recipe, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string, string) error); ok { r1 = rf(repo, name) } else { @@ -526,6 +640,10 @@ func (_m *Client) GetRepository(repo string) (*api.Repository, error) { ret := _m.Called(repo) var r0 *api.Repository + var r1 error + if rf, ok := ret.Get(0).(func(string) (*api.Repository, error)); ok { + return rf(repo) + } if rf, ok := ret.Get(0).(func(string) *api.Repository); ok { r0 = rf(repo) } else { @@ -534,7 +652,6 @@ func (_m *Client) GetRepository(repo string) (*api.Repository, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(repo) } else { @@ -549,13 +666,16 @@ func (_m *Client) GetShell() (api.CloudShell, error) { ret := _m.Called() var r0 api.CloudShell + var r1 error + if rf, ok := ret.Get(0).(func() (api.CloudShell, error)); ok { + return rf() + } if rf, ok := ret.Get(0).(func() api.CloudShell); ok { r0 = rf() } else { r0 = ret.Get(0).(api.CloudShell) } - var r1 error if rf, ok := ret.Get(1).(func() error); ok { r1 = rf() } else { @@ -570,6 +690,10 @@ func (_m *Client) GetStack(name string, provider string) (*api.Stack, error) { ret := _m.Called(name, provider) var r0 *api.Stack + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (*api.Stack, error)); ok { + return rf(name, provider) + } if rf, ok := ret.Get(0).(func(string, string) *api.Stack); ok { r0 = rf(name, provider) } else { @@ -578,7 +702,6 @@ func (_m *Client) GetStack(name string, provider string) (*api.Stack, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string, string) error); ok { r1 = rf(name, provider) } else { @@ -593,6 +716,10 @@ func (_m *Client) GetTerraformInstallations(repoId string) ([]*api.TerraformInst ret := _m.Called(repoId) var r0 []*api.TerraformInstallation + var r1 error + if rf, ok := ret.Get(0).(func(string) ([]*api.TerraformInstallation, error)); ok { + return rf(repoId) + } if rf, ok := ret.Get(0).(func(string) []*api.TerraformInstallation); ok { r0 = rf(repoId) } else { @@ -601,7 +728,6 @@ func (_m *Client) GetTerraformInstallations(repoId string) ([]*api.TerraformInst } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(repoId) } else { @@ -616,6 +742,10 @@ func (_m *Client) GetTerraforma(repoId string) ([]*api.Terraform, error) { ret := _m.Called(repoId) var r0 []*api.Terraform + var r1 error + if rf, ok := ret.Get(0).(func(string) ([]*api.Terraform, error)); ok { + return rf(repoId) + } if rf, ok := ret.Get(0).(func(string) []*api.Terraform); ok { r0 = rf(repoId) } else { @@ -624,7 +754,6 @@ func (_m *Client) GetTerraforma(repoId string) ([]*api.Terraform, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(repoId) } else { @@ -639,13 +768,16 @@ func (_m *Client) GetTfProviderScaffold(name string, version string) (string, er ret := _m.Called(name, version) var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (string, error)); ok { + return rf(name, version) + } if rf, ok := ret.Get(0).(func(string, string) string); ok { r0 = rf(name, version) } else { r0 = ret.Get(0).(string) } - var r1 error if rf, ok := ret.Get(1).(func(string, string) error); ok { r1 = rf(name, version) } else { @@ -660,6 +792,10 @@ func (_m *Client) GetTfProviders() ([]string, error) { ret := _m.Called() var r0 []string + var r1 error + if rf, ok := ret.Get(0).(func() ([]string, error)); ok { + return rf() + } if rf, ok := ret.Get(0).(func() []string); ok { r0 = rf() } else { @@ -668,7 +804,6 @@ func (_m *Client) GetTfProviders() ([]string, error) { } } - var r1 error if rf, ok := ret.Get(1).(func() error); ok { r1 = rf() } else { @@ -683,6 +818,10 @@ func (_m *Client) GetVersions(chartId string) ([]*api.Version, error) { ret := _m.Called(chartId) var r0 []*api.Version + var r1 error + if rf, ok := ret.Get(0).(func(string) ([]*api.Version, error)); ok { + return rf(chartId) + } if rf, ok := ret.Get(0).(func(string) []*api.Version); ok { r0 = rf(chartId) } else { @@ -691,7 +830,6 @@ func (_m *Client) GetVersions(chartId string) ([]*api.Version, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(chartId) } else { @@ -706,13 +844,16 @@ func (_m *Client) GrabAccessToken() (string, error) { ret := _m.Called() var r0 string + var r1 error + if rf, ok := ret.Get(0).(func() (string, error)); ok { + return rf() + } if rf, ok := ret.Get(0).(func() string); ok { r0 = rf() } else { r0 = ret.Get(0).(string) } - var r1 error if rf, ok := ret.Get(1).(func() error); ok { r1 = rf() } else { @@ -727,20 +868,23 @@ func (_m *Client) ImpersonateServiceAccount(email string) (string, string, error ret := _m.Called(email) var r0 string + var r1 string + var r2 error + if rf, ok := ret.Get(0).(func(string) (string, string, error)); ok { + return rf(email) + } if rf, ok := ret.Get(0).(func(string) string); ok { r0 = rf(email) } else { r0 = ret.Get(0).(string) } - var r1 string if rf, ok := ret.Get(1).(func(string) string); ok { r1 = rf(email) } else { r1 = ret.Get(1).(string) } - var r2 error if rf, ok := ret.Get(2).(func(string) error); ok { r2 = rf(email) } else { @@ -769,6 +913,10 @@ func (_m *Client) ListArtifacts(repo string) ([]api.Artifact, error) { ret := _m.Called(repo) var r0 []api.Artifact + var r1 error + if rf, ok := ret.Get(0).(func(string) ([]api.Artifact, error)); ok { + return rf(repo) + } if rf, ok := ret.Get(0).(func(string) []api.Artifact); ok { r0 = rf(repo) } else { @@ -777,7 +925,6 @@ func (_m *Client) ListArtifacts(repo string) ([]api.Artifact, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(repo) } else { @@ -792,6 +939,10 @@ func (_m *Client) ListKeyBackups() ([]*api.KeyBackup, error) { ret := _m.Called() var r0 []*api.KeyBackup + var r1 error + if rf, ok := ret.Get(0).(func() ([]*api.KeyBackup, error)); ok { + return rf() + } if rf, ok := ret.Get(0).(func() []*api.KeyBackup); ok { r0 = rf() } else { @@ -800,7 +951,6 @@ func (_m *Client) ListKeyBackups() ([]*api.KeyBackup, error) { } } - var r1 error if rf, ok := ret.Get(1).(func() error); ok { r1 = rf() } else { @@ -815,6 +965,10 @@ func (_m *Client) ListKeys(emails []string) ([]*api.PublicKey, error) { ret := _m.Called(emails) var r0 []*api.PublicKey + var r1 error + if rf, ok := ret.Get(0).(func([]string) ([]*api.PublicKey, error)); ok { + return rf(emails) + } if rf, ok := ret.Get(0).(func([]string) []*api.PublicKey); ok { r0 = rf(emails) } else { @@ -823,7 +977,6 @@ func (_m *Client) ListKeys(emails []string) ([]*api.PublicKey, error) { } } - var r1 error if rf, ok := ret.Get(1).(func([]string) error); ok { r1 = rf(emails) } else { @@ -838,6 +991,10 @@ func (_m *Client) ListRecipes(repo string, provider string) ([]*api.Recipe, erro ret := _m.Called(repo, provider) var r0 []*api.Recipe + var r1 error + if rf, ok := ret.Get(0).(func(string, string) ([]*api.Recipe, error)); ok { + return rf(repo, provider) + } if rf, ok := ret.Get(0).(func(string, string) []*api.Recipe); ok { r0 = rf(repo, provider) } else { @@ -846,7 +1003,6 @@ func (_m *Client) ListRecipes(repo string, provider string) ([]*api.Recipe, erro } } - var r1 error if rf, ok := ret.Get(1).(func(string, string) error); ok { r1 = rf(repo, provider) } else { @@ -861,6 +1017,10 @@ func (_m *Client) ListRepositories(query string) ([]*api.Repository, error) { ret := _m.Called(query) var r0 []*api.Repository + var r1 error + if rf, ok := ret.Get(0).(func(string) ([]*api.Repository, error)); ok { + return rf(query) + } if rf, ok := ret.Get(0).(func(string) []*api.Repository); ok { r0 = rf(query) } else { @@ -869,7 +1029,6 @@ func (_m *Client) ListRepositories(query string) ([]*api.Repository, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(query) } else { @@ -884,6 +1043,10 @@ func (_m *Client) ListStacks(featured bool) ([]*api.Stack, error) { ret := _m.Called(featured) var r0 []*api.Stack + var r1 error + if rf, ok := ret.Get(0).(func(bool) ([]*api.Stack, error)); ok { + return rf(featured) + } if rf, ok := ret.Get(0).(func(bool) []*api.Stack); ok { r0 = rf(featured) } else { @@ -892,7 +1055,6 @@ func (_m *Client) ListStacks(featured bool) ([]*api.Stack, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(bool) error); ok { r1 = rf(featured) } else { @@ -907,13 +1069,16 @@ func (_m *Client) Login(email string, pwd string) (string, error) { ret := _m.Called(email, pwd) var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (string, error)); ok { + return rf(email, pwd) + } if rf, ok := ret.Get(0).(func(string, string) string); ok { r0 = rf(email, pwd) } else { r0 = ret.Get(0).(string) } - var r1 error if rf, ok := ret.Get(1).(func(string, string) error); ok { r1 = rf(email, pwd) } else { @@ -928,6 +1093,10 @@ func (_m *Client) LoginMethod(email string) (*api.LoginMethod, error) { ret := _m.Called(email) var r0 *api.LoginMethod + var r1 error + if rf, ok := ret.Get(0).(func(string) (*api.LoginMethod, error)); ok { + return rf(email) + } if rf, ok := ret.Get(0).(func(string) *api.LoginMethod); ok { r0 = rf(email) } else { @@ -936,7 +1105,6 @@ func (_m *Client) LoginMethod(email string) (*api.LoginMethod, error) { } } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(email) } else { @@ -951,6 +1119,10 @@ func (_m *Client) Me() (*api.Me, error) { ret := _m.Called() var r0 *api.Me + var r1 error + if rf, ok := ret.Get(0).(func() (*api.Me, error)); ok { + return rf() + } if rf, ok := ret.Get(0).(func() *api.Me); ok { r0 = rf() } else { @@ -959,7 +1131,6 @@ func (_m *Client) Me() (*api.Me, error) { } } - var r1 error if rf, ok := ret.Get(1).(func() error); ok { r1 = rf() } else { @@ -988,13 +1159,16 @@ func (_m *Client) PollLoginToken(token string) (string, error) { ret := _m.Called(token) var r0 string + var r1 error + if rf, ok := ret.Get(0).(func(string) (string, error)); ok { + return rf(token) + } if rf, ok := ret.Get(0).(func(string) string); ok { r0 = rf(token) } else { r0 = ret.Get(0).(string) } - var r1 error if rf, ok := ret.Get(1).(func(string) error); ok { r1 = rf(token) } else { @@ -1004,11 +1178,29 @@ func (_m *Client) PollLoginToken(token string) (string, error) { return r0, r1 } +// PromoteCluster provides a mock function with given fields: +func (_m *Client) PromoteCluster() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + // ReleaseLock provides a mock function with given fields: repo, lock func (_m *Client) ReleaseLock(repo string, lock string) (*api.ApplyLock, error) { ret := _m.Called(repo, lock) var r0 *api.ApplyLock + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (*api.ApplyLock, error)); ok { + return rf(repo, lock) + } if rf, ok := ret.Get(0).(func(string, string) *api.ApplyLock); ok { r0 = rf(repo, lock) } else { @@ -1017,7 +1209,6 @@ func (_m *Client) ReleaseLock(repo string, lock string) (*api.ApplyLock, error) } } - var r1 error if rf, ok := ret.Get(1).(func(string, string) error); ok { r1 = rf(repo, lock) } else { @@ -1032,13 +1223,16 @@ func (_m *Client) ResetInstallations() (int, error) { ret := _m.Called() var r0 int + var r1 error + if rf, ok := ret.Get(0).(func() (int, error)); ok { + return rf() + } if rf, ok := ret.Get(0).(func() int); ok { r0 = rf() } else { r0 = ret.Get(0).(int) } - var r1 error if rf, ok := ret.Get(1).(func() error); ok { r1 = rf() } else { @@ -1053,6 +1247,10 @@ func (_m *Client) Scaffolds(in *api.ScaffoldInputs) ([]*api.ScaffoldFile, error) ret := _m.Called(in) var r0 []*api.ScaffoldFile + var r1 error + if rf, ok := ret.Get(0).(func(*api.ScaffoldInputs) ([]*api.ScaffoldFile, error)); ok { + return rf(in) + } if rf, ok := ret.Get(0).(func(*api.ScaffoldInputs) []*api.ScaffoldFile); ok { r0 = rf(in) } else { @@ -1061,7 +1259,6 @@ func (_m *Client) Scaffolds(in *api.ScaffoldInputs) ([]*api.ScaffoldFile, error) } } - var r1 error if rf, ok := ret.Get(1).(func(*api.ScaffoldInputs) error); ok { r1 = rf(in) } else { @@ -1132,13 +1329,16 @@ func (_m *Client) UploadTerraform(dir string, repoName string) (api.Terraform, e ret := _m.Called(dir, repoName) var r0 api.Terraform + var r1 error + if rf, ok := ret.Get(0).(func(string, string) (api.Terraform, error)); ok { + return rf(dir, repoName) + } if rf, ok := ret.Get(0).(func(string, string) api.Terraform); ok { r0 = rf(dir, repoName) } else { r0 = ret.Get(0).(api.Terraform) } - var r1 error if rf, ok := ret.Get(1).(func(string, string) error); ok { r1 = rf(dir, repoName) } else { diff --git a/pkg/utils/print.go b/pkg/utils/print.go index c653505c..bf9831ca 100644 --- a/pkg/utils/print.go +++ b/pkg/utils/print.go @@ -98,3 +98,12 @@ func PrintTable[T any](list []T, headers []string, rowFun func(T) ([]string, err table.Render() return nil } + +func PrintAttributes(attrs map[string]string) { + table := tablewriter.NewWriter(os.Stdout) + table.SetHeader([]string{"Attribute", "Value"}) + for k, v := range attrs { + table.Append([]string{k, v}) + } + table.Render() +}