From d3e2d244ae436c74475b9ed9b2f45ba0a1cdfddf Mon Sep 17 00:00:00 2001 From: smithers1221 Date: Fri, 30 Aug 2019 15:42:02 -0700 Subject: [PATCH 01/16] firstdraft --- cli/cmd/release_create.go | 69 +++++++++++++++++++++++++++- cli/cmd/root.go | 10 +++++ cli/cmd/runner.go | 38 ++++++++++------ client/client.go | 8 ++++ client/collector.go | 2 + client/release.go | 2 + pkg/kotsclient/app.go | 94 +++++++++++++++++++++++++++++++++++++++ pkg/kotsclient/client.go | 35 +++++++++++++++ pkg/kotsclient/release.go | 41 +++++++++++++++++ 9 files changed, 285 insertions(+), 14 deletions(-) create mode 100644 pkg/kotsclient/app.go create mode 100644 pkg/kotsclient/client.go create mode 100644 pkg/kotsclient/release.go diff --git a/cli/cmd/release_create.go b/cli/cmd/release_create.go index eebf35510..47d777863 100644 --- a/cli/cmd/release_create.go +++ b/cli/cmd/release_create.go @@ -1,6 +1,7 @@ package cmd import ( + "encoding/json" "fmt" "io/ioutil" @@ -19,6 +20,7 @@ func (r *runners) InitReleaseCreate(parent *cobra.Command) { cmd.Flags().StringVar(&r.args.createReleaseYaml, "yaml", "", "The YAML config for this release. Use '-' to read from stdin. Cannot be used with the `yaml-file` falg.") cmd.Flags().StringVar(&r.args.createReleaseYamlFile, "yaml-file", "", "The file name with YAML config for this release. Cannot be used with the `yaml` flag.") + cmd.Flags().StringVar(&r.args.createReleaseYamlDir, "yaml-dir", "", "The directory containing the 5 required YAML configs for a Kots release. Cannot be used with the `yaml` flag.") cmd.Flags().StringVar(&r.args.createReleasePromote, "promote", "", "Channel name or id to promote this release to") cmd.Flags().StringVar(&r.args.createReleasePromoteNotes, "release-notes", "", "When used with --promote , sets the **markdown** release notes") cmd.Flags().BoolVar(&r.args.createReleasePromoteRequired, "required", false, "When used with --promote , marks this release as required during upgrades.") @@ -27,8 +29,34 @@ func (r *runners) InitReleaseCreate(parent *cobra.Command) { cmd.RunE = r.releaseCreate } +func Contains(a []string, x string) bool { + for _, n := range a { + if x == n { + return true + } + } + return false +} + +type KotsSingleReleaseYaml struct { + name string + path string + content string +} + +type KotsReleaseYamls []KotsSingleReleaseYaml + +func makeStruct(specName string, content string) KotsSingleReleaseYaml { + var path string + path = specName + kotsSingleSpec := KotsSingleReleaseYaml{specName, path, content} + + return kotsSingleSpec +} + func (r *runners) releaseCreate(cmd *cobra.Command, args []string) error { - if r.args.createReleaseYaml == "" && r.args.createReleaseYamlFile == "" { + + if r.args.createReleaseYaml == "" && r.args.createReleaseYamlFile == "" && r.args.createReleaseYamlDir == "" { return fmt.Errorf("yaml is required") } @@ -52,6 +80,45 @@ func (r *runners) releaseCreate(cmd *cobra.Command, args []string) error { r.args.createReleaseYaml = string(bytes) } + fileList := []string{"config.yaml", "deployment.yaml", "service.yaml", "preflight.yaml", "support-bundle.yaml"} + + if r.args.createReleaseYamlDir != "" { + files, err := ioutil.ReadDir(r.args.createReleaseYamlDir) + if err != nil { + return err + } + + var bytes []byte + + if len(files) < 5 { + return fmt.Errorf("Missing 1 or more required files") + } + + type kotsSingleSpec map[string]interface{} + var spec kotsSingleSpec + var allKotsReleaseSpecs []kotsSingleSpec + + for _, file := range files { + if Contains(fileList, file.Name()) { + bytes, err = ioutil.ReadFile(r.args.createReleaseYamlDir + "/" + file.Name()) + spec = kotsSingleSpec{"name": file.Name(), "path": file.Name(), "content": string(bytes)} + allKotsReleaseSpecs = append(allKotsReleaseSpecs, spec) + + if err != nil { + return err + } + } + } + + jsonAllYamls, err := json.Marshal(allKotsReleaseSpecs) + + if err != nil { + return err + } + r.args.createReleaseYaml = string(jsonAllYamls) + + } + // if the --promote param was used make sure it identifies exactly one // channel before proceeding var promoteChanID string diff --git a/cli/cmd/root.go b/cli/cmd/root.go index 3961464cb..1e82fb3ba 100644 --- a/cli/cmd/root.go +++ b/cli/cmd/root.go @@ -6,6 +6,7 @@ import ( "os" "text/tabwriter" + "github.com/replicatedhq/replicated/pkg/kotsclient" "github.com/replicatedhq/replicated/pkg/shipclient" "github.com/replicatedhq/replicated/client" @@ -151,6 +152,9 @@ func Execute(rootCmd *cobra.Command, stdin io.Reader, stdout io.Writer, stderr i shipAPI := shipclient.NewGraphQLClient(graphqlOrigin, apiToken) runCmds.shipAPI = shipAPI + kotsAPI := kotsclient.NewGraphQLClient(graphqlOrigin, apiToken) + runCmds.kotsAPI = kotsAPI + commonAPI := client.NewClient(platformOrigin, graphqlOrigin, apiToken) runCmds.api = commonAPI @@ -176,6 +180,12 @@ func Execute(rootCmd *cobra.Command, stdin io.Reader, stdout io.Writer, stderr i return err } runCmds.appID = app.ID + } else { + app, err := kotsAPI.GetApp(appSlugOrID) + if err != nil { + return err + } + runCmds.appID = app.ID } return nil diff --git a/cli/cmd/runner.go b/cli/cmd/runner.go index 26b134453..bed4c8691 100644 --- a/cli/cmd/runner.go +++ b/cli/cmd/runner.go @@ -4,6 +4,8 @@ import ( "io" "text/tabwriter" + "github.com/replicatedhq/replicated/pkg/kotsclient" + "github.com/replicatedhq/replicated/pkg/shipclient" "github.com/spf13/cobra" @@ -19,7 +21,9 @@ type runners struct { api client.Client platformAPI platformclient.Client shipAPI shipclient.Client + kotsAPI kotsclient.Client stdin io.Reader + dir string w *tabwriter.Writer rootCmd *cobra.Command @@ -37,19 +41,27 @@ type runnerArgs struct { updateCollectorYamlFile string updateCollectorName string - createReleaseYaml string - createReleaseYamlFile string - createReleasePromote string - createReleasePromoteRequired bool - createReleasePromoteNotes string - createReleasePromoteVersion string - lintReleaseYaml string - lintReleaseYamlFile string - releaseOptional bool - releaseNotes string - releaseVersion string - updateReleaseYaml string - updateReleaseYamlFile string + createReleaseYaml string + createReleaseYamlFile string + createReleaseYamlDir string + createReleaseConfigYaml string + createReleaseDeploymentYaml string + createReleaseServiceYaml string + createReleasePreflightYaml string + createReleaseSupportBundleYaml string + createReleasePromote string + createReleasePromoteDir string + createReleasePromoteRequired bool + createReleasePromoteNotes string + createReleasePromoteVersion string + lintReleaseYaml string + lintReleaseYamlFile string + releaseOptional bool + releaseNotes string + releaseVersion string + updateReleaseYaml string + updateReleaseYamlDir string + updateReleaseYamlFile string entitlementsAPIServer string entitlementsVerbose bool diff --git a/client/client.go b/client/client.go index 96b0ba535..39b119a7c 100644 --- a/client/client.go +++ b/client/client.go @@ -1,6 +1,7 @@ package client import ( + "github.com/replicatedhq/replicated/pkg/kotsclient" "github.com/replicatedhq/replicated/pkg/platformclient" "github.com/replicatedhq/replicated/pkg/shipclient" ) @@ -8,12 +9,14 @@ import ( type Client struct { PlatformClient platformclient.Client ShipClient shipclient.Client + KotsClient kotsclient.Client } func NewClient(platformOrigin string, graphqlOrigin string, apiToken string) Client { client := Client{ PlatformClient: platformclient.NewHTTPClient(platformOrigin, apiToken), ShipClient: shipclient.NewGraphQLClient(graphqlOrigin, apiToken), + KotsClient: kotsclient.NewGraphQLClient(graphqlOrigin, apiToken), } return client @@ -30,5 +33,10 @@ func (c *Client) GetAppType(appID string) (string, error) { return "ship", nil } + kotsApp, err := c.KotsClient.GetApp(appID) + if err == nil && kotsApp != nil { + return "kots", nil + } + return "", err } diff --git a/client/collector.go b/client/collector.go index c1410d553..6ce04523a 100644 --- a/client/collector.go +++ b/client/collector.go @@ -14,6 +14,8 @@ func (c *Client) ListCollectors(appID string) ([]types.CollectorInfo, error) { return nil, err } + // TODO: if kots message yadda yadda about updating support-bundle.yaml + shipappCollectors, err := c.ShipClient.ListCollectors(appID, appType) if err != nil { return nil, err diff --git a/client/release.go b/client/release.go index a33d68d1a..5c9def43b 100644 --- a/client/release.go +++ b/client/release.go @@ -85,6 +85,8 @@ func (c *Client) CreateRelease(appID string, yaml string) (*types.ReleaseInfo, e }, nil } else if appType == "ship" { return c.ShipClient.CreateRelease(appID, yaml) + } else { + return c.KotsClient.CreateRelease(appID, yaml) } return nil, errors.New("unknown app type") diff --git a/pkg/kotsclient/app.go b/pkg/kotsclient/app.go new file mode 100644 index 000000000..fe69c3b83 --- /dev/null +++ b/pkg/kotsclient/app.go @@ -0,0 +1,94 @@ +package kotsclient + +import ( + "github.com/pkg/errors" + "github.com/replicatedhq/replicated/pkg/graphql" + "github.com/replicatedhq/replicated/pkg/types" +) + +type GraphQLResponseListApps struct { + Data *KotsData `json:"data,omitempty"` + Errors []graphql.GQLError `json:"errors,omitempty"` +} + +type KotsData struct { + Kots *KotsAppsData `json:"kots"` +} + +type KotsAppsData struct { + KotsApps []*KotsApp `json:"apps"` +} + +type KotsChannelData struct { + ID string `json:"id"` +} + +type KotsApp struct { + ID string `json:"id"` + Name string `json:"name"` + Slug string `json:"slug"` + Channels []*KotsChannelData `json: "channels"` +} + +func (c *GraphQLClient) ListApps() ([]types.AppAndChannels, error) { + response := GraphQLResponseListApps{} + + request := graphql.Request{ + Query: ` + query kots { + kots { + apps { + id + name + created + updated + isDefault + isArchived + slug + channels { + id + } + isKotsApp + } + } + } + `, + + Variables: map[string]interface{}{}, + } + + if err := c.ExecuteRequest(request, &response); err != nil { + return nil, err + } + + appsAndChannels := make([]types.AppAndChannels, 0, 0) + for _, kotsapp := range response.Data.Kots.KotsApps { + + appAndChannels := types.AppAndChannels{ + App: &types.App{ + ID: kotsapp.ID, + Name: kotsapp.Name, + Slug: kotsapp.Slug, + }, + } + + appsAndChannels = append(appsAndChannels, appAndChannels) + } + + return appsAndChannels, nil +} + +func (c *GraphQLClient) GetApp(appID string) (*types.App, error) { + apps, err := c.ListApps() + if err != nil { + return nil, err + } + + for _, app := range apps { + if app.App.ID == appID || app.App.Slug == appID { + return app.App, nil + } + } + + return nil, errors.New("App not found") +} diff --git a/pkg/kotsclient/client.go b/pkg/kotsclient/client.go new file mode 100644 index 000000000..9e3f273c9 --- /dev/null +++ b/pkg/kotsclient/client.go @@ -0,0 +1,35 @@ +package kotsclient + +import ( + "github.com/replicatedhq/replicated/pkg/graphql" + "github.com/replicatedhq/replicated/pkg/types" +) + +type Client interface { + CreateRelease(appID string, spec string) (*types.ReleaseInfo, error) + GetApp(appID string) (*types.App, error) +} + +type AppOptions struct { + Name string +} + +type ChannelOptions struct { + Name string + Description string +} + +// Client communicates with the Replicated Vendor GraphQL API. +type GraphQLClient struct { + GraphQLClient *graphql.Client +} + +func NewGraphQLClient(origin string, apiKey string) Client { + c := &GraphQLClient{GraphQLClient: graphql.NewClient(origin, apiKey)} + + return c +} + +func (c *GraphQLClient) ExecuteRequest(requestObj graphql.Request, deserializeTarget interface{}) error { + return c.GraphQLClient.ExecuteRequest(requestObj, deserializeTarget) +} diff --git a/pkg/kotsclient/release.go b/pkg/kotsclient/release.go new file mode 100644 index 000000000..b793b49b0 --- /dev/null +++ b/pkg/kotsclient/release.go @@ -0,0 +1,41 @@ +package kotsclient + +import ( + "github.com/replicatedhq/replicated/pkg/graphql" + "github.com/replicatedhq/replicated/pkg/types" +) + +type KotsReleaseData struct { + Sequence int64 `json:"sequence"` +} + +var createKotsRelease = ` +mutation createKotsRelease($appId: ID!, $spec: String!) { + createKotsRelease(appId: $appId, spec: $spec) { + sequence + } +} +` + +func (c *GraphQLClient) CreateRelease(appID string, yaml string) (*types.ReleaseInfo, error) { + response := KotsReleaseData{} + + request := graphql.Request{ + Query: createKotsRelease, + Variables: map[string]interface{}{ + "appId": appID, + "spec": yaml, + }, + } + + if err := c.ExecuteRequest(request, &response); err != nil { + return nil, err + } + + releaseInfo := types.ReleaseInfo{ + AppID: appID, + Sequence: response.Sequence, + } + + return &releaseInfo, nil +} From 6ac7d41c49f5b52b28610da87feda6f4c77f17e2 Mon Sep 17 00:00:00 2001 From: smithers1221 Date: Tue, 10 Sep 2019 09:51:43 -0700 Subject: [PATCH 02/16] channel create and ls; todo what the what with releases --- cli/cmd/release_create.go | 45 ++---------- client/channel.go | 7 ++ client/release.go | 2 +- pkg/kotsclient/app.go | 10 +-- pkg/kotsclient/channel.go | 146 ++++++++++++++++++++++++++++++++++++++ pkg/kotsclient/client.go | 10 ++- pkg/kotsclient/release.go | 63 ++++++++++++---- 7 files changed, 225 insertions(+), 58 deletions(-) create mode 100644 pkg/kotsclient/channel.go diff --git a/cli/cmd/release_create.go b/cli/cmd/release_create.go index 47d777863..13e66cacf 100644 --- a/cli/cmd/release_create.go +++ b/cli/cmd/release_create.go @@ -29,31 +29,6 @@ func (r *runners) InitReleaseCreate(parent *cobra.Command) { cmd.RunE = r.releaseCreate } -func Contains(a []string, x string) bool { - for _, n := range a { - if x == n { - return true - } - } - return false -} - -type KotsSingleReleaseYaml struct { - name string - path string - content string -} - -type KotsReleaseYamls []KotsSingleReleaseYaml - -func makeStruct(specName string, content string) KotsSingleReleaseYaml { - var path string - path = specName - kotsSingleSpec := KotsSingleReleaseYaml{specName, path, content} - - return kotsSingleSpec -} - func (r *runners) releaseCreate(cmd *cobra.Command, args []string) error { if r.args.createReleaseYaml == "" && r.args.createReleaseYamlFile == "" && r.args.createReleaseYamlDir == "" { @@ -80,8 +55,6 @@ func (r *runners) releaseCreate(cmd *cobra.Command, args []string) error { r.args.createReleaseYaml = string(bytes) } - fileList := []string{"config.yaml", "deployment.yaml", "service.yaml", "preflight.yaml", "support-bundle.yaml"} - if r.args.createReleaseYamlDir != "" { files, err := ioutil.ReadDir(r.args.createReleaseYamlDir) if err != nil { @@ -90,23 +63,17 @@ func (r *runners) releaseCreate(cmd *cobra.Command, args []string) error { var bytes []byte - if len(files) < 5 { - return fmt.Errorf("Missing 1 or more required files") - } - type kotsSingleSpec map[string]interface{} var spec kotsSingleSpec var allKotsReleaseSpecs []kotsSingleSpec for _, file := range files { - if Contains(fileList, file.Name()) { - bytes, err = ioutil.ReadFile(r.args.createReleaseYamlDir + "/" + file.Name()) - spec = kotsSingleSpec{"name": file.Name(), "path": file.Name(), "content": string(bytes)} - allKotsReleaseSpecs = append(allKotsReleaseSpecs, spec) - - if err != nil { - return err - } + bytes, err = ioutil.ReadFile(r.args.createReleaseYamlDir + "/" + file.Name()) + spec = kotsSingleSpec{"name": file.Name(), "path": file.Name(), "content": string(bytes)} + allKotsReleaseSpecs = append(allKotsReleaseSpecs, spec) + + if err != nil { + return err } } diff --git a/client/channel.go b/client/channel.go index 98bc6e4fa..cc9778558 100644 --- a/client/channel.go +++ b/client/channel.go @@ -34,6 +34,8 @@ func (c *Client) ListChannels(appID string) ([]types.Channel, error) { return channels, nil } else if appType == "ship" { return c.ShipClient.ListChannels(appID) + } else if appType == "kots" { + return c.KotsClient.ListChannels(appID) } return nil, errors.New("unknown app type") @@ -63,6 +65,11 @@ func (c *Client) CreateChannel(appID string, name string, description string) ([ return nil, err } return c.ShipClient.ListChannels(appID) + } else if appType == "kots" { + if err := c.KotsClient.CreateChannel(appID, name, description); err != nil { + return nil, err + } + return c.KotsClient.ListChannels(appID) } return nil, errors.New("unknown app type") diff --git a/client/release.go b/client/release.go index 5c9def43b..a9861540f 100644 --- a/client/release.go +++ b/client/release.go @@ -85,7 +85,7 @@ func (c *Client) CreateRelease(appID string, yaml string) (*types.ReleaseInfo, e }, nil } else if appType == "ship" { return c.ShipClient.CreateRelease(appID, yaml) - } else { + } else if appType == "kots" { return c.KotsClient.CreateRelease(appID, yaml) } diff --git a/pkg/kotsclient/app.go b/pkg/kotsclient/app.go index fe69c3b83..c525b7b45 100644 --- a/pkg/kotsclient/app.go +++ b/pkg/kotsclient/app.go @@ -19,15 +19,15 @@ type KotsAppsData struct { KotsApps []*KotsApp `json:"apps"` } -type KotsChannelData struct { +type KotsAppChannelData struct { ID string `json:"id"` } type KotsApp struct { - ID string `json:"id"` - Name string `json:"name"` - Slug string `json:"slug"` - Channels []*KotsChannelData `json: "channels"` + ID string `json:"id"` + Name string `json:"name"` + Slug string `json:"slug"` + Channels []*KotsAppChannelData `json: "channels"` } func (c *GraphQLClient) ListApps() ([]types.AppAndChannels, error) { diff --git a/pkg/kotsclient/channel.go b/pkg/kotsclient/channel.go new file mode 100644 index 000000000..8ac662a64 --- /dev/null +++ b/pkg/kotsclient/channel.go @@ -0,0 +1,146 @@ +package kotsclient + +import ( + "github.com/pkg/errors" + "github.com/replicatedhq/replicated/pkg/graphql" + "github.com/replicatedhq/replicated/pkg/types" +) + +type GraphQLResponseListChannels struct { + Data *KotsChannelData `json:"data,omitempty"` + Errors []graphql.GQLError `json:"errors,omitempty"` +} + +type KotsChannelData struct { + KotsChannels []*KotsChannel `json:"getKotsAppChannels"` +} + +type KotsChannel struct { + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + + CurrentSequence int64 `json:"currentSequence"` + CurrentVersion string `json:"currentVersion"` +} + +func (c *GraphQLClient) ListChannels(appID string) ([]types.Channel, error) { + response := GraphQLResponseListChannels{} + + request := graphql.Request{ + Query: ` + query getKotsAppChannels($appId: ID!) { + getKotsAppChannels(appId: $appId) { + id + appId + name + currentVersion + currentReleaseDate + currentSpec + numReleases + description + channelIcon + created + updated + isDefault + isArchived + adoptionRate { + releaseSequence + semver + count + percent + totalOnChannel + } + customers { + id + name + avatar + shipInstallStatus { + status + } + } + githubRef { + owner + repoFullName + branch + path + } + releases { + sequence + semver + } + } + } + `, + + Variables: map[string]interface{}{ + "appId": appID, + }, + } + + if err := c.ExecuteRequest(request, &response); err != nil { + return nil, err + } + + channels := make([]types.Channel, 0, 0) + for _, kotsChannel := range response.Data.KotsChannels { + channel := types.Channel{ + ID: kotsChannel.ID, + Name: kotsChannel.Name, + Description: kotsChannel.Description, + ReleaseSequence: kotsChannel.CurrentSequence, + ReleaseLabel: kotsChannel.CurrentVersion, + } + + channels = append(channels, channel) + } + + return channels, nil +} + +func (c *GraphQLClient) CreateChannel(appID string, name string, description string) error { + response := graphql.ResponseErrorOnly{} + + request := graphql.Request{ + Query: ` + mutation createKotsChannel($appId: String!, $channelName: String!, $description: String) { + createKotsChannel(appId: $appId, channelName: $channelName, description: $description) { + id + name + description + currentVersion + currentReleaseDate + numReleases + created + updated + isDefault + isArchived + } + } + `, + Variables: map[string]interface{}{ + "appId": appID, + "channelName": name, + "description": description, + }, + } + + if err := c.ExecuteRequest(request, &response); err != nil { + return err + } + + if len(response.Errors) != 0 { + return errors.New(response.Errors[0].Message) + } + + return nil + +} + +func ArchiveChannel(appID string, channelID string) error { + return nil +} + +func GetChannel(appID string, channelID string) (interface{}, []interface{}, error) { + return nil, nil, nil +} diff --git a/pkg/kotsclient/client.go b/pkg/kotsclient/client.go index 9e3f273c9..e3ef72609 100644 --- a/pkg/kotsclient/client.go +++ b/pkg/kotsclient/client.go @@ -6,8 +6,16 @@ import ( ) type Client interface { - CreateRelease(appID string, spec string) (*types.ReleaseInfo, error) + ListApps() ([]types.AppAndChannels, error) GetApp(appID string) (*types.App, error) + + CreateRelease(appID string, multiyaml string) (*types.ReleaseInfo, error) + // ListReleases(appID string) ([]types.ReleaseInfo, error) + // UpdateRelease(appID string, sequence int64, yaml string) error + // PromoteRelease(appID string, sequence int64, label string, notes string, channelIDs ...string) error + + ListChannels(string) ([]types.Channel, error) + CreateChannel(string, string, string) error } type AppOptions struct { diff --git a/pkg/kotsclient/release.go b/pkg/kotsclient/release.go index b793b49b0..9d0434850 100644 --- a/pkg/kotsclient/release.go +++ b/pkg/kotsclient/release.go @@ -1,40 +1,79 @@ package kotsclient import ( + "fmt" + "github.com/replicatedhq/replicated/pkg/graphql" "github.com/replicatedhq/replicated/pkg/types" ) -type KotsReleaseData struct { +type GraphQLResponseKotsCreateRelease struct { + Data KotsCreateReleaseData `json:"data,omitempty"` + Errors []graphql.GQLError `json:"errors,omitempty"` +} + +type KotsCreateReleaseData struct { + KotsReleaseData KotsReleaseSequence `json:"createKotsRelease"` +} + +type KotsReleaseSequence struct { Sequence int64 `json:"sequence"` } -var createKotsRelease = ` -mutation createKotsRelease($appId: ID!, $spec: String!) { - createKotsRelease(appId: $appId, spec: $spec) { - sequence - } +type GraphQLResponseKotsUpdateRelease struct { + Data KotsUpdateReleaseData `json:"data,omitempty"` + Errors []graphql.GQLError `json:"errors,omitempty"` +} + +type KotsUpdateReleaseData struct { + KotsReleaseData KotsReleaseSequence `json:"createKotsRelease"` } -` -func (c *GraphQLClient) CreateRelease(appID string, yaml string) (*types.ReleaseInfo, error) { - response := KotsReleaseData{} +func (c *GraphQLClient) CreateRelease(appID string, multiyaml string) (*types.ReleaseInfo, error) { + response := GraphQLResponseKotsCreateRelease{} request := graphql.Request{ - Query: createKotsRelease, + Query: ` + query createKotsRelease($appId: ID!, $spec: String!) { + createKotsRelease(appId: $appId, spec: $spec) { + sequence + } + }`, Variables: map[string]interface{}{ "appId": appID, - "spec": yaml, + "spec": multiyaml, }, } if err := c.ExecuteRequest(request, &response); err != nil { + fmt.Println("anything?", response.Data.KotsReleaseData.Sequence) + return nil, err + } + + request = graphql.Request{ + Query: ` + mutation updateKotsRelease($appId: ID!, $spec: String!, $sequence: Int) { + updateKotsRelease(appId: $appId, spec: $spec, sequence: $sequence) { + sequence + } + } + `, + Variables: map[string]interface{}{ + "appId": appID, + "spec": multiyaml, + "sequence": response.Data.KotsReleaseData.Sequence, + }, + } + + finalizeKotsReleaseCreate := GraphQLResponseKotsUpdateRelease{} + + if err := c.ExecuteRequest(request, &finalizeKotsReleaseCreate); err != nil { return nil, err } releaseInfo := types.ReleaseInfo{ AppID: appID, - Sequence: response.Sequence, + Sequence: finalizeKotsReleaseCreate.Data.KotsReleaseData.Sequence, } return &releaseInfo, nil From 9731bb938d6e5b98b9527f0599704fb843f398e8 Mon Sep 17 00:00:00 2001 From: smithers1221 Date: Tue, 10 Sep 2019 10:28:17 -0700 Subject: [PATCH 03/16] error msg for users attempting to create collectors --- client/collector.go | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/client/collector.go b/client/collector.go index 6ce04523a..920e45ef6 100644 --- a/client/collector.go +++ b/client/collector.go @@ -14,7 +14,10 @@ func (c *Client) ListCollectors(appID string) ([]types.CollectorInfo, error) { return nil, err } - // TODO: if kots message yadda yadda about updating support-bundle.yaml + if appType == "kots" { + errors.New("On a kots application, users must modify the support-bundle.yaml file in the release") + return nil, err + } shipappCollectors, err := c.ShipClient.ListCollectors(appID, appType) if err != nil { @@ -47,11 +50,30 @@ func (c *Client) ListCollectors(appID string) ([]types.CollectorInfo, error) { } func (c *Client) UpdateCollector(appID string, specID string, yaml string) (interface{}, error) { + appType, err := c.GetAppType(appID) + if err != nil { + return nil, err + } + + if appType == "kots" { + errors.New("On a kots application, users must modify the support-bundle.yaml file in the release") + return nil, err + } return c.ShipClient.UpdateCollector(appID, specID, yaml) } func (c *Client) UpdateCollectorName(appID string, specID string, name string) (interface{}, error) { + appType, err := c.GetAppType(appID) + if err != nil { + return nil, err + } + + if appType == "kots" { + errors.New("On a kots application, users must modify the support-bundle.yaml file in the release") + return nil, err + } + return c.ShipClient.UpdateCollectorName(appID, specID, name) } @@ -59,6 +81,14 @@ func (c *Client) UpdateCollectorName(appID string, specID string, name string) ( // func (c *Client) CreateCollector(appID string, name string, yaml string) (*collectors.AppCollectorInfo, error) { func (c *Client) CreateCollector(appID string, name string, yaml string) (*collectors.AppCollectorInfo, error) { + appType, err := c.GetAppType(appID) + if err != nil { + return nil, err + } + + if appType == "kots" { + return nil, errors.New("On a kots application, users must modify the support-bundle.yaml file in the release") + } return c.ShipClient.CreateCollector(appID, name, yaml) } From 88ee8be5e3bbf46e2ffd086d0bfed76ef37bd910 Mon Sep 17 00:00:00 2001 From: smithers1221 Date: Wed, 11 Sep 2019 13:04:18 -0700 Subject: [PATCH 04/16] release create --- cli/cmd/release_create.go | 66 ++++++++++++++++++++++++++------------- pkg/graphql/client.go | 6 ++-- pkg/kotsclient/release.go | 47 ++++++++++++++-------------- 3 files changed, 72 insertions(+), 47 deletions(-) diff --git a/cli/cmd/release_create.go b/cli/cmd/release_create.go index 13e66cacf..db48f6a4d 100644 --- a/cli/cmd/release_create.go +++ b/cli/cmd/release_create.go @@ -4,10 +4,21 @@ import ( "encoding/json" "fmt" "io/ioutil" + "os" + "path/filepath" + "strings" + "github.com/pkg/errors" "github.com/spf13/cobra" ) +type kotsSingleSpec struct { + Name string `json:"name"` + Path string `json:"path"` + Content string `json:"content"` + Children []string `json:"children"` +} + func (r *runners) InitReleaseCreate(parent *cobra.Command) { cmd := &cobra.Command{ Use: "create", @@ -30,19 +41,18 @@ func (r *runners) InitReleaseCreate(parent *cobra.Command) { } func (r *runners) releaseCreate(cmd *cobra.Command, args []string) error { - if r.args.createReleaseYaml == "" && r.args.createReleaseYamlFile == "" && r.args.createReleaseYamlDir == "" { - return fmt.Errorf("yaml is required") + return errors.New("yaml is required") } if r.args.createReleaseYaml != "" && r.args.createReleaseYamlFile != "" { - return fmt.Errorf("only one of yaml or yaml-file may be specified") + return errors.New("only one of yaml or yaml-file may be specified") } if r.args.createReleaseYaml == "-" { bytes, err := ioutil.ReadAll(r.stdin) if err != nil { - return err + return errors.Wrap(err, "read from stdin") } r.args.createReleaseYaml = string(bytes) } @@ -50,40 +60,52 @@ func (r *runners) releaseCreate(cmd *cobra.Command, args []string) error { if r.args.createReleaseYamlFile != "" { bytes, err := ioutil.ReadFile(r.args.createReleaseYamlFile) if err != nil { - return err + return errors.Wrap(err, "read file yaml") } r.args.createReleaseYaml = string(bytes) } if r.args.createReleaseYamlDir != "" { - files, err := ioutil.ReadDir(r.args.createReleaseYamlDir) - if err != nil { - return err - } - - var bytes []byte - - type kotsSingleSpec map[string]interface{} - var spec kotsSingleSpec var allKotsReleaseSpecs []kotsSingleSpec + err := filepath.Walk(r.args.createReleaseYamlDir, func(path string, info os.FileInfo, err error) error { + if err != nil { + return errors.Wrapf(err, "walk %s", info.Name()) + } - for _, file := range files { - bytes, err = ioutil.ReadFile(r.args.createReleaseYamlDir + "/" + file.Name()) - spec = kotsSingleSpec{"name": file.Name(), "path": file.Name(), "content": string(bytes)} - allKotsReleaseSpecs = append(allKotsReleaseSpecs, spec) + if info.IsDir() { + return nil + } + if strings.HasPrefix(info.Name(), ".") { + return nil + } + ext := filepath.Ext(info.Name()) + if ext != ".yaml" && ext != ".yml" { + return nil + } + bytes, err := ioutil.ReadFile(path) if err != nil { - return err + return errors.Wrapf(err, "read file %s", path) + } + + spec := kotsSingleSpec{ + Name: info.Name(), + Path: path, + Content: string(bytes), + Children: []string{}, } + allKotsReleaseSpecs = append(allKotsReleaseSpecs, spec) + return nil + }) + if err != nil { + return errors.Wrapf(err, "walk %s", r.args.createReleaseYamlDir) } jsonAllYamls, err := json.Marshal(allKotsReleaseSpecs) - if err != nil { - return err + return errors.Wrap(err, "marshal spec") } r.args.createReleaseYaml = string(jsonAllYamls) - } // if the --promote param was used make sure it identifies exactly one diff --git a/pkg/graphql/client.go b/pkg/graphql/client.go index 608ae48d1..083492962 100644 --- a/pkg/graphql/client.go +++ b/pkg/graphql/client.go @@ -80,8 +80,6 @@ func (c *Client) ExecuteRequest(requestObj Request, deserializeTarget interface{ resp, err := client.Do(req) if err != nil { return err - } else if resp.StatusCode != http.StatusOK { - return fmt.Errorf("unexpected status code %d", resp.StatusCode) } responseBody, err := ioutil.ReadAll(resp.Body) @@ -96,6 +94,10 @@ func (c *Client) ExecuteRequest(requestObj Request, deserializeTarget interface{ return err } + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("unexpected status code %d", resp.StatusCode) + } + if err := json.Unmarshal(responseBody, deserializeTarget); err != nil { return err } diff --git a/pkg/kotsclient/release.go b/pkg/kotsclient/release.go index 9d0434850..2e6928195 100644 --- a/pkg/kotsclient/release.go +++ b/pkg/kotsclient/release.go @@ -34,46 +34,47 @@ func (c *GraphQLClient) CreateRelease(appID string, multiyaml string) (*types.Re request := graphql.Request{ Query: ` - query createKotsRelease($appId: ID!, $spec: String!) { - createKotsRelease(appId: $appId, spec: $spec) { - sequence - } + mutation createKotsRelease($appId: ID!, $spec: String!) { + createKotsRelease(appId: $appId, spec: $spec) { + sequence + } }`, Variables: map[string]interface{}{ "appId": appID, "spec": multiyaml, }, } + fmt.Println("multiyaml:", multiyaml) if err := c.ExecuteRequest(request, &response); err != nil { fmt.Println("anything?", response.Data.KotsReleaseData.Sequence) return nil, err } - request = graphql.Request{ - Query: ` - mutation updateKotsRelease($appId: ID!, $spec: String!, $sequence: Int) { - updateKotsRelease(appId: $appId, spec: $spec, sequence: $sequence) { - sequence - } - } - `, - Variables: map[string]interface{}{ - "appId": appID, - "spec": multiyaml, - "sequence": response.Data.KotsReleaseData.Sequence, - }, - } + // request = graphql.Request{ + // Query: ` + // mutation updateKotsRelease($appId: ID!, $spec: String!, $sequence: Int) { + // updateKotsRelease(appId: $appId, spec: $spec, sequence: $sequence) { + // sequence + // } + // } + // `, + // Variables: map[string]interface{}{ + // "appId": appID, + // "spec": multiyaml, + // "sequence": response.Data.KotsReleaseData.Sequence, + // }, + // } - finalizeKotsReleaseCreate := GraphQLResponseKotsUpdateRelease{} + // finalizeKotsReleaseCreate := GraphQLResponseKotsUpdateRelease{} - if err := c.ExecuteRequest(request, &finalizeKotsReleaseCreate); err != nil { - return nil, err - } + // if err := c.ExecuteRequest(request, &finalizeKotsReleaseCreate); err != nil { + // return nil, err + // } releaseInfo := types.ReleaseInfo{ AppID: appID, - Sequence: finalizeKotsReleaseCreate.Data.KotsReleaseData.Sequence, + Sequence: response.Data.KotsReleaseData.Sequence, } return &releaseInfo, nil From 9ad1010dcfd0b16ecd0e55955579caa44f2c48d8 Mon Sep 17 00:00:00 2001 From: smithers1221 Date: Wed, 11 Sep 2019 13:22:14 -0700 Subject: [PATCH 05/16] release create --- cli/cmd/release_create.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cli/cmd/release_create.go b/cli/cmd/release_create.go index db48f6a4d..2fbc8d5ea 100644 --- a/cli/cmd/release_create.go +++ b/cli/cmd/release_create.go @@ -68,6 +68,9 @@ func (r *runners) releaseCreate(cmd *cobra.Command, args []string) error { if r.args.createReleaseYamlDir != "" { var allKotsReleaseSpecs []kotsSingleSpec err := filepath.Walk(r.args.createReleaseYamlDir, func(path string, info os.FileInfo, err error) error { + // strip r.args.createReleaseYamlDir from info.Name() + file := strings.Trim(info.Name(), r.args.createReleaseYamlDir) + fmt.Println("file", file) if err != nil { return errors.Wrapf(err, "walk %s", info.Name()) } @@ -90,7 +93,7 @@ func (r *runners) releaseCreate(cmd *cobra.Command, args []string) error { spec := kotsSingleSpec{ Name: info.Name(), - Path: path, + Path: file, Content: string(bytes), Children: []string{}, } From 4758f2bb5d25ada2464f302c4a34d3a2f0122472 Mon Sep 17 00:00:00 2001 From: smithers1221 Date: Wed, 11 Sep 2019 13:38:51 -0700 Subject: [PATCH 06/16] fixing filepath --- cli/cmd/release_create.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cli/cmd/release_create.go b/cli/cmd/release_create.go index 2fbc8d5ea..a8f299cce 100644 --- a/cli/cmd/release_create.go +++ b/cli/cmd/release_create.go @@ -68,9 +68,9 @@ func (r *runners) releaseCreate(cmd *cobra.Command, args []string) error { if r.args.createReleaseYamlDir != "" { var allKotsReleaseSpecs []kotsSingleSpec err := filepath.Walk(r.args.createReleaseYamlDir, func(path string, info os.FileInfo, err error) error { - // strip r.args.createReleaseYamlDir from info.Name() - file := strings.Trim(info.Name(), r.args.createReleaseYamlDir) - fmt.Println("file", file) + + singlefile := strings.TrimPrefix(path, r.args.createReleaseYamlDir) + if err != nil { return errors.Wrapf(err, "walk %s", info.Name()) } @@ -93,7 +93,7 @@ func (r *runners) releaseCreate(cmd *cobra.Command, args []string) error { spec := kotsSingleSpec{ Name: info.Name(), - Path: file, + Path: singlefile, Content: string(bytes), Children: []string{}, } From 6c4423afdcb78c85b08dfee32e51e19373281a09 Mon Sep 17 00:00:00 2001 From: smithers1221 Date: Wed, 11 Sep 2019 17:07:49 -0700 Subject: [PATCH 07/16] release promote --- client/release.go | 42 +++++++++++- pkg/kotsclient/client.go | 4 +- pkg/kotsclient/release.go | 132 ++++++++++++++++++++++++++++++++------ 3 files changed, 153 insertions(+), 25 deletions(-) diff --git a/client/release.go b/client/release.go index a9861540f..ce6da92fe 100644 --- a/client/release.go +++ b/client/release.go @@ -44,8 +44,43 @@ func (c *Client) ListReleases(appID string) ([]types.ReleaseInfo, error) { } return releaseInfos, nil + + // TODO: need to fix active channels output for ship and kots apps } else if appType == "ship" { - return c.ShipClient.ListReleases(appID) + shipReleases, err := c.ShipClient.ListReleases(appID) + if err != nil { + return nil, err + } + + releaseInfos := make([]types.ReleaseInfo, 0, 0) + for _, shipRelease := range shipReleases { + activeChannels := make([]types.Channel, 0, 0) + for _, shipReleaseChannel := range shipRelease.ActiveChannels { + activeChannel := types.Channel{ + ID: shipReleaseChannel.ID, + Name: shipReleaseChannel.Name, + Description: shipReleaseChannel.Description, + } + + activeChannels = append(activeChannels, activeChannel) + } + releaseInfo := types.ReleaseInfo{ + AppID: shipRelease.AppID, + CreatedAt: shipRelease.CreatedAt, + EditedAt: shipRelease.EditedAt, + Editable: shipRelease.Editable, + Sequence: shipRelease.Sequence, + Version: shipRelease.Version, + ActiveChannels: activeChannels, + } + + releaseInfos = append(releaseInfos, releaseInfo) + } + + return releaseInfos, nil + + } else if appType == "kots" { + return c.KotsClient.ListReleases(appID) } return nil, errors.New("unknown app type") @@ -110,8 +145,9 @@ func (c *Client) PromoteRelease(appID string, sequence int64, label string, note return c.PlatformClient.PromoteRelease(appID, sequence, label, notes, required, channelIDs...) } else if appType == "ship" { return c.ShipClient.PromoteRelease(appID, sequence, label, notes, channelIDs...) + } else if appType == "kots" { + return c.KotsClient.PromoteRelease(appID, sequence, label, notes, channelIDs...) } - return errors.New("unknown app type") } @@ -126,6 +162,8 @@ func (c *Client) LintRelease(appID string, yaml string) ([]types.LintMessage, er // return c.PlatformClient.LintRelease(appID, yaml) } else if appType == "ship" { return c.ShipClient.LintRelease(appID, yaml) + } else if appType == "kots" { + return nil, errors.New("Linting is not yet supported for Kots applications") } return nil, errors.New("unknown app type") diff --git a/pkg/kotsclient/client.go b/pkg/kotsclient/client.go index e3ef72609..4836b0cd7 100644 --- a/pkg/kotsclient/client.go +++ b/pkg/kotsclient/client.go @@ -10,9 +10,9 @@ type Client interface { GetApp(appID string) (*types.App, error) CreateRelease(appID string, multiyaml string) (*types.ReleaseInfo, error) - // ListReleases(appID string) ([]types.ReleaseInfo, error) + ListReleases(appID string) ([]types.ReleaseInfo, error) // UpdateRelease(appID string, sequence int64, yaml string) error - // PromoteRelease(appID string, sequence int64, label string, notes string, channelIDs ...string) error + PromoteRelease(appID string, sequence int64, label string, notes string, channelIDs ...string) error ListChannels(string) ([]types.Channel, error) CreateChannel(string, string, string) error diff --git a/pkg/kotsclient/release.go b/pkg/kotsclient/release.go index 2e6928195..670b300fc 100644 --- a/pkg/kotsclient/release.go +++ b/pkg/kotsclient/release.go @@ -2,9 +2,12 @@ package kotsclient import ( "fmt" + "time" + "github.com/pkg/errors" "github.com/replicatedhq/replicated/pkg/graphql" "github.com/replicatedhq/replicated/pkg/types" + "github.com/replicatedhq/replicated/pkg/util" ) type GraphQLResponseKotsCreateRelease struct { @@ -29,6 +32,22 @@ type KotsUpdateReleaseData struct { KotsReleaseData KotsReleaseSequence `json:"createKotsRelease"` } +type GraphQLResponseListReleases struct { + Data *KotsReleasesData `json:"data,omitempty"` + Errors []graphql.GQLError `json:"errors,omitempty"` +} + +type KotsReleasesData struct { + KotsReleases []*KotsRelease `json:"allKotsReleases"` +} + +type KotsRelease struct { + ID string `json:"id"` + Sequence int64 `json:"sequence"` + CreatedAt string `json:"created"` + ReleaseNotes string `json:"releaseNotes"` +} + func (c *GraphQLClient) CreateRelease(appID string, multiyaml string) (*types.ReleaseInfo, error) { response := GraphQLResponseKotsCreateRelease{} @@ -51,27 +70,6 @@ func (c *GraphQLClient) CreateRelease(appID string, multiyaml string) (*types.Re return nil, err } - // request = graphql.Request{ - // Query: ` - // mutation updateKotsRelease($appId: ID!, $spec: String!, $sequence: Int) { - // updateKotsRelease(appId: $appId, spec: $spec, sequence: $sequence) { - // sequence - // } - // } - // `, - // Variables: map[string]interface{}{ - // "appId": appID, - // "spec": multiyaml, - // "sequence": response.Data.KotsReleaseData.Sequence, - // }, - // } - - // finalizeKotsReleaseCreate := GraphQLResponseKotsUpdateRelease{} - - // if err := c.ExecuteRequest(request, &finalizeKotsReleaseCreate); err != nil { - // return nil, err - // } - releaseInfo := types.ReleaseInfo{ AppID: appID, Sequence: response.Data.KotsReleaseData.Sequence, @@ -79,3 +77,95 @@ func (c *GraphQLClient) CreateRelease(appID string, multiyaml string) (*types.Re return &releaseInfo, nil } + +var allKotsReleases = ` + query allKotsReleases($appId: ID!, $pageSize: Int, $currentPage: Int) { + allKotsReleases(appId: $appId, pageSize: $pageSize, currentPage: $currentPage) { + sequence + spec + created + releaseNotes + channels { + id + name + currentVersion + numReleases + } + isReleaseNotEditable + } + } +` + +func (c *GraphQLClient) ListReleases(appID string) ([]types.ReleaseInfo, error) { + response := GraphQLResponseListReleases{} + + request := graphql.Request{ + Query: allKotsReleases, + Variables: map[string]interface{}{ + "appId": appID, + }, + } + + if err := c.ExecuteRequest(request, &response); err != nil { + return nil, err + } + + location, err := time.LoadLocation("Local") + if err != nil { + return nil, err + } + + releaseInfos := make([]types.ReleaseInfo, 0, 0) + for _, kotsRelease := range response.Data.KotsReleases { + createdAt, err := util.ParseTime(kotsRelease.CreatedAt) + if err != nil { + return nil, err + } + releaseInfo := types.ReleaseInfo{ + AppID: appID, + CreatedAt: createdAt.In(location), + EditedAt: time.Now(), + Editable: false, + Sequence: kotsRelease.Sequence, + Version: "ba", + } + + releaseInfos = append(releaseInfos, releaseInfo) + } + + return releaseInfos, nil +} + +var promoteKotsRelease = ` +mutation promoteKotsRelease($appId: ID!, $sequence: Int, $channelIds: [String], $versionLabel: String!, $releaseNotes: String) { + promoteKotsRelease(appId: $appId, sequence: $sequence, channelIds: $channelIds, versionLabel: $versionLabel, releaseNotes: $releaseNotes) { + sequence + } + } +` + +func (c *GraphQLClient) PromoteRelease(appID string, sequence int64, label string, notes string, channelIDs ...string) error { + response := graphql.ResponseErrorOnly{} + + request := graphql.Request{ + Query: promoteKotsRelease, + Variables: map[string]interface{}{ + "appId": appID, + "sequence": sequence, + "versionLabel": label, + "releaseNotes": notes, + "troubleshootSpecId": "", + "channelIds": channelIDs, + }, + } + + if err := c.ExecuteRequest(request, &response); err != nil { + return err + } + + if len(response.Errors) != 0 { + return errors.New(response.Errors[0].Message) + } + + return nil +} From ba4ea4a461d1add21a55e171d61c65f16a102422 Mon Sep 17 00:00:00 2001 From: smithers1221 Date: Wed, 11 Sep 2019 18:51:38 -0700 Subject: [PATCH 08/16] kots release update and promote --- cli/cmd/release_update.go | 57 ++++++++++++++++++++++++++++++++++++--- client/release.go | 17 ++++++++++-- pkg/kotsclient/client.go | 2 +- pkg/kotsclient/release.go | 47 ++++++++++++++++++++++++++++++++ 4 files changed, 117 insertions(+), 6 deletions(-) diff --git a/cli/cmd/release_update.go b/cli/cmd/release_update.go index c73a66017..9f26b1c5a 100644 --- a/cli/cmd/release_update.go +++ b/cli/cmd/release_update.go @@ -1,11 +1,16 @@ package cmd import ( - "errors" + "encoding/json" + // "errors" "fmt" "io/ioutil" + "os" + "path/filepath" "strconv" + "strings" + "github.com/pkg/errors" "github.com/spf13/cobra" ) @@ -20,12 +25,13 @@ func (r *runners) InitReleaseUpdate(parent *cobra.Command) { cmd.Flags().StringVar(&r.args.updateReleaseYaml, "yaml", "", "The new YAML config for this release. Use '-' to read from stdin. Cannot be used with the `yaml-file` flag.") cmd.Flags().StringVar(&r.args.updateReleaseYamlFile, "yaml-file", "", "The file name with YAML config for this release. Cannot be used with the `yaml` flag.") + cmd.Flags().StringVar(&r.args.updateReleaseYamlDir, "yaml-dir", "", "The directory containing the 5 required YAML configs for a Kots release. Cannot be used with the `yaml` flag.") cmd.RunE = r.releaseUpdate } func (r *runners) releaseUpdate(cmd *cobra.Command, args []string) error { - if r.args.updateReleaseYaml == "" && r.args.updateReleaseYamlFile == "" { + if r.args.updateReleaseYaml == "" && r.args.updateReleaseYamlFile == "" && r.args.updateReleaseYamlDir == "" { return fmt.Errorf("yaml is required") } @@ -57,7 +63,52 @@ func (r *runners) releaseUpdate(cmd *cobra.Command, args []string) error { return fmt.Errorf("invalid release sequence: %s", args[0]) } - if err := r.platformAPI.UpdateRelease(r.appID, seq, r.args.updateReleaseYaml); err != nil { + if r.args.updateReleaseYamlDir != "" { + var allKotsReleaseSpecs []kotsSingleSpec + err := filepath.Walk(r.args.updateReleaseYamlDir, func(path string, info os.FileInfo, err error) error { + + singlefile := strings.TrimPrefix(path, r.args.updateReleaseYamlDir) + + if err != nil { + return errors.Wrapf(err, "walk %s", info.Name()) + } + + if info.IsDir() { + return nil + } + if strings.HasPrefix(info.Name(), ".") { + return nil + } + ext := filepath.Ext(info.Name()) + if ext != ".yaml" && ext != ".yml" { + return nil + } + + bytes, err := ioutil.ReadFile(path) + if err != nil { + return errors.Wrapf(err, "read file %s", path) + } + + spec := kotsSingleSpec{ + Name: info.Name(), + Path: singlefile, + Content: string(bytes), + Children: []string{}, + } + allKotsReleaseSpecs = append(allKotsReleaseSpecs, spec) + return nil + }) + if err != nil { + return errors.Wrapf(err, "walk %s", r.args.updateReleaseYamlDir) + } + + jsonAllYamls, err := json.Marshal(allKotsReleaseSpecs) + if err != nil { + return errors.Wrap(err, "marshal spec") + } + r.args.updateReleaseYaml = string(jsonAllYamls) + } + if err := r.api.UpdateRelease(r.appID, seq, r.args.updateReleaseYaml); err != nil { return fmt.Errorf("Failure setting new yaml config for release: %v", err) } diff --git a/client/release.go b/client/release.go index ce6da92fe..7ebaa6c33 100644 --- a/client/release.go +++ b/client/release.go @@ -127,8 +127,21 @@ func (c *Client) CreateRelease(appID string, yaml string) (*types.ReleaseInfo, e return nil, errors.New("unknown app type") } -func (c *Client) UpdateRelease(appID string, sequence int64, releaseOptions interface{}) error { - return nil +func (c *Client) UpdateRelease(appID string, sequence int64, yaml string) error { + + appType, err := c.GetAppType(appID) + if err != nil { + return err + } + + if appType == "platform" { + return c.PlatformClient.UpdateRelease(appID, sequence, yaml) + } else if appType == "ship" { + return c.ShipClient.UpdateRelease(appID, sequence, yaml) + } else if appType == "kots" { + return c.KotsClient.UpdateRelease(appID, sequence, yaml) + } + return errors.New("unknown app type") } func (c *Client) GetRelease(appID string, sequence int64) (interface{}, error) { diff --git a/pkg/kotsclient/client.go b/pkg/kotsclient/client.go index 4836b0cd7..1036199e2 100644 --- a/pkg/kotsclient/client.go +++ b/pkg/kotsclient/client.go @@ -11,7 +11,7 @@ type Client interface { CreateRelease(appID string, multiyaml string) (*types.ReleaseInfo, error) ListReleases(appID string) ([]types.ReleaseInfo, error) - // UpdateRelease(appID string, sequence int64, yaml string) error + UpdateRelease(appID string, sequence int64, yaml string) error PromoteRelease(appID string, sequence int64, label string, notes string, channelIDs ...string) error ListChannels(string) ([]types.Channel, error) diff --git a/pkg/kotsclient/release.go b/pkg/kotsclient/release.go index 670b300fc..e12e0b82a 100644 --- a/pkg/kotsclient/release.go +++ b/pkg/kotsclient/release.go @@ -48,6 +48,19 @@ type KotsRelease struct { ReleaseNotes string `json:"releaseNotes"` } +type GraphQLResponseUpdateKotsRelease struct { + Data *KotsReleaseUpdateData `json:"data,omitempty"` +} + +type KotsReleaseUpdateData struct { + UpdateKotsRelease *UpdateKotsRelease `json:"updateKotsRelease"` +} + +type UpdateKotsRelease struct { + ID string `json:"id"` + Config string `json:"spec,omitempty"` +} + func (c *GraphQLClient) CreateRelease(appID string, multiyaml string) (*types.ReleaseInfo, error) { response := GraphQLResponseKotsCreateRelease{} @@ -78,6 +91,40 @@ func (c *GraphQLClient) CreateRelease(appID string, multiyaml string) (*types.Re return &releaseInfo, nil } +var updateKotsRelease = ` + mutation updateKotsRelease($appId: ID!, $spec: String!, $sequence: Int) { + updateKotsRelease(appId: $appId, spec: $spec, sequence: $sequence) { + sequence + } + } +` + +func (c *GraphQLClient) UpdateRelease(appID string, sequence int64, multiyaml string) error { + response := GraphQLResponseUpdateKotsRelease{} + + request := graphql.Request{ + Query: ` + mutation updateKotsRelease($appId: ID!, $spec: String!, $sequence: Int) { + updateKotsRelease(appId: $appId, spec: $spec, sequence: $sequence) { + sequence + } + } + `, + + Variables: map[string]interface{}{ + "appId": appID, + "spec": multiyaml, + "sequence": sequence, + }, + } + + if err := c.ExecuteRequest(request, &response); err != nil { + return err + } + + return nil +} + var allKotsReleases = ` query allKotsReleases($appId: ID!, $pageSize: Int, $currentPage: Int) { allKotsReleases(appId: $appId, pageSize: $pageSize, currentPage: $currentPage) { From 6c268cd2fd37064413225c070b653bc571d50dee Mon Sep 17 00:00:00 2001 From: smithers1221 Date: Thu, 12 Sep 2019 16:17:23 -0700 Subject: [PATCH 09/16] showing active channels on release ls --- pkg/kotsclient/app.go | 17 +++++++++++++++-- pkg/kotsclient/channel.go | 17 ++++++----------- pkg/kotsclient/release.go | 32 ++++++++++++++++++++++---------- pkg/shipclient/app.go | 2 +- pkg/shipclient/channel.go | 7 +++---- pkg/shipclient/release.go | 33 +++++++++++++++++++++++---------- 6 files changed, 70 insertions(+), 38 deletions(-) diff --git a/pkg/kotsclient/app.go b/pkg/kotsclient/app.go index c525b7b45..007bb79b5 100644 --- a/pkg/kotsclient/app.go +++ b/pkg/kotsclient/app.go @@ -20,7 +20,11 @@ type KotsAppsData struct { } type KotsAppChannelData struct { - ID string `json:"id"` + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + CurrentSequence int64 `json:"currentSequence"` + CurrentVersion string `json:"currentVersion"` } type KotsApp struct { @@ -63,13 +67,22 @@ func (c *GraphQLClient) ListApps() ([]types.AppAndChannels, error) { appsAndChannels := make([]types.AppAndChannels, 0, 0) for _, kotsapp := range response.Data.Kots.KotsApps { - + channels := make([]types.Channel, 0, 0) + for _, kotsChannel := range kotsapp.Channels { + channel := types.Channel{ + ID: kotsChannel.ID, + Name: kotsChannel.Name, + Description: kotsChannel.Description, + } + channels = append(channels, channel) + } appAndChannels := types.AppAndChannels{ App: &types.App{ ID: kotsapp.ID, Name: kotsapp.Name, Slug: kotsapp.Slug, }, + Channels: channels, } appsAndChannels = append(appsAndChannels, appAndChannels) diff --git a/pkg/kotsclient/channel.go b/pkg/kotsclient/channel.go index 8ac662a64..a8293f569 100644 --- a/pkg/kotsclient/channel.go +++ b/pkg/kotsclient/channel.go @@ -16,12 +16,9 @@ type KotsChannelData struct { } type KotsChannel struct { - ID string `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - - CurrentSequence int64 `json:"currentSequence"` - CurrentVersion string `json:"currentVersion"` + ID string `json:"id"` + Name string `json:"name"` + CurrentVersion string `json:"currentVersion"` } func (c *GraphQLClient) ListChannels(appID string) ([]types.Channel, error) { @@ -85,11 +82,9 @@ func (c *GraphQLClient) ListChannels(appID string) ([]types.Channel, error) { channels := make([]types.Channel, 0, 0) for _, kotsChannel := range response.Data.KotsChannels { channel := types.Channel{ - ID: kotsChannel.ID, - Name: kotsChannel.Name, - Description: kotsChannel.Description, - ReleaseSequence: kotsChannel.CurrentSequence, - ReleaseLabel: kotsChannel.CurrentVersion, + ID: kotsChannel.ID, + Name: kotsChannel.Name, + ReleaseLabel: kotsChannel.CurrentVersion, } channels = append(channels, channel) diff --git a/pkg/kotsclient/release.go b/pkg/kotsclient/release.go index e12e0b82a..c301a11cd 100644 --- a/pkg/kotsclient/release.go +++ b/pkg/kotsclient/release.go @@ -42,10 +42,11 @@ type KotsReleasesData struct { } type KotsRelease struct { - ID string `json:"id"` - Sequence int64 `json:"sequence"` - CreatedAt string `json:"created"` - ReleaseNotes string `json:"releaseNotes"` + ID string `json:"id"` + Sequence int64 `json:"sequence"` + CreatedAt string `json:"created"` + ReleaseNotes string `json:"releaseNotes"` + Channels []*KotsChannel `json:"channels"` } type GraphQLResponseUpdateKotsRelease struct { @@ -164,17 +165,28 @@ func (c *GraphQLClient) ListReleases(appID string) ([]types.ReleaseInfo, error) releaseInfos := make([]types.ReleaseInfo, 0, 0) for _, kotsRelease := range response.Data.KotsReleases { + activeChannels := make([]types.Channel, 0, 0) createdAt, err := util.ParseTime(kotsRelease.CreatedAt) if err != nil { return nil, err } + + for _, kotsReleaseChannel := range kotsRelease.Channels { + activeChannel := types.Channel{ + ID: kotsReleaseChannel.ID, + Name: kotsReleaseChannel.Name, + } + activeChannels = append(activeChannels, activeChannel) + + } releaseInfo := types.ReleaseInfo{ - AppID: appID, - CreatedAt: createdAt.In(location), - EditedAt: time.Now(), - Editable: false, - Sequence: kotsRelease.Sequence, - Version: "ba", + AppID: appID, + CreatedAt: createdAt.In(location), + EditedAt: time.Now(), + Editable: false, + Sequence: kotsRelease.Sequence, + Version: "ba", + ActiveChannels: activeChannels, } releaseInfos = append(releaseInfos, releaseInfo) diff --git a/pkg/shipclient/app.go b/pkg/shipclient/app.go index eb92b146d..3ae7b6c03 100644 --- a/pkg/shipclient/app.go +++ b/pkg/shipclient/app.go @@ -67,7 +67,6 @@ query { Name: shipChannel.Name, Description: shipChannel.Description, } - channels = append(channels, channel) } @@ -77,6 +76,7 @@ query { Name: app.Name, Slug: app.Slug, }, + Channels: channels, } appsAndChannels = append(appsAndChannels, appAndChannels) diff --git a/pkg/shipclient/channel.go b/pkg/shipclient/channel.go index cdb1ad529..9c0b81247 100644 --- a/pkg/shipclient/channel.go +++ b/pkg/shipclient/channel.go @@ -16,10 +16,9 @@ type ShipChannelData struct { } type ShipChannel struct { - ID string `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - + ID string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` CurrentSequence int64 `json:"currentSequence"` CurrentVersion string `json:"currentVersion"` } diff --git a/pkg/shipclient/release.go b/pkg/shipclient/release.go index 2e78397a8..733760fe6 100644 --- a/pkg/shipclient/release.go +++ b/pkg/shipclient/release.go @@ -23,10 +23,11 @@ type ShipReleasesData struct { } type ShipRelease struct { - ID string `json:"id"` - Sequence int64 `json:"sequence"` - CreatedAt string `json:"created"` - ReleaseNotes string `json:"releaseNotes"` + ID string `json:"id"` + Sequence int64 `json:"sequence"` + CreatedAt string `json:"created"` + ReleaseNotes string `json:"releaseNotes"` + Channels []*ShipChannel `json:"channels"` } type GraphQLResponseFinalizeRelease struct { @@ -117,17 +118,29 @@ func (c *GraphQLClient) ListReleases(appID string) ([]types.ReleaseInfo, error) releaseInfos := make([]types.ReleaseInfo, 0, 0) for _, shipRelease := range response.Data.ShipReleases { + activeChannels := make([]types.Channel, 0, 0) createdAt, err := util.ParseTime(shipRelease.CreatedAt) if err != nil { return nil, err } + + for _, shipReleaseChannel := range shipRelease.Channels { + activeChannel := types.Channel{ + ID: shipReleaseChannel.ID, + Name: shipReleaseChannel.Name, + } + activeChannels = append(activeChannels, activeChannel) + + } + releaseInfo := types.ReleaseInfo{ - AppID: appID, - CreatedAt: createdAt.In(location), - EditedAt: time.Now(), - Editable: false, - Sequence: shipRelease.Sequence, - Version: "ba", + AppID: appID, + CreatedAt: createdAt.In(location), + EditedAt: time.Now(), + Editable: false, + Sequence: shipRelease.Sequence, + Version: "ba", + ActiveChannels: activeChannels, } releaseInfos = append(releaseInfos, releaseInfo) From 81fd2a0b3f214bd66e175609f91b98fc984bcfc8 Mon Sep 17 00:00:00 2001 From: smithers1221 Date: Fri, 13 Sep 2019 09:49:59 -0700 Subject: [PATCH 10/16] replicated vendor cli for kots/release --- client/channel.go | 8 -- pkg/kotsclient/channel.go | 256 +++++++++++++++++++------------------- pkg/kotsclient/client.go | 4 +- 3 files changed, 127 insertions(+), 141 deletions(-) diff --git a/client/channel.go b/client/channel.go index cc9778558..5033fe3a6 100644 --- a/client/channel.go +++ b/client/channel.go @@ -34,8 +34,6 @@ func (c *Client) ListChannels(appID string) ([]types.Channel, error) { return channels, nil } else if appType == "ship" { return c.ShipClient.ListChannels(appID) - } else if appType == "kots" { - return c.KotsClient.ListChannels(appID) } return nil, errors.New("unknown app type") @@ -65,12 +63,6 @@ func (c *Client) CreateChannel(appID string, name string, description string) ([ return nil, err } return c.ShipClient.ListChannels(appID) - } else if appType == "kots" { - if err := c.KotsClient.CreateChannel(appID, name, description); err != nil { - return nil, err - } - return c.KotsClient.ListChannels(appID) } - return nil, errors.New("unknown app type") } diff --git a/pkg/kotsclient/channel.go b/pkg/kotsclient/channel.go index a8293f569..4d4f9cf7e 100644 --- a/pkg/kotsclient/channel.go +++ b/pkg/kotsclient/channel.go @@ -1,19 +1,13 @@ package kotsclient -import ( - "github.com/pkg/errors" - "github.com/replicatedhq/replicated/pkg/graphql" - "github.com/replicatedhq/replicated/pkg/types" -) - -type GraphQLResponseListChannels struct { - Data *KotsChannelData `json:"data,omitempty"` - Errors []graphql.GQLError `json:"errors,omitempty"` -} +// type GraphQLResponseListChannels struct { +// Data *KotsChannelData `json:"data,omitempty"` +// Errors []graphql.GQLError `json:"errors,omitempty"` +// } -type KotsChannelData struct { - KotsChannels []*KotsChannel `json:"getKotsAppChannels"` -} +// type KotsChannelData struct { +// KotsChannels []*KotsChannel `json:"getKotsAppChannels"` +// } type KotsChannel struct { ID string `json:"id"` @@ -21,121 +15,121 @@ type KotsChannel struct { CurrentVersion string `json:"currentVersion"` } -func (c *GraphQLClient) ListChannels(appID string) ([]types.Channel, error) { - response := GraphQLResponseListChannels{} - - request := graphql.Request{ - Query: ` - query getKotsAppChannels($appId: ID!) { - getKotsAppChannels(appId: $appId) { - id - appId - name - currentVersion - currentReleaseDate - currentSpec - numReleases - description - channelIcon - created - updated - isDefault - isArchived - adoptionRate { - releaseSequence - semver - count - percent - totalOnChannel - } - customers { - id - name - avatar - shipInstallStatus { - status - } - } - githubRef { - owner - repoFullName - branch - path - } - releases { - sequence - semver - } - } - } - `, - - Variables: map[string]interface{}{ - "appId": appID, - }, - } - - if err := c.ExecuteRequest(request, &response); err != nil { - return nil, err - } - - channels := make([]types.Channel, 0, 0) - for _, kotsChannel := range response.Data.KotsChannels { - channel := types.Channel{ - ID: kotsChannel.ID, - Name: kotsChannel.Name, - ReleaseLabel: kotsChannel.CurrentVersion, - } - - channels = append(channels, channel) - } - - return channels, nil -} - -func (c *GraphQLClient) CreateChannel(appID string, name string, description string) error { - response := graphql.ResponseErrorOnly{} - - request := graphql.Request{ - Query: ` - mutation createKotsChannel($appId: String!, $channelName: String!, $description: String) { - createKotsChannel(appId: $appId, channelName: $channelName, description: $description) { - id - name - description - currentVersion - currentReleaseDate - numReleases - created - updated - isDefault - isArchived - } - } - `, - Variables: map[string]interface{}{ - "appId": appID, - "channelName": name, - "description": description, - }, - } - - if err := c.ExecuteRequest(request, &response); err != nil { - return err - } - - if len(response.Errors) != 0 { - return errors.New(response.Errors[0].Message) - } - - return nil - -} - -func ArchiveChannel(appID string, channelID string) error { - return nil -} - -func GetChannel(appID string, channelID string) (interface{}, []interface{}, error) { - return nil, nil, nil -} +// func (c *GraphQLClient) ListChannels(appID string) ([]types.Channel, error) { +// response := GraphQLResponseListChannels{} + +// request := graphql.Request{ +// Query: ` +// query getKotsAppChannels($appId: ID!) { +// getKotsAppChannels(appId: $appId) { +// id +// appId +// name +// currentVersion +// currentReleaseDate +// currentSpec +// numReleases +// description +// channelIcon +// created +// updated +// isDefault +// isArchived +// adoptionRate { +// releaseSequence +// semver +// count +// percent +// totalOnChannel +// } +// customers { +// id +// name +// avatar +// shipInstallStatus { +// status +// } +// } +// githubRef { +// owner +// repoFullName +// branch +// path +// } +// releases { +// sequence +// semver +// } +// } +// } +// `, + +// Variables: map[string]interface{}{ +// "appId": appID, +// }, +// } + +// if err := c.ExecuteRequest(request, &response); err != nil { +// return nil, err +// } + +// channels := make([]types.Channel, 0, 0) +// for _, kotsChannel := range response.Data.KotsChannels { +// channel := types.Channel{ +// ID: kotsChannel.ID, +// Name: kotsChannel.Name, +// ReleaseLabel: kotsChannel.CurrentVersion, +// } + +// channels = append(channels, channel) +// } + +// return channels, nil +// } + +// func (c *GraphQLClient) CreateChannel(appID string, name string, description string) error { +// response := graphql.ResponseErrorOnly{} + +// request := graphql.Request{ +// Query: ` +// mutation createKotsChannel($appId: String!, $channelName: String!, $description: String) { +// createKotsChannel(appId: $appId, channelName: $channelName, description: $description) { +// id +// name +// description +// currentVersion +// currentReleaseDate +// numReleases +// created +// updated +// isDefault +// isArchived +// } +// } +// `, +// Variables: map[string]interface{}{ +// "appId": appID, +// "channelName": name, +// "description": description, +// }, +// } + +// if err := c.ExecuteRequest(request, &response); err != nil { +// return err +// } + +// if len(response.Errors) != 0 { +// return errors.New(response.Errors[0].Message) +// } + +// return nil + +// } + +// func ArchiveChannel(appID string, channelID string) error { +// return nil +// } + +// func GetChannel(appID string, channelID string) (interface{}, []interface{}, error) { +// return nil, nil, nil +// } diff --git a/pkg/kotsclient/client.go b/pkg/kotsclient/client.go index 1036199e2..0df28c4e2 100644 --- a/pkg/kotsclient/client.go +++ b/pkg/kotsclient/client.go @@ -14,8 +14,8 @@ type Client interface { UpdateRelease(appID string, sequence int64, yaml string) error PromoteRelease(appID string, sequence int64, label string, notes string, channelIDs ...string) error - ListChannels(string) ([]types.Channel, error) - CreateChannel(string, string, string) error + // ListChannels(string) ([]types.Channel, error) + // CreateChannel(string, string, string) error } type AppOptions struct { From 419892b181093098c98da4146498f63f7f1f89c2 Mon Sep 17 00:00:00 2001 From: smithers1221 Date: Fri, 13 Sep 2019 10:35:51 -0700 Subject: [PATCH 11/16] edit, remove prints --- cli/cmd/release_create.go | 2 +- cli/cmd/release_update.go | 2 +- pkg/kotsclient/release.go | 3 --- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/cli/cmd/release_create.go b/cli/cmd/release_create.go index a8f299cce..e7eb8d135 100644 --- a/cli/cmd/release_create.go +++ b/cli/cmd/release_create.go @@ -31,7 +31,7 @@ func (r *runners) InitReleaseCreate(parent *cobra.Command) { cmd.Flags().StringVar(&r.args.createReleaseYaml, "yaml", "", "The YAML config for this release. Use '-' to read from stdin. Cannot be used with the `yaml-file` falg.") cmd.Flags().StringVar(&r.args.createReleaseYamlFile, "yaml-file", "", "The file name with YAML config for this release. Cannot be used with the `yaml` flag.") - cmd.Flags().StringVar(&r.args.createReleaseYamlDir, "yaml-dir", "", "The directory containing the 5 required YAML configs for a Kots release. Cannot be used with the `yaml` flag.") + cmd.Flags().StringVar(&r.args.createReleaseYamlDir, "yaml-dir", "", "The directory containing multiple yamls for a Kots release. Cannot be used with the `yaml` flag.") cmd.Flags().StringVar(&r.args.createReleasePromote, "promote", "", "Channel name or id to promote this release to") cmd.Flags().StringVar(&r.args.createReleasePromoteNotes, "release-notes", "", "When used with --promote , sets the **markdown** release notes") cmd.Flags().BoolVar(&r.args.createReleasePromoteRequired, "required", false, "When used with --promote , marks this release as required during upgrades.") diff --git a/cli/cmd/release_update.go b/cli/cmd/release_update.go index 9f26b1c5a..33cc8ae5e 100644 --- a/cli/cmd/release_update.go +++ b/cli/cmd/release_update.go @@ -25,7 +25,7 @@ func (r *runners) InitReleaseUpdate(parent *cobra.Command) { cmd.Flags().StringVar(&r.args.updateReleaseYaml, "yaml", "", "The new YAML config for this release. Use '-' to read from stdin. Cannot be used with the `yaml-file` flag.") cmd.Flags().StringVar(&r.args.updateReleaseYamlFile, "yaml-file", "", "The file name with YAML config for this release. Cannot be used with the `yaml` flag.") - cmd.Flags().StringVar(&r.args.updateReleaseYamlDir, "yaml-dir", "", "The directory containing the 5 required YAML configs for a Kots release. Cannot be used with the `yaml` flag.") + cmd.Flags().StringVar(&r.args.updateReleaseYamlDir, "yaml-dir", "", "The directory containing multiple yamls for a Kots release. Cannot be used with the `yaml` flag.") cmd.RunE = r.releaseUpdate } diff --git a/pkg/kotsclient/release.go b/pkg/kotsclient/release.go index c301a11cd..0ab59ff71 100644 --- a/pkg/kotsclient/release.go +++ b/pkg/kotsclient/release.go @@ -1,7 +1,6 @@ package kotsclient import ( - "fmt" "time" "github.com/pkg/errors" @@ -77,10 +76,8 @@ func (c *GraphQLClient) CreateRelease(appID string, multiyaml string) (*types.Re "spec": multiyaml, }, } - fmt.Println("multiyaml:", multiyaml) if err := c.ExecuteRequest(request, &response); err != nil { - fmt.Println("anything?", response.Data.KotsReleaseData.Sequence) return nil, err } From 2bf0fb6dee2714aec5df2b60d1edf5b47a1da0ca Mon Sep 17 00:00:00 2001 From: smithers1221 Date: Mon, 16 Sep 2019 09:47:59 -0700 Subject: [PATCH 12/16] removing commented out stuff --- client/collector.go | 8 --- pkg/kotsclient/channel.go | 128 -------------------------------------- pkg/kotsclient/client.go | 3 - 3 files changed, 139 deletions(-) diff --git a/client/collector.go b/client/collector.go index 920e45ef6..cf3da0d5b 100644 --- a/client/collector.go +++ b/client/collector.go @@ -81,14 +81,6 @@ func (c *Client) UpdateCollectorName(appID string, specID string, name string) ( // func (c *Client) CreateCollector(appID string, name string, yaml string) (*collectors.AppCollectorInfo, error) { func (c *Client) CreateCollector(appID string, name string, yaml string) (*collectors.AppCollectorInfo, error) { - appType, err := c.GetAppType(appID) - if err != nil { - return nil, err - } - - if appType == "kots" { - return nil, errors.New("On a kots application, users must modify the support-bundle.yaml file in the release") - } return c.ShipClient.CreateCollector(appID, name, yaml) } diff --git a/pkg/kotsclient/channel.go b/pkg/kotsclient/channel.go index 4d4f9cf7e..d37e2db35 100644 --- a/pkg/kotsclient/channel.go +++ b/pkg/kotsclient/channel.go @@ -1,135 +1,7 @@ package kotsclient -// type GraphQLResponseListChannels struct { -// Data *KotsChannelData `json:"data,omitempty"` -// Errors []graphql.GQLError `json:"errors,omitempty"` -// } - -// type KotsChannelData struct { -// KotsChannels []*KotsChannel `json:"getKotsAppChannels"` -// } - type KotsChannel struct { ID string `json:"id"` Name string `json:"name"` CurrentVersion string `json:"currentVersion"` } - -// func (c *GraphQLClient) ListChannels(appID string) ([]types.Channel, error) { -// response := GraphQLResponseListChannels{} - -// request := graphql.Request{ -// Query: ` -// query getKotsAppChannels($appId: ID!) { -// getKotsAppChannels(appId: $appId) { -// id -// appId -// name -// currentVersion -// currentReleaseDate -// currentSpec -// numReleases -// description -// channelIcon -// created -// updated -// isDefault -// isArchived -// adoptionRate { -// releaseSequence -// semver -// count -// percent -// totalOnChannel -// } -// customers { -// id -// name -// avatar -// shipInstallStatus { -// status -// } -// } -// githubRef { -// owner -// repoFullName -// branch -// path -// } -// releases { -// sequence -// semver -// } -// } -// } -// `, - -// Variables: map[string]interface{}{ -// "appId": appID, -// }, -// } - -// if err := c.ExecuteRequest(request, &response); err != nil { -// return nil, err -// } - -// channels := make([]types.Channel, 0, 0) -// for _, kotsChannel := range response.Data.KotsChannels { -// channel := types.Channel{ -// ID: kotsChannel.ID, -// Name: kotsChannel.Name, -// ReleaseLabel: kotsChannel.CurrentVersion, -// } - -// channels = append(channels, channel) -// } - -// return channels, nil -// } - -// func (c *GraphQLClient) CreateChannel(appID string, name string, description string) error { -// response := graphql.ResponseErrorOnly{} - -// request := graphql.Request{ -// Query: ` -// mutation createKotsChannel($appId: String!, $channelName: String!, $description: String) { -// createKotsChannel(appId: $appId, channelName: $channelName, description: $description) { -// id -// name -// description -// currentVersion -// currentReleaseDate -// numReleases -// created -// updated -// isDefault -// isArchived -// } -// } -// `, -// Variables: map[string]interface{}{ -// "appId": appID, -// "channelName": name, -// "description": description, -// }, -// } - -// if err := c.ExecuteRequest(request, &response); err != nil { -// return err -// } - -// if len(response.Errors) != 0 { -// return errors.New(response.Errors[0].Message) -// } - -// return nil - -// } - -// func ArchiveChannel(appID string, channelID string) error { -// return nil -// } - -// func GetChannel(appID string, channelID string) (interface{}, []interface{}, error) { -// return nil, nil, nil -// } diff --git a/pkg/kotsclient/client.go b/pkg/kotsclient/client.go index 0df28c4e2..af3879283 100644 --- a/pkg/kotsclient/client.go +++ b/pkg/kotsclient/client.go @@ -13,9 +13,6 @@ type Client interface { ListReleases(appID string) ([]types.ReleaseInfo, error) UpdateRelease(appID string, sequence int64, yaml string) error PromoteRelease(appID string, sequence int64, label string, notes string, channelIDs ...string) error - - // ListChannels(string) ([]types.Channel, error) - // CreateChannel(string, string, string) error } type AppOptions struct { From aa1a78427bc8cd0eee0c6d9d1637986430a69163 Mon Sep 17 00:00:00 2001 From: smithers1221 Date: Mon, 16 Sep 2019 11:41:08 -0700 Subject: [PATCH 13/16] removing items added to collectorfunction --- client/collector.go | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/client/collector.go b/client/collector.go index cf3da0d5b..d6895aee6 100644 --- a/client/collector.go +++ b/client/collector.go @@ -9,16 +9,6 @@ import ( func (c *Client) ListCollectors(appID string) ([]types.CollectorInfo, error) { - appType, err := c.GetAppType(appID) - if err != nil { - return nil, err - } - - if appType == "kots" { - errors.New("On a kots application, users must modify the support-bundle.yaml file in the release") - return nil, err - } - shipappCollectors, err := c.ShipClient.ListCollectors(appID, appType) if err != nil { return nil, err @@ -50,29 +40,11 @@ func (c *Client) ListCollectors(appID string) ([]types.CollectorInfo, error) { } func (c *Client) UpdateCollector(appID string, specID string, yaml string) (interface{}, error) { - appType, err := c.GetAppType(appID) - if err != nil { - return nil, err - } - - if appType == "kots" { - errors.New("On a kots application, users must modify the support-bundle.yaml file in the release") - return nil, err - } return c.ShipClient.UpdateCollector(appID, specID, yaml) } func (c *Client) UpdateCollectorName(appID string, specID string, name string) (interface{}, error) { - appType, err := c.GetAppType(appID) - if err != nil { - return nil, err - } - - if appType == "kots" { - errors.New("On a kots application, users must modify the support-bundle.yaml file in the release") - return nil, err - } return c.ShipClient.UpdateCollectorName(appID, specID, name) From 7499e8d786fd0c7a420422bafd19d88a80c801c7 Mon Sep 17 00:00:00 2001 From: smithers1221 Date: Mon, 16 Sep 2019 11:49:49 -0700 Subject: [PATCH 14/16] overzealous deleting --- client/collector.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/client/collector.go b/client/collector.go index d6895aee6..96abc673b 100644 --- a/client/collector.go +++ b/client/collector.go @@ -9,6 +9,11 @@ import ( func (c *Client) ListCollectors(appID string) ([]types.CollectorInfo, error) { + appType, err := c.GetAppType(appID) + if err != nil { + return nil, err + } + shipappCollectors, err := c.ShipClient.ListCollectors(appID, appType) if err != nil { return nil, err From a13285710958c1e92bae0c5cf2b61f49e9c57225 Mon Sep 17 00:00:00 2001 From: smithers1221 Date: Mon, 16 Sep 2019 12:21:20 -0700 Subject: [PATCH 15/16] always leaving extra lines behind --- cli/cmd/release_update.go | 1 - cli/cmd/root.go | 2 +- pkg/kotsclient/release.go | 8 +------- pkg/shipclient/release.go | 1 - 4 files changed, 2 insertions(+), 10 deletions(-) diff --git a/cli/cmd/release_update.go b/cli/cmd/release_update.go index 33cc8ae5e..46fac2835 100644 --- a/cli/cmd/release_update.go +++ b/cli/cmd/release_update.go @@ -2,7 +2,6 @@ package cmd import ( "encoding/json" - // "errors" "fmt" "io/ioutil" "os" diff --git a/cli/cmd/root.go b/cli/cmd/root.go index 1e82fb3ba..be11df2f2 100644 --- a/cli/cmd/root.go +++ b/cli/cmd/root.go @@ -180,7 +180,7 @@ func Execute(rootCmd *cobra.Command, stdin io.Reader, stdout io.Writer, stderr i return err } runCmds.appID = app.ID - } else { + } else if appType == "kots" { app, err := kotsAPI.GetApp(appSlugOrID) if err != nil { return err diff --git a/pkg/kotsclient/release.go b/pkg/kotsclient/release.go index 0ab59ff71..33d7b19e3 100644 --- a/pkg/kotsclient/release.go +++ b/pkg/kotsclient/release.go @@ -101,13 +101,7 @@ func (c *GraphQLClient) UpdateRelease(appID string, sequence int64, multiyaml st response := GraphQLResponseUpdateKotsRelease{} request := graphql.Request{ - Query: ` - mutation updateKotsRelease($appId: ID!, $spec: String!, $sequence: Int) { - updateKotsRelease(appId: $appId, spec: $spec, sequence: $sequence) { - sequence - } - } - `, + Query: updateKotsRelease, Variables: map[string]interface{}{ "appId": appID, diff --git a/pkg/shipclient/release.go b/pkg/shipclient/release.go index 733760fe6..2d576e992 100644 --- a/pkg/shipclient/release.go +++ b/pkg/shipclient/release.go @@ -130,7 +130,6 @@ func (c *GraphQLClient) ListReleases(appID string) ([]types.ReleaseInfo, error) Name: shipReleaseChannel.Name, } activeChannels = append(activeChannels, activeChannel) - } releaseInfo := types.ReleaseInfo{ From 33c6fe25bbb668c6ff32fec5134b9772acc9cdba Mon Sep 17 00:00:00 2001 From: smithers1221 Date: Mon, 16 Sep 2019 15:13:12 -0700 Subject: [PATCH 16/16] todo: remove all completed todos --- client/release.go | 1 - 1 file changed, 1 deletion(-) diff --git a/client/release.go b/client/release.go index 7ebaa6c33..49d111f32 100644 --- a/client/release.go +++ b/client/release.go @@ -45,7 +45,6 @@ func (c *Client) ListReleases(appID string) ([]types.ReleaseInfo, error) { return releaseInfos, nil - // TODO: need to fix active channels output for ship and kots apps } else if appType == "ship" { shipReleases, err := c.ShipClient.ListReleases(appID) if err != nil {