diff --git a/cli/cmd/channel_inspect.go b/cli/cmd/channel_inspect.go index 178cf5bfe..caf4df676 100644 --- a/cli/cmd/channel_inspect.go +++ b/cli/cmd/channel_inspect.go @@ -25,7 +25,7 @@ func (r *runners) channelInspect(cmd *cobra.Command, args []string) error { } chanID := args[0] - appChan, _, err := r.platformAPI.GetChannel(r.appID, chanID) + appChan, _, err := r.api.GetChannel(r.appID, chanID) if err != nil { return err } diff --git a/cli/cmd/channel_rm.go b/cli/cmd/channel_rm.go index 50316a743..433479164 100644 --- a/cli/cmd/channel_rm.go +++ b/cli/cmd/channel_rm.go @@ -24,7 +24,7 @@ func (r *runners) channelRemove(cmd *cobra.Command, args []string) error { } chanID := args[0] - if err := r.platformAPI.ArchiveChannel(r.appID, chanID); err != nil { + if err := r.api.ArchiveChannel(r.appID, chanID); err != nil { return err } diff --git a/cli/print/channel_attributes.go b/cli/print/channel_attributes.go index 60ee4e330..dd37fc8c2 100644 --- a/cli/print/channel_attributes.go +++ b/cli/print/channel_attributes.go @@ -10,7 +10,7 @@ import ( var channelAttrsTmplSrc = `ID: {{ .Id }} NAME: {{ .Name }} DESCRIPTION: {{ .Description }} -RELEASE: {{ .ReleaseSequence }} +RELEASE: {{ if ge .ReleaseSequence 1 }}{{ .ReleaseSequence }}{{else}} {{end}} VERSION: {{ .ReleaseLabel }} ` diff --git a/client/channel.go b/client/channel.go index cc9778558..d440756f3 100644 --- a/client/channel.go +++ b/client/channel.go @@ -3,6 +3,7 @@ package client import ( "errors" + channels "github.com/replicatedhq/replicated/gen/go/v1" "github.com/replicatedhq/replicated/pkg/types" ) @@ -41,12 +42,38 @@ func (c *Client) ListChannels(appID string) ([]types.Channel, error) { return nil, errors.New("unknown app type") } -func (c *Client) GetChannel(appID string, channelID string) (interface{}, interface{}, error) { - return nil, nil, nil +func (c *Client) GetChannel(appID string, channelID string) (*channels.AppChannel, []channels.ChannelRelease, error) { + appType, err := c.GetAppType(appID) + if err != nil { + return nil, nil, err + } + + if appType == "platform" { + return c.PlatformClient.GetChannel(appID, channelID) + } else if appType == "ship" { + return c.ShipClient.GetChannel(appID, channelID) + } else if appType == "kots" { + return c.KotsClient.GetChannel(appID, channelID) + } + return nil, nil, errors.New("unknown app type") + } func (c *Client) ArchiveChannel(appID string, channelID string) error { - return nil + appType, err := c.GetAppType(appID) + if err != nil { + return err + } + + if appType == "platform" { + return c.PlatformClient.ArchiveChannel(appID, channelID) + } else if appType == "ship" { + return errors.New("This feature is not currently supported for Ship applications.") + } else if appType == "kots" { + return errors.New("This feature is not currently supported for Kots applications.") + } + return errors.New("unknown app type") + } func (c *Client) CreateChannel(appID string, name string, description string) ([]types.Channel, error) { diff --git a/pkg/kotsclient/channel.go b/pkg/kotsclient/channel.go index e28777b21..921b725cc 100644 --- a/pkg/kotsclient/channel.go +++ b/pkg/kotsclient/channel.go @@ -1,6 +1,7 @@ package kotsclient import ( + channels "github.com/replicatedhq/replicated/gen/go/v1" "github.com/replicatedhq/replicated/pkg/graphql" "github.com/replicatedhq/replicated/pkg/types" ) @@ -10,14 +11,23 @@ type GraphQLResponseListChannels struct { Errors []graphql.GQLError `json:"errors,omitempty"` } +type GraphQLResponseGetChannel struct { + Data *KotsGetChannelData `json:"data,omitempty"` + Errors []graphql.GQLError `json:"errors,omitempty"` +} +type KotsGetChannelData struct { + KotsChannel *KotsChannel `json:"getKotsChannel"` +} type KotsChannelData struct { KotsChannels []*KotsChannel `json:"getKotsAppChannels"` } type KotsChannel struct { - ID string `json:"id"` - Name string `json:"name"` - CurrentVersion string `json:"currentVersion"` + 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) { @@ -130,6 +140,80 @@ func ArchiveChannel(appID string, channelID string) error { return nil } -func GetChannel(appID string, channelID string) (interface{}, []interface{}, error) { - return nil, nil, nil +var getKotsChannel = ` +query getKotsChannel($channelId: ID!) { + getKotsChannel(channelId: $channelId) { + id + appId + name + description + channelIcon + currentVersion + currentReleaseDate + installInstructions + numReleases + adoptionRate { + releaseSequence + semver + count + percent + totalOnChannel + } + customers { + id + name + avatar + actions { + shipApplyDocker + } + installationId + shipInstallStatus { + status + updatedAt + } + } + githubRef { + owner + repoFullName + branch + path + } + extraLintRules + created + updated + isDefault + isArchived + releases { + semver + releaseNotes + created + updated + sequence + airgapBuildStatus + } + } +} +` + +func (c *GraphQLClient) GetChannel(appID string, channelID string) (*channels.AppChannel, []channels.ChannelRelease, error) { + response := GraphQLResponseGetChannel{} + + request := graphql.Request{ + Query: getKotsChannel, + Variables: map[string]interface{}{ + "appID": appID, + "channelId": channelID, + }, + } + if err := c.ExecuteRequest(request, &response); err != nil { + return nil, nil, err + } + + channelDetail := channels.AppChannel{ + Id: response.Data.KotsChannel.ID, + Name: response.Data.KotsChannel.Name, + Description: response.Data.KotsChannel.Description, + ReleaseLabel: response.Data.KotsChannel.CurrentVersion, + } + return &channelDetail, nil, nil } diff --git a/pkg/kotsclient/client.go b/pkg/kotsclient/client.go index 1036199e2..732f341ef 100644 --- a/pkg/kotsclient/client.go +++ b/pkg/kotsclient/client.go @@ -1,6 +1,7 @@ package kotsclient import ( + channels "github.com/replicatedhq/replicated/gen/go/v1" "github.com/replicatedhq/replicated/pkg/graphql" "github.com/replicatedhq/replicated/pkg/types" ) @@ -16,6 +17,7 @@ type Client interface { ListChannels(string) ([]types.Channel, error) CreateChannel(string, string, string) error + GetChannel(appID, channelID string) (*channels.AppChannel, []channels.ChannelRelease, error) } type AppOptions struct { diff --git a/pkg/shipclient/channel.go b/pkg/shipclient/channel.go index eda610f0b..c7effed4c 100644 --- a/pkg/shipclient/channel.go +++ b/pkg/shipclient/channel.go @@ -1,6 +1,7 @@ package shipclient import ( + channels "github.com/replicatedhq/replicated/gen/go/v1" "github.com/replicatedhq/replicated/pkg/graphql" "github.com/replicatedhq/replicated/pkg/types" ) @@ -10,6 +11,15 @@ type GraphQLResponseListChannels struct { Errors []graphql.GQLError `json:"errors,omitempty"` } +type GraphQLResponseGetChannel struct { + Data *ShipGetChannelData `json:"data,omitempty"` + Errors []graphql.GQLError `json:"errors,omitempty"` +} + +type ShipGetChannelData struct { + ShipChannel *ShipChannel `json:"getChannel"` +} + type ShipChannelData struct { ShipChannels []*ShipChannel `json:"getAppChannels"` } @@ -121,6 +131,82 @@ func ArchiveChannel(appID string, channelID string) error { return nil } -func GetChannel(appID string, channelID string) (interface{}, []interface{}, error) { - return nil, nil, nil +var getShipChannel = ` + query getChannel($channelId: ID!) { + getChannel(channelId: $channelId) { + id + appId + name + description + channelIcon + currentVersion + currentReleaseDate + installInstructions + currentSpec + numReleases + adoptionRate { + releaseId + semver + count + percent + totalOnChannel + } + customers { + id + name + avatar + actions { + shipApplyDocker + } + installationId + shipInstallStatus { + status + updatedAt + } + } + githubRef { + owner + repoFullName + branch + path + } + extraLintRules + created + updated + isDefault + isArchived + releases { + id + semver + spec + releaseNotes + created + updated + sequence + } + } + } +` + +func (c *GraphQLClient) GetChannel(appID string, channelID string) (*channels.AppChannel, []channels.ChannelRelease, error) { + response := GraphQLResponseGetChannel{} + + request := graphql.Request{ + Query: getShipChannel, + Variables: map[string]interface{}{ + "appID": appID, + "channelId": channelID, + }, + } + if err := c.ExecuteRequest(request, &response); err != nil { + return nil, nil, err + } + + channelDetail := channels.AppChannel{ + Id: response.Data.ShipChannel.ID, + Name: response.Data.ShipChannel.Name, + Description: response.Data.ShipChannel.Description, + ReleaseLabel: response.Data.ShipChannel.CurrentVersion, + } + return &channelDetail, nil, nil } diff --git a/pkg/shipclient/client.go b/pkg/shipclient/client.go index 2f53b6ec0..fca8a5404 100644 --- a/pkg/shipclient/client.go +++ b/pkg/shipclient/client.go @@ -1,6 +1,7 @@ package shipclient import ( + channels "github.com/replicatedhq/replicated/gen/go/v1" v1 "github.com/replicatedhq/replicated/gen/go/v1" "github.com/replicatedhq/replicated/pkg/graphql" "github.com/replicatedhq/replicated/pkg/types" @@ -12,6 +13,7 @@ type Client interface { ListChannels(string) ([]types.Channel, error) CreateChannel(string, string, string) error + GetChannel(appID, channelID string) (*channels.AppChannel, []channels.ChannelRelease, error) ListReleases(appID string) ([]types.ReleaseInfo, error) CreateRelease(appID string, yaml string) (*types.ReleaseInfo, error) diff --git a/pkg/shipclient/release.go b/pkg/shipclient/release.go index 2d576e992..35f595bdb 100644 --- a/pkg/shipclient/release.go +++ b/pkg/shipclient/release.go @@ -237,8 +237,31 @@ func (c *GraphQLClient) CreateRelease(appID string, yaml string) (*types.Release return &releaseInfo, nil } +var updateShipRelease = ` +mutation updateRelease($appId: ID!, $spec: String!, $sequence: Int) { + updateRelease(appId: $appId, spec: $spec, sequence: $sequence) { + id + } + }` + func (c *GraphQLClient) UpdateRelease(appID string, sequence int64, yaml string) error { + response := graphql.ResponseErrorOnly{} + + request := graphql.Request{ + Query: updateShipRelease, + Variables: map[string]interface{}{ + "appId": appID, + "sequence": sequence, + "spec": yaml, + }, + } + + if err := c.ExecuteRequest(request, &response); err != nil { + return err + } + return nil + } var promoteShipReleaseQuery = `