1
0
mirror of https://github.com/rancher/cli.git synced 2026-02-05 09:48:36 +01:00

Remove app, catalog, multiclusterapp commands (#405)

Ref: https://github.com/rancher/rancher/issues/48252
This commit is contained in:
Sakala Venkata Krishna Rohit
2024-12-03 11:59:06 -08:00
committed by GitHub
parent 2cf4939754
commit 0b6ae1f01b
10 changed files with 2 additions and 3336 deletions

1463
cmd/app.go

File diff suppressed because it is too large Load Diff

View File

@@ -1,23 +0,0 @@
package cmd
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestGetExternalIDInVersion(t *testing.T) {
assert := assert.New(t)
got, err := updateExternalIDVersion("catalog://?catalog=library&template=cert-manager&version=v0.5.2", "v1.2.3")
assert.Nil(err)
assert.Equal("catalog://?catalog=library&template=cert-manager&version=v1.2.3", got)
got, err = updateExternalIDVersion("catalog://?catalog=c-29wkq/clusterscope&type=clusterCatalog&template=mysql&version=0.3.8", "0.3.9")
assert.Nil(err)
assert.Equal("catalog://?catalog=c-29wkq/clusterscope&type=clusterCatalog&template=mysql&version=0.3.9", got)
got, err = updateExternalIDVersion("catalog://?catalog=p-j9gfw/projectscope&type=projectCatalog&template=grafana&version=0.0.31", "0.0.30")
assert.Nil(err)
assert.Equal("catalog://?catalog=p-j9gfw/projectscope&type=projectCatalog&template=grafana&version=0.0.30", got)
}

View File

@@ -1,311 +0,0 @@
package cmd
import (
"strings"
"time"
"github.com/pkg/errors"
managementClient "github.com/rancher/rancher/pkg/client/generated/management/v3"
"github.com/sirupsen/logrus"
"github.com/urfave/cli"
)
const (
addCatalogDescription = `
Add a new catalog to the Rancher server
Example:
# Add a catalog
$ rancher catalog add foo https://my.catalog
# Add a catalog and specify the branch to use
$ rancher catalog add --branch awesomebranch foo https://my.catalog
# Add a catalog and specify the helm version to use. Specify 'v2' for helm 2 and 'v3' for helm 3
$ rancher catalog add --helm-version v3 foo https://my.catalog
`
refreshCatalogDescription = `
Refresh a catalog on the Rancher server
Example:
# Refresh a catalog
$ rancher catalog refresh foo
# Refresh multiple catalogs
$ rancher catalog refresh foo bar baz
# Refresh all catalogs
$ rancher catalog refresh --all
# Refresh is asynchronous unless you specify '--wait'
$ rancher catalog refresh --all --wait --wait-timeout=60
# Default wait timeout is 60 seconds, set to 0 to remove the timeout
$ rancher catalog refresh --all --wait --wait-timeout=0
`
)
type CatalogData struct {
ID string
Catalog managementClient.Catalog
}
func CatalogCommand() cli.Command {
catalogLsFlags := []cli.Flag{
formatFlag,
quietFlag,
cli.BoolFlag{
Name: "verbose,v",
Usage: "Include the catalog's state",
},
}
return cli.Command{
Name: "catalog",
Usage: "Operations with catalogs",
Action: defaultAction(catalogLs),
Flags: catalogLsFlags,
Subcommands: []cli.Command{
{
Name: "ls",
Usage: "List catalogs",
Description: "\nList all catalogs in the current Rancher server",
ArgsUsage: "None",
Action: catalogLs,
Flags: catalogLsFlags,
},
{
Name: "add",
Usage: "Add a catalog",
Description: addCatalogDescription,
ArgsUsage: "[NAME, URL]",
Action: catalogAdd,
Flags: []cli.Flag{
cli.StringFlag{
Name: "branch",
Usage: "Branch from the url to use",
Value: "master",
},
cli.StringFlag{
Name: "helm-version",
Usage: "Version of helm the app(s) in your catalog will use for deployment. Use 'v2' for helm 2 or 'v3' for helm 3",
Value: "v2",
},
},
},
{
Name: "delete",
Usage: "Delete a catalog",
Description: "\nDelete a catalog from the Rancher server",
ArgsUsage: "[CATALOG_NAME/CATALOG_ID]",
Action: catalogDelete,
},
{
Name: "refresh",
Usage: "Refresh catalog templates",
Description: refreshCatalogDescription,
ArgsUsage: "[CATALOG_NAME/CATALOG_ID]...",
Action: catalogRefresh,
Flags: []cli.Flag{
cli.BoolFlag{
Name: "all",
Usage: "Refresh all catalogs",
},
cli.BoolFlag{
Name: "wait,w",
Usage: "Wait for catalog(s) to become active",
},
cli.IntFlag{
Name: "wait-timeout",
Usage: "Wait timeout duration in seconds",
Value: 60,
},
},
},
},
}
}
func catalogLs(ctx *cli.Context) error {
c, err := GetClient(ctx)
if err != nil {
return err
}
collection, err := c.ManagementClient.Catalog.List(defaultListOpts(ctx))
if err != nil {
return err
}
fields := [][]string{
{"ID", "ID"},
{"NAME", "Catalog.Name"},
{"URL", "Catalog.URL"},
{"BRANCH", "Catalog.Branch"},
{"KIND", "Catalog.Kind"},
{"HELMVERSION", "Catalog.HelmVersion"},
}
if ctx.Bool("verbose") {
fields = append(fields, []string{"STATE", "Catalog.State"})
}
writer := NewTableWriter(fields, ctx)
defer writer.Close()
for _, item := range collection.Data {
writer.Write(&CatalogData{
ID: item.ID,
Catalog: item,
})
}
return writer.Err()
}
func catalogAdd(ctx *cli.Context) error {
if len(ctx.Args()) < 2 {
return cli.ShowSubcommandHelp(ctx)
}
c, err := GetClient(ctx)
if err != nil {
return err
}
catalog := &managementClient.Catalog{
Branch: ctx.String("branch"),
Name: ctx.Args().First(),
Kind: "helm",
URL: ctx.Args().Get(1),
HelmVersion: strings.ToLower(ctx.String("helm-version")),
}
_, err = c.ManagementClient.Catalog.Create(catalog)
if err != nil {
return err
}
return nil
}
func catalogDelete(ctx *cli.Context) error {
if len(ctx.Args()) < 1 {
return cli.ShowSubcommandHelp(ctx)
}
c, err := GetClient(ctx)
if err != nil {
return err
}
for _, arg := range ctx.Args() {
resource, err := Lookup(c, arg, "catalog")
if err != nil {
return err
}
catalog, err := c.ManagementClient.Catalog.ByID(resource.ID)
if err != nil {
return err
}
err = c.ManagementClient.Catalog.Delete(catalog)
if err != nil {
return err
}
}
return nil
}
func catalogRefresh(ctx *cli.Context) error {
if len(ctx.Args()) < 1 && !ctx.Bool("all") {
return cli.ShowSubcommandHelp(ctx)
}
c, err := GetClient(ctx)
if err != nil {
return err
}
var catalogs []managementClient.Catalog
if ctx.Bool("all") {
opts := baseListOpts()
collection, err := c.ManagementClient.Catalog.List(opts)
if err != nil {
return err
}
// save the catalogs in case we need to wait for them to become active
catalogs = collection.Data
_, err = c.ManagementClient.Catalog.CollectionActionRefresh(collection)
if err != nil {
return err
}
} else {
for _, arg := range ctx.Args() {
resource, err := Lookup(c, arg, "catalog")
if err != nil {
return err
}
catalog, err := c.ManagementClient.Catalog.ByID(resource.ID)
if err != nil {
return err
}
// collect the refreshing catalogs in case we need to wait for them later
catalogs = append(catalogs, *catalog)
_, err = c.ManagementClient.Catalog.ActionRefresh(catalog)
if err != nil {
return err
}
}
}
if ctx.Bool("wait") {
timeout := time.Duration(ctx.Int("wait-timeout")) * time.Second
start := time.Now()
logrus.Debugf("catalog: waiting for catalogs to become active (timeout=%v)", timeout)
for _, catalog := range catalogs {
logrus.Debugf("catalog: waiting for %s to become active", catalog.Name)
resource, err := Lookup(c, catalog.Name, "catalog")
if err != nil {
return err
}
catalog, err := c.ManagementClient.Catalog.ByID(resource.ID)
if err != nil {
return err
}
for catalog.State != "active" {
time.Sleep(time.Second)
catalog, err = c.ManagementClient.Catalog.ByID(resource.ID)
if err != nil {
return err
}
if timeout > 0 && time.Since(start) > timeout {
return errors.New("catalog: timed out waiting for refresh")
}
}
}
logrus.Debugf("catalog: waited for %v", time.Since(start))
}
return nil
}

View File

@@ -248,14 +248,6 @@ func searchForMember(ctx *cli.Context, c *cliclient.MasterClient, name string) (
return &results.Data[selection], nil
}
func getRancherServerVersion(c *cliclient.MasterClient) (string, error) {
setting, err := c.ManagementClient.Setting.ByID("server-version")
if err != nil {
return "", err
}
return setting.Value, err
}
func loadAndVerifyCert(path string) (string, error) {
caCert, err := os.ReadFile(path)
if err != nil {
@@ -625,73 +617,6 @@ func createdTimetoHuman(t string) (string, error) {
return parsedTime.Format(humanTimeFormat), nil
}
func outputMembers(ctx *cli.Context, c *cliclient.MasterClient, members []managementClient.Member) error {
writer := NewTableWriter([][]string{
{"NAME", "Name"},
{"MEMBER_TYPE", "MemberType"},
{"ACCESS_TYPE", "AccessType"},
}, ctx)
defer writer.Close()
for _, m := range members {
principalID := m.UserPrincipalID
if m.UserPrincipalID == "" {
principalID = m.GroupPrincipalID
}
principal, err := c.ManagementClient.Principal.ByID(url.PathEscape(principalID))
if err != nil {
return err
}
memberType := fmt.Sprintf("%s %s", principal.Provider, principal.PrincipalType)
writer.Write(&MemberData{
Name: principal.Name,
MemberType: cases.Title(language.Und).String(memberType),
AccessType: m.AccessType,
})
}
return writer.Err()
}
func addMembersByNames(ctx *cli.Context, c *cliclient.MasterClient, members []managementClient.Member, toAddMembers []string, accessType string) ([]managementClient.Member, error) {
for _, name := range toAddMembers {
member, err := searchForMember(ctx, c, name)
if err != nil {
return nil, err
}
toAddMember := managementClient.Member{
AccessType: accessType,
}
if member.PrincipalType == "user" {
toAddMember.UserPrincipalID = member.ID
} else {
toAddMember.GroupPrincipalID = member.ID
}
members = append(members, toAddMember)
}
return members, nil
}
func deleteMembersByNames(ctx *cli.Context, c *cliclient.MasterClient, members []managementClient.Member, todeleteMembers []string) ([]managementClient.Member, error) {
for _, name := range todeleteMembers {
member, err := searchForMember(ctx, c, name)
if err != nil {
return nil, err
}
var toKeepMembers []managementClient.Member
for _, m := range members {
if m.GroupPrincipalID != member.ID && m.UserPrincipalID != member.ID {
toKeepMembers = append(toKeepMembers, m)
}
}
members = toKeepMembers
}
return members, nil
}
func ConfigDir() (string, error) {
homeDir, err := os.UserHomeDir()
if err != nil {

File diff suppressed because it is too large Load Diff

View File

@@ -1,122 +0,0 @@
package cmd
import (
"testing"
client "github.com/rancher/rancher/pkg/client/generated/management/v3"
"github.com/stretchr/testify/assert"
)
func TestFromMultiClusterAppAnswers(t *testing.T) {
assert := assert.New(t)
answerSlice := []client.Answer{
{
ProjectID: "c-1:p-1",
Values: map[string]string{
"var-1": "val1",
"var-2": "val2",
},
ValuesSetString: map[string]string{
"str-var-1": "str-val1",
"str-var-2": "str-val2",
},
}, {
ProjectID: "c-1:p-2",
Values: map[string]string{
"var-3": "val3",
},
ValuesSetString: map[string]string{
"str-var-3": "str-val3",
},
}, {
ClusterID: "c-1",
Values: map[string]string{
"var-4": "val4",
},
ValuesSetString: map[string]string{
"str-var-4": "str-val4",
},
}, {
ClusterID: "c-2",
Values: map[string]string{
"var-5": "val5",
},
ValuesSetString: map[string]string{
"str-var-5": "str-val5",
},
}, {
Values: map[string]string{
"var-6": "val6",
},
ValuesSetString: map[string]string{
"str-var-6": "str-val6",
},
},
}
answers, answersSetString := fromMultiClusterAppAnswers(answerSlice)
assert.Equal(len(answers), 6)
assert.Equal(answers["c-1:p-1:var-1"], "val1")
assert.Equal(answers["c-1:p-1:var-2"], "val2")
assert.Equal(answers["c-1:p-2:var-3"], "val3")
assert.Equal(answers["c-1:var-4"], "val4")
assert.Equal(answers["c-2:var-5"], "val5")
assert.Equal(answers["var-6"], "val6")
assert.Equal(len(answersSetString), 6)
assert.Equal(answersSetString["c-1:p-1:str-var-1"], "str-val1")
assert.Equal(answersSetString["c-1:p-1:str-var-2"], "str-val2")
assert.Equal(answersSetString["c-1:p-2:str-var-3"], "str-val3")
assert.Equal(answersSetString["c-1:str-var-4"], "str-val4")
assert.Equal(answersSetString["c-2:str-var-5"], "str-val5")
assert.Equal(answersSetString["str-var-6"], "str-val6")
}
func TestGetReadableTargetNames(t *testing.T) {
assert := assert.New(t)
clusters := map[string]client.Cluster{
"c-1": {
Name: "cn-1",
},
"c-2": {
Name: "cn-2",
},
}
projects := map[string]client.Project{
"c-1:p-1": {
Name: "pn-1",
},
"c-1:p-2": {
Name: "pn-2",
},
"c-2:p-3": {
Name: "pn-3",
},
"c-2:p-4": {
Name: "pn-4",
},
}
targets := []client.Target{
{
ProjectID: "c-1:p-1",
},
{
ProjectID: "c-1:p-2",
},
{
ProjectID: "c-2:p-3",
},
}
result := getReadableTargetNames(clusters, projects, targets)
assert.Contains(result, "cn-1:pn-1")
assert.Contains(result, "cn-1:pn-2")
assert.Contains(result, "cn-2:pn-3")
targets = []client.Target{
{
ProjectID: "c-0:p-0",
},
}
result = getReadableTargetNames(clusters, projects, targets)
assert.Contains(result, "c-0:p-0")
}

View File

@@ -11,7 +11,7 @@ import (
)
var (
waitTypes = []string{"cluster", "app", "project", "multiClusterApp"}
waitTypes = []string{"cluster", "project"}
)
func WaitCommand() cli.Command {

3
go.mod
View File

@@ -9,7 +9,6 @@ replace k8s.io/client-go => k8s.io/client-go v0.31.1
require (
github.com/ghodss/yaml v1.0.0
github.com/grantae/certinfo v0.0.0-20170412194111-59d56a35515b
github.com/hashicorp/go-version v1.2.1
github.com/pkg/errors v0.9.1
github.com/rancher/norman v0.0.0-20241001183610-78a520c160ab
github.com/rancher/rancher/pkg/apis v0.0.0-20241119163817-d801b4924311
@@ -23,7 +22,6 @@ require (
golang.org/x/sync v0.8.0
golang.org/x/term v0.25.0
golang.org/x/text v0.19.0
gopkg.in/yaml.v2 v2.4.0
k8s.io/client-go v12.0.0+incompatible
)
@@ -75,6 +73,7 @@ require (
golang.org/x/time v0.7.0 // indirect
google.golang.org/protobuf v1.35.1 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/api v0.31.1 // indirect
k8s.io/apimachinery v0.31.1 // indirect

2
go.sum
View File

@@ -51,8 +51,6 @@ github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aN
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grantae/certinfo v0.0.0-20170412194111-59d56a35515b h1:NGgE5ELokSf2tZ/bydyDUKrvd/jP8lrAoPNeBuMOTOk=
github.com/grantae/certinfo v0.0.0-20170412194111-59d56a35515b/go.mod h1:zT/uzhdQGTqlwTq7Lpbj3JoJQWfPfIJ1tE0OidAmih8=
github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI=
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=

View File

@@ -105,15 +105,12 @@ func mainErr() error {
},
}
app.Commands = []cli.Command{
cmd.AppCommand(),
cmd.CatalogCommand(),
cmd.ClusterCommand(),
cmd.ContextCommand(),
cmd.InspectCommand(),
cmd.KubectlCommand(),
cmd.LoginCommand(),
cmd.MachineCommand(),
cmd.MultiClusterAppCommand(),
cmd.NamespaceCommand(),
cmd.NodeCommand(),
cmd.ProjectCommand(),