github.com/argoproj/argo-cd/v3@v3.2.1/cmd/argocd/commands/admin/repo.go (about) 1 package admin 2 3 import ( 4 stderrors "errors" 5 "os" 6 7 log "github.com/sirupsen/logrus" 8 "github.com/spf13/cobra" 9 corev1 "k8s.io/api/core/v1" 10 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 "k8s.io/client-go/kubernetes/fake" 12 13 cmdutil "github.com/argoproj/argo-cd/v3/cmd/util" 14 "github.com/argoproj/argo-cd/v3/common" 15 "github.com/argoproj/argo-cd/v3/util/cli" 16 "github.com/argoproj/argo-cd/v3/util/db" 17 "github.com/argoproj/argo-cd/v3/util/errors" 18 "github.com/argoproj/argo-cd/v3/util/git" 19 "github.com/argoproj/argo-cd/v3/util/settings" 20 ) 21 22 const ( 23 ArgoCDNamespace = "argocd" 24 repoSecretPrefix = "repo" 25 ) 26 27 func NewRepoCommand() *cobra.Command { 28 command := &cobra.Command{ 29 Use: "repo", 30 Short: "Manage repositories configuration", 31 Run: func(c *cobra.Command, args []string) { 32 c.HelpFunc()(c, args) 33 }, 34 } 35 command.AddCommand(NewGenRepoSpecCommand()) 36 37 return command 38 } 39 40 func NewGenRepoSpecCommand() *cobra.Command { 41 var ( 42 repoOpts cmdutil.RepoOptions 43 outputFormat string 44 ) 45 46 // For better readability and easier formatting 47 repoAddExamples := ` 48 # Add a Git repository via SSH using a private key for authentication, ignoring the server's host key: 49 argocd admin repo generate-spec git@git.example.com:repos/repo --insecure-ignore-host-key --ssh-private-key-path ~/id_rsa 50 51 # Add a Git repository via SSH on a non-default port - need to use ssh:// style URLs here 52 argocd admin repo generate-spec ssh://git@git.example.com:2222/repos/repo --ssh-private-key-path ~/id_rsa 53 54 # Add a private Git repository via HTTPS using username/password and TLS client certificates: 55 argocd admin repo generate-spec https://git.example.com/repos/repo --username git --password secret --tls-client-cert-path ~/mycert.crt --tls-client-cert-key-path ~/mycert.key 56 57 # Add a private Git BitBucket Data Center repository via HTTPS using bearer token: 58 argocd admin repo generate-spec https://bitbucket.example.com/scm/proj/repo --bearer-token secret-token 59 60 # Add a private Git repository via HTTPS using username/password without verifying the server's TLS certificate 61 argocd admin repo generate-spec https://git.example.com/repos/repo --username git --password secret --insecure-skip-server-verification 62 63 # Add a public Helm repository named 'stable' via HTTPS 64 argocd admin repo generate-spec https://charts.helm.sh/stable --type helm --name stable 65 66 # Add a private Helm repository named 'stable' via HTTPS 67 argocd admin repo generate-spec https://charts.helm.sh/stable --type helm --name stable --username test --password test 68 69 # Add a private Helm OCI-based repository named 'stable' via HTTPS 70 argocd admin repo generate-spec helm-oci-registry.cn-zhangjiakou.cr.aliyuncs.com --type helm --name stable --enable-oci --username test --password test 71 72 # Add a private HTTPS OCI repository named 'stable' 73 argocd admin repo generate-spec oci://helm-oci-registry.cn-zhangjiakou.cr.aliyuncs.com --type oci --name stable --username test --password test 74 75 # Add a private OCI repository named 'stable' without verifying the server's TLS certificate 76 argocd admin repo generate-spec oci://helm-oci-registry.cn-zhangjiakou.cr.aliyuncs.com --type oci --name stable --username test --password test --insecure-skip-server-verification 77 78 # Add a private HTTP OCI repository named 'stable' 79 argocd admin repo generate-spec oci://helm-oci-registry.cn-zhangjiakou.cr.aliyuncs.com --type oci --name stable --username test --password test --insecure-oci-force-http 80 ` 81 82 command := &cobra.Command{ 83 Use: "generate-spec REPOURL", 84 Short: "Generate declarative config for a repo", 85 Example: repoAddExamples, 86 Run: func(c *cobra.Command, args []string) { 87 ctx := c.Context() 88 89 log.SetLevel(log.WarnLevel) 90 if len(args) != 1 { 91 c.HelpFunc()(c, args) 92 os.Exit(1) 93 } 94 95 // Repository URL 96 repoOpts.Repo.Repo = args[0] 97 98 // Specifying ssh-private-key-path is only valid for SSH repositories 99 if repoOpts.SshPrivateKeyPath != "" { 100 if ok, _ := git.IsSSHURL(repoOpts.Repo.Repo); ok { 101 keyData, err := os.ReadFile(repoOpts.SshPrivateKeyPath) 102 if err != nil { 103 log.Fatal(err) 104 } 105 repoOpts.Repo.SSHPrivateKey = string(keyData) 106 } else { 107 err := stderrors.New("--ssh-private-key-path is only supported for SSH repositories") 108 errors.CheckError(err) 109 } 110 } 111 112 // tls-client-cert-path and tls-client-cert-key-key-path must always be 113 // specified together 114 if (repoOpts.TlsClientCertPath != "" && repoOpts.TlsClientCertKeyPath == "") || (repoOpts.TlsClientCertPath == "" && repoOpts.TlsClientCertKeyPath != "") { 115 err := stderrors.New("--tls-client-cert-path and --tls-client-cert-key-path must be specified together") 116 errors.CheckError(err) 117 } 118 119 // Specifying tls-client-cert-path is only valid for HTTPS repositories 120 if repoOpts.TlsClientCertPath != "" { 121 if git.IsHTTPSURL(repoOpts.Repo.Repo) { 122 tlsCertData, err := os.ReadFile(repoOpts.TlsClientCertPath) 123 errors.CheckError(err) 124 tlsCertKey, err := os.ReadFile(repoOpts.TlsClientCertKeyPath) 125 errors.CheckError(err) 126 repoOpts.Repo.TLSClientCertData = string(tlsCertData) 127 repoOpts.Repo.TLSClientCertKey = string(tlsCertKey) 128 } else { 129 err := stderrors.New("--tls-client-cert-path is only supported for HTTPS repositories") 130 errors.CheckError(err) 131 } 132 } 133 134 // Set repository connection properties only when creating repository, not 135 // when creating repository credentials. 136 // InsecureIgnoreHostKey is deprecated and only here for backwards compat 137 repoOpts.Repo.InsecureIgnoreHostKey = repoOpts.InsecureIgnoreHostKey 138 repoOpts.Repo.Insecure = repoOpts.InsecureSkipServerVerification 139 repoOpts.Repo.EnableLFS = repoOpts.EnableLfs 140 repoOpts.Repo.EnableOCI = repoOpts.EnableOci 141 repoOpts.Repo.UseAzureWorkloadIdentity = repoOpts.UseAzureWorkloadIdentity 142 repoOpts.Repo.InsecureOCIForceHttp = repoOpts.InsecureOCIForceHTTP 143 144 if repoOpts.Repo.Type == "helm" && repoOpts.Repo.Name == "" { 145 errors.CheckError(stderrors.New("must specify --name for repos of type 'helm'")) 146 } 147 148 // If the user set a username, but didn't supply password via --password, 149 // then we prompt for it 150 if repoOpts.Repo.Username != "" && repoOpts.Repo.Password == "" { 151 repoOpts.Repo.Password = cli.PromptPassword(repoOpts.Repo.Password) 152 } 153 154 err := cmdutil.ValidateBearerTokenAndPasswordCombo(repoOpts.Repo.BearerToken, repoOpts.Repo.Password) 155 errors.CheckError(err) 156 err = cmdutil.ValidateBearerTokenForHTTPSRepoOnly(repoOpts.Repo.BearerToken, git.IsHTTPSURL(repoOpts.Repo.Repo)) 157 errors.CheckError(err) 158 err = cmdutil.ValidateBearerTokenForGitOnly(repoOpts.Repo.BearerToken, repoOpts.Repo.Type) 159 errors.CheckError(err) 160 161 argoCDCM := &corev1.ConfigMap{ 162 TypeMeta: metav1.TypeMeta{ 163 Kind: "ConfigMap", 164 APIVersion: "v1", 165 }, 166 ObjectMeta: metav1.ObjectMeta{ 167 Name: common.ArgoCDConfigMapName, 168 Namespace: ArgoCDNamespace, 169 Labels: map[string]string{ 170 "app.kubernetes.io/part-of": "argocd", 171 }, 172 }, 173 } 174 kubeClientset := fake.NewClientset(argoCDCM) 175 settingsMgr := settings.NewSettingsManager(ctx, kubeClientset, ArgoCDNamespace) 176 argoDB := db.NewDB(ArgoCDNamespace, settingsMgr, kubeClientset) 177 178 _, err = argoDB.CreateRepository(ctx, &repoOpts.Repo) 179 errors.CheckError(err) 180 181 secret, err := kubeClientset.CoreV1().Secrets(ArgoCDNamespace).Get(ctx, db.RepoURLToSecretName(repoSecretPrefix, repoOpts.Repo.Repo, repoOpts.Repo.Project), metav1.GetOptions{}) 182 errors.CheckError(err) 183 184 errors.CheckError(PrintResources(outputFormat, os.Stdout, secret)) 185 }, 186 } 187 command.Flags().StringVarP(&outputFormat, "output", "o", "yaml", "Output format. One of: json|yaml") 188 cmdutil.AddRepoFlags(command, &repoOpts) 189 return command 190 }