github.com/oam-dev/kubevela@v1.9.11/references/cli/addon-registry.go (about)

     1  /*
     2  Copyright 2021 The KubeVela Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package cli
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"net/url"
    23  
    24  	"github.com/gosuri/uitable"
    25  	"github.com/pkg/errors"
    26  	"github.com/spf13/cobra"
    27  
    28  	pkgaddon "github.com/oam-dev/kubevela/pkg/addon"
    29  	"github.com/oam-dev/kubevela/pkg/utils/common"
    30  	cmdutil "github.com/oam-dev/kubevela/pkg/utils/util"
    31  )
    32  
    33  const (
    34  	addonRegistryType = "type"
    35  	addonEndpoint     = "endpoint"
    36  	addonOssBucket    = "bucket"
    37  	addonPath         = "path"
    38  	addonGitToken     = "gitToken"
    39  	addonOssType      = "OSS"
    40  	addonGitType      = "git"
    41  	addonGiteeType    = "gitee"
    42  	addonGitlabType   = "gitlab"
    43  	addonHelmType     = "helm"
    44  	addonUsername     = "username"
    45  	addonPassword     = "password"
    46  	// only gitlab registry need set this flag
    47  	addonRepoName            = "gitlabRepoName"
    48  	addonHelmInsecureSkipTLS = "insecureSkipTLS"
    49  )
    50  
    51  // NewAddonRegistryCommand return an addon registry command
    52  func NewAddonRegistryCommand(c common.Args, ioStreams cmdutil.IOStreams) *cobra.Command {
    53  	cmd := &cobra.Command{
    54  		Use:   "registry",
    55  		Short: "Manage addon registry.",
    56  		Long:  "Manage addon registry.",
    57  	}
    58  	cmd.AddCommand(
    59  		NewAddAddonRegistryCommand(c, ioStreams),
    60  		NewListAddonRegistryCommand(c, ioStreams),
    61  		NewUpdateAddonRegistryCommand(c, ioStreams),
    62  		NewDeleteAddonRegistryCommand(c, ioStreams),
    63  		NewGetAddonRegistryCommand(c, ioStreams),
    64  	)
    65  	return cmd
    66  }
    67  
    68  // NewAddAddonRegistryCommand return an addon registry create command
    69  func NewAddAddonRegistryCommand(c common.Args, _ cmdutil.IOStreams) *cobra.Command {
    70  	cmd := &cobra.Command{
    71  		Use:   "add",
    72  		Short: "Add an addon registry.",
    73  		Long:  "Add an addon registry.",
    74  		Example: `add a helm repo registry: vela addon registry add --type=helm my-repo --endpoint=<URL>
    75  add a github registry: vela addon registry add my-repo --type git --endpoint=<URL> --path=<path> --gitToken=<git token>
    76  add a specified github registry: vela addon registry add my-repo --type git --endpoint=https://github.com/kubevela/catalog --path=addons --gitToken=<git token>
    77  add a gitlab registry: vela addon registry add my-repo --type gitlab --endpoint=<URL> --gitlabRepoName=<repoName> --path=<path> --gitToken=<git token>
    78  add a specified gitlab registry: vela addon registry add my-repo --type gitlab --endpoint=http://gitlab.xxx.com/xxx/catalog --path=addons --gitlabRepoName=catalog --gitToken=<git token>`,
    79  		RunE: func(cmd *cobra.Command, args []string) error {
    80  			registry, err := getRegistryFromArgs(cmd, args)
    81  			if err != nil {
    82  				return err
    83  			}
    84  			if registry.Helm != nil {
    85  				versionedRegistry := pkgaddon.BuildVersionedRegistry(registry.Name, registry.Helm.URL, &common.HTTPOption{
    86  					Username:        registry.Helm.Username,
    87  					Password:        registry.Helm.Password,
    88  					InsecureSkipTLS: registry.Helm.InsecureSkipTLS,
    89  				})
    90  				_, err = versionedRegistry.ListAddon()
    91  				if err != nil {
    92  					return fmt.Errorf("fail to add registry %s: %w", registry.Name, err)
    93  				}
    94  			}
    95  			if err := addAddonRegistry(context.Background(), c, *registry); err != nil {
    96  				return err
    97  			}
    98  			return nil
    99  		},
   100  	}
   101  	parseArgsFromFlag(cmd)
   102  	return cmd
   103  }
   104  
   105  // NewGetAddonRegistryCommand return an addon registry get command
   106  func NewGetAddonRegistryCommand(c common.Args, _ cmdutil.IOStreams) *cobra.Command {
   107  	return &cobra.Command{
   108  		Use:     "get",
   109  		Short:   "Get an addon registry.",
   110  		Long:    "Get an addon registry.",
   111  		Example: "vela addon registry get <registry name>",
   112  		RunE: func(cmd *cobra.Command, args []string) error {
   113  			if len(args) != 1 {
   114  				return errors.New("must specify the registry name")
   115  			}
   116  			name := args[0]
   117  			err := getAddonRegistry(context.Background(), c, name)
   118  			if err != nil {
   119  				return err
   120  			}
   121  			return nil
   122  		},
   123  	}
   124  }
   125  
   126  // NewListAddonRegistryCommand return an addon registry list command
   127  func NewListAddonRegistryCommand(c common.Args, _ cmdutil.IOStreams) *cobra.Command {
   128  	return &cobra.Command{
   129  		Use:     "list",
   130  		Short:   "List addon registries.",
   131  		Long:    "List addon registries.",
   132  		Example: "vela addon registry list",
   133  		RunE: func(cmd *cobra.Command, args []string) error {
   134  			if err := listAddonRegistry(context.Background(), c); err != nil {
   135  				return err
   136  			}
   137  			return nil
   138  		},
   139  	}
   140  }
   141  
   142  // NewUpdateAddonRegistryCommand return an addon registry update command
   143  func NewUpdateAddonRegistryCommand(c common.Args, _ cmdutil.IOStreams) *cobra.Command {
   144  	cmd := &cobra.Command{
   145  		Use:     "update",
   146  		Short:   "Update an addon registry.",
   147  		Long:    "Update an addon registry.",
   148  		Example: "vela addon registry update <registry-name> --type OSS --endpoint=<URL> --bucket=<bucket name>",
   149  		RunE: func(cmd *cobra.Command, args []string) error {
   150  			registry, err := getRegistryFromArgs(cmd, args)
   151  			if err != nil {
   152  				return err
   153  			}
   154  			if err := updateAddonRegistry(context.Background(), c, *registry); err != nil {
   155  				return err
   156  			}
   157  			return nil
   158  		},
   159  	}
   160  	parseArgsFromFlag(cmd)
   161  	return cmd
   162  }
   163  
   164  // NewDeleteAddonRegistryCommand return an addon registry delete command
   165  func NewDeleteAddonRegistryCommand(c common.Args, _ cmdutil.IOStreams) *cobra.Command {
   166  	return &cobra.Command{
   167  		Use:     "delete",
   168  		Short:   "Delete an addon registry",
   169  		Long:    "Delete an addon registry",
   170  		Example: "vela addon registry delete <registry-name>",
   171  		RunE: func(cmd *cobra.Command, args []string) error {
   172  			if len(args) != 1 {
   173  				return errors.New("must specify the registry name")
   174  			}
   175  			name := args[0]
   176  			err := deleteAddonRegistry(context.Background(), c, name)
   177  			if err != nil {
   178  				return err
   179  			}
   180  			return nil
   181  		},
   182  	}
   183  }
   184  
   185  func listAddonRegistry(ctx context.Context, c common.Args) error {
   186  	client, err := c.GetClient()
   187  	if err != nil {
   188  		return err
   189  	}
   190  	ds := pkgaddon.NewRegistryDataStore(client)
   191  	registries, err := ds.ListRegistries(ctx)
   192  	if err != nil {
   193  		return err
   194  	}
   195  	table := uitable.New()
   196  	table.AddRow("Name", "Type", "URL")
   197  	for _, registry := range registries {
   198  		var repoType, repoURL string
   199  		switch {
   200  		case registry.OSS != nil:
   201  			repoType = "OSS"
   202  			u, err := url.Parse(registry.OSS.Endpoint)
   203  			if err != nil {
   204  				continue
   205  			}
   206  			if registry.OSS.Bucket == "" {
   207  				repoURL = u.String()
   208  			} else {
   209  				if u.Scheme == "" {
   210  					u.Scheme = "https"
   211  				}
   212  				repoURL = fmt.Sprintf("%s://%s.%s", u.Scheme, registry.OSS.Bucket, u.Host)
   213  			}
   214  
   215  		case registry.Git != nil:
   216  			repoType = "git"
   217  			repoURL = fmt.Sprintf("%s/tree/master/%s", registry.Git.URL, registry.Git.Path)
   218  		case registry.Gitee != nil:
   219  			repoType = "gitee"
   220  			repoURL = fmt.Sprintf("%s/tree/master/%s", registry.Gitee.URL, registry.Gitee.Path)
   221  		case registry.Helm != nil:
   222  			repoType = "helm"
   223  			repoURL = registry.Helm.URL
   224  		case registry.Gitlab != nil:
   225  			repoType = "gitlab"
   226  			repoURL = registry.Gitlab.URL
   227  		}
   228  
   229  		table.AddRow(registry.Name, repoType, repoURL)
   230  	}
   231  	fmt.Println(table.String())
   232  	return nil
   233  }
   234  
   235  func getAddonRegistry(ctx context.Context, c common.Args, name string) error {
   236  	client, err := c.GetClient()
   237  	if err != nil {
   238  		return err
   239  	}
   240  	ds := pkgaddon.NewRegistryDataStore(client)
   241  	registry, err := ds.GetRegistry(ctx, name)
   242  	if err != nil {
   243  		return err
   244  	}
   245  	table := uitable.New()
   246  	switch {
   247  	case registry.OSS != nil:
   248  		table.AddRow("NAME", "Type", "ENDPOINT", "BUCKET", "PATH")
   249  		table.AddRow(registry.Name, "OSS", registry.OSS.Endpoint, registry.OSS.Bucket, registry.OSS.Path)
   250  	case registry.Helm != nil:
   251  		table.AddRow("NAME", "Type", "ENDPOINT")
   252  		table.AddRow(registry.Name, "Helm", registry.Helm.URL)
   253  	case registry.Gitee != nil:
   254  		table.AddRow("NAME", "Type", "ENDPOINT", "PATH")
   255  		table.AddRow(registry.Name, "Gitee", registry.Gitee.URL, registry.Gitee.Path)
   256  	case registry.Gitlab != nil:
   257  		table.AddRow("NAME", "Type", "ENDPOINT", "REPOSITORY", "PATH")
   258  		table.AddRow(registry.Name, "Gitlab", registry.Gitlab.URL, registry.Gitlab.Repo, registry.Gitlab.Path)
   259  	case registry.Git != nil:
   260  		table.AddRow("NAME", "Type", "ENDPOINT", "PATH")
   261  		table.AddRow(registry.Name, "Git", registry.Git.URL, registry.Git.Path)
   262  	default:
   263  		table.AddRow("Name")
   264  		table.AddRow(registry.Name)
   265  	}
   266  	fmt.Println(table.String())
   267  	return nil
   268  }
   269  
   270  func deleteAddonRegistry(ctx context.Context, c common.Args, name string) error {
   271  	client, err := c.GetClient()
   272  	if err != nil {
   273  		return err
   274  	}
   275  	ds := pkgaddon.NewRegistryDataStore(client)
   276  	if err := ds.DeleteRegistry(ctx, name); err != nil {
   277  		return err
   278  	}
   279  	fmt.Printf("Successfully delete an addon registry %s \n", name)
   280  	return nil
   281  }
   282  
   283  func addAddonRegistry(ctx context.Context, c common.Args, registry pkgaddon.Registry) error {
   284  	client, err := c.GetClient()
   285  	if err != nil {
   286  		return err
   287  	}
   288  	ds := pkgaddon.NewRegistryDataStore(client)
   289  	if err := ds.AddRegistry(ctx, registry); err != nil {
   290  		return err
   291  	}
   292  	fmt.Printf("Successfully add an addon registry %s \n", registry.Name)
   293  	return nil
   294  }
   295  
   296  func updateAddonRegistry(ctx context.Context, c common.Args, registry pkgaddon.Registry) error {
   297  	client, err := c.GetClient()
   298  	if err != nil {
   299  		return err
   300  	}
   301  	ds := pkgaddon.NewRegistryDataStore(client)
   302  	if err := ds.UpdateRegistry(ctx, registry); err != nil {
   303  		return err
   304  	}
   305  	fmt.Printf("Successfully update an addon registry %s \n", registry.Name)
   306  	return nil
   307  }
   308  
   309  func parseArgsFromFlag(cmd *cobra.Command) {
   310  	cmd.Flags().StringP(addonRegistryType, "", "", "specify the addon registry type")
   311  	cmd.Flags().StringP(addonEndpoint, "", "", "specify the addon registry endpoint")
   312  	cmd.Flags().StringP(addonOssBucket, "", "", "specify the OSS bucket name")
   313  	cmd.Flags().StringP(addonPath, "", "", "specify the addon registry path, must be set when addons are not in root of registry")
   314  	cmd.Flags().StringP(addonGitToken, "", "", "specify the github repo token")
   315  	cmd.Flags().StringP(addonUsername, "", "", "specify the Helm addon registry username")
   316  	cmd.Flags().StringP(addonPassword, "", "", "specify the Helm addon registry password")
   317  	cmd.Flags().StringP(addonRepoName, "", "", "specify the gitlab addon registry repoName, must be set when registry is gitlab")
   318  	cmd.Flags().BoolP(addonHelmInsecureSkipTLS, "", false,
   319  		"specify the Helm addon registry skip tls verify")
   320  }
   321  
   322  func getRegistryFromArgs(cmd *cobra.Command, args []string) (*pkgaddon.Registry, error) {
   323  	r := &pkgaddon.Registry{}
   324  	if len(args) != 1 {
   325  		return nil, errors.New("must specify the registry name")
   326  	}
   327  	r.Name = args[0]
   328  
   329  	registryType, err := cmd.Flags().GetString(addonRegistryType)
   330  	if err != nil {
   331  		return nil, err
   332  	}
   333  
   334  	endpoint, err := cmd.Flags().GetString(addonEndpoint)
   335  	if err != nil {
   336  		return nil, err
   337  	}
   338  	if endpoint == "" {
   339  		return nil, errors.New("addon registry must set --endpoint flag")
   340  	}
   341  
   342  	switch registryType {
   343  	case addonOssType:
   344  		r.OSS = &pkgaddon.OSSAddonSource{}
   345  
   346  		r.OSS.Endpoint = endpoint
   347  		bucket, err := cmd.Flags().GetString(addonOssBucket)
   348  		if err != nil {
   349  			return nil, err
   350  		}
   351  		r.OSS.Bucket = bucket
   352  		path, err := cmd.Flags().GetString(addonPath)
   353  		if err != nil {
   354  			return nil, err
   355  		}
   356  		r.OSS.Path = path
   357  	case addonGitType:
   358  		r.Git = &pkgaddon.GitAddonSource{}
   359  		r.Git.URL = endpoint
   360  		path, err := cmd.Flags().GetString(addonPath)
   361  		if err != nil {
   362  			return nil, err
   363  		}
   364  		r.Git.Path = path
   365  		token, err := cmd.Flags().GetString(addonGitToken)
   366  		if err != nil {
   367  			return nil, err
   368  		}
   369  		r.Git.Token = token
   370  	case addonGiteeType:
   371  		r.Gitee = &pkgaddon.GiteeAddonSource{}
   372  		r.Gitee.URL = endpoint
   373  		path, err := cmd.Flags().GetString(addonPath)
   374  		if err != nil {
   375  			return nil, err
   376  		}
   377  		r.Gitee.Path = path
   378  		token, err := cmd.Flags().GetString(addonGitToken)
   379  		if err != nil {
   380  			return nil, err
   381  		}
   382  		r.Gitee.Token = token
   383  	case addonGitlabType:
   384  		r.Gitlab = &pkgaddon.GitlabAddonSource{}
   385  		r.Gitlab.URL = endpoint
   386  		path, err := cmd.Flags().GetString(addonPath)
   387  		if err != nil {
   388  			return nil, err
   389  		}
   390  		r.Gitlab.Path = path
   391  		token, err := cmd.Flags().GetString(addonGitToken)
   392  		if err != nil {
   393  			return nil, err
   394  		}
   395  		r.Gitlab.Token = token
   396  		gitLabRepoName, err := cmd.Flags().GetString(addonRepoName)
   397  		if err != nil {
   398  			return nil, err
   399  		}
   400  		r.Gitlab.Repo = gitLabRepoName
   401  	case addonHelmType:
   402  		r.Helm = &pkgaddon.HelmSource{}
   403  		r.Helm.URL = endpoint
   404  		r.Helm.Username, err = cmd.Flags().GetString(addonUsername)
   405  		if err != nil {
   406  			return nil, err
   407  		}
   408  		r.Helm.Password, err = cmd.Flags().GetString(addonPassword)
   409  		if err != nil {
   410  			return nil, err
   411  		}
   412  		r.Helm.InsecureSkipTLS, err = cmd.Flags().GetBool(addonHelmInsecureSkipTLS)
   413  		if err != nil {
   414  			return nil, err
   415  		}
   416  
   417  	default:
   418  		return nil, errors.New("not support addon registry type")
   419  	}
   420  	return r, nil
   421  }