mirror of
https://github.com/fluxcd/flux2.git
synced 2025-10-30 07:47:09 +08:00
Remove file reading from bootstrap package
Signed-off-by: Philip Laine <philip.laine@gmail.com>
This commit is contained in:
@ -212,19 +212,18 @@ func bootstrapBServerCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
secretOpts.Username = bServerArgs.username
|
secretOpts.Username = bServerArgs.username
|
||||||
}
|
}
|
||||||
secretOpts.Password = bitbucketToken
|
secretOpts.Password = bitbucketToken
|
||||||
|
secretOpts.CAFile = caBundle
|
||||||
if bootstrapArgs.caFile != "" {
|
|
||||||
secretOpts.CAFilePath = bootstrapArgs.caFile
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
|
keypair, err := sourcesecret.LoadKeyPairFromPath(bootstrapArgs.privateKeyFile, gitArgs.password)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
secretOpts.Keypair = keypair
|
||||||
secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(bootstrapArgs.keyAlgorithm)
|
secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(bootstrapArgs.keyAlgorithm)
|
||||||
secretOpts.RSAKeyBits = int(bootstrapArgs.keyRSABits)
|
secretOpts.RSAKeyBits = int(bootstrapArgs.keyRSABits)
|
||||||
secretOpts.ECDSACurve = bootstrapArgs.keyECDSACurve.Curve
|
secretOpts.ECDSACurve = bootstrapArgs.keyECDSACurve.Curve
|
||||||
secretOpts.SSHHostname = bServerArgs.hostname
|
|
||||||
|
|
||||||
if bootstrapArgs.privateKeyFile != "" {
|
secretOpts.SSHHostname = bServerArgs.hostname
|
||||||
secretOpts.PrivateKeyPath = bootstrapArgs.privateKeyFile
|
|
||||||
}
|
|
||||||
if bootstrapArgs.sshHostname != "" {
|
if bootstrapArgs.sshHostname != "" {
|
||||||
secretOpts.SSHHostname = bootstrapArgs.sshHostname
|
secretOpts.SSHHostname = bootstrapArgs.sshHostname
|
||||||
}
|
}
|
||||||
@ -243,7 +242,13 @@ func bootstrapBServerCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
RecurseSubmodules: bootstrapArgs.recurseSubmodules,
|
RecurseSubmodules: bootstrapArgs.recurseSubmodules,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entityList, err := bootstrap.LoadEntityListFromPath(bootstrapArgs.gpgKeyRingPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Bootstrap config
|
// Bootstrap config
|
||||||
|
|
||||||
bootstrapOpts := []bootstrap.GitProviderOption{
|
bootstrapOpts := []bootstrap.GitProviderOption{
|
||||||
bootstrap.WithProviderRepository(bServerArgs.owner, bServerArgs.repository, bServerArgs.personal),
|
bootstrap.WithProviderRepository(bServerArgs.owner, bServerArgs.repository, bServerArgs.personal),
|
||||||
bootstrap.WithBranch(bootstrapArgs.branch),
|
bootstrap.WithBranch(bootstrapArgs.branch),
|
||||||
@ -255,7 +260,7 @@ func bootstrapBServerCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
bootstrap.WithKubeconfig(kubeconfigArgs, kubeclientOptions),
|
bootstrap.WithKubeconfig(kubeconfigArgs, kubeclientOptions),
|
||||||
bootstrap.WithLogger(logger),
|
bootstrap.WithLogger(logger),
|
||||||
bootstrap.WithCABundle(caBundle),
|
bootstrap.WithCABundle(caBundle),
|
||||||
bootstrap.WithGitCommitSigning(bootstrapArgs.gpgKeyRingPath, bootstrapArgs.gpgPassphrase, bootstrapArgs.gpgKeyID),
|
bootstrap.WithGitCommitSigning(entityList, bootstrapArgs.gpgPassphrase, bootstrapArgs.gpgKeyID),
|
||||||
}
|
}
|
||||||
if bootstrapArgs.sshHostname != "" {
|
if bootstrapArgs.sshHostname != "" {
|
||||||
bootstrapOpts = append(bootstrapOpts, bootstrap.WithSSHHostname(bootstrapArgs.sshHostname))
|
bootstrapOpts = append(bootstrapOpts, bootstrap.WithSSHHostname(bootstrapArgs.sshHostname))
|
||||||
|
|||||||
@ -169,6 +169,15 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
installOptions.BaseURL = customBaseURL
|
installOptions.BaseURL = customBaseURL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var caBundle []byte
|
||||||
|
if bootstrapArgs.caFile != "" {
|
||||||
|
var err error
|
||||||
|
caBundle, err = os.ReadFile(bootstrapArgs.caFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to read TLS CA file: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Source generation and secret config
|
// Source generation and secret config
|
||||||
secretOpts := sourcesecret.Options{
|
secretOpts := sourcesecret.Options{
|
||||||
Name: bootstrapArgs.secretName,
|
Name: bootstrapArgs.secretName,
|
||||||
@ -179,10 +188,7 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
if bootstrapArgs.tokenAuth {
|
if bootstrapArgs.tokenAuth {
|
||||||
secretOpts.Username = gitArgs.username
|
secretOpts.Username = gitArgs.username
|
||||||
secretOpts.Password = gitArgs.password
|
secretOpts.Password = gitArgs.password
|
||||||
|
secretOpts.CAFile = caBundle
|
||||||
if bootstrapArgs.caFile != "" {
|
|
||||||
secretOpts.CAFilePath = bootstrapArgs.caFile
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove port of the given host when not syncing over HTTP/S to not assume port for protocol
|
// Remove port of the given host when not syncing over HTTP/S to not assume port for protocol
|
||||||
// This _might_ be overwritten later on by e.g. --ssh-hostname
|
// This _might_ be overwritten later on by e.g. --ssh-hostname
|
||||||
@ -213,9 +219,12 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
if bootstrapArgs.sshHostname != "" {
|
if bootstrapArgs.sshHostname != "" {
|
||||||
repositoryURL.Host = bootstrapArgs.sshHostname
|
repositoryURL.Host = bootstrapArgs.sshHostname
|
||||||
}
|
}
|
||||||
if bootstrapArgs.privateKeyFile != "" {
|
|
||||||
secretOpts.PrivateKeyPath = bootstrapArgs.privateKeyFile
|
keypair, err := sourcesecret.LoadKeyPairFromPath(bootstrapArgs.privateKeyFile, gitArgs.password)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
secretOpts.Keypair = keypair
|
||||||
|
|
||||||
// Configure last as it depends on the config above.
|
// Configure last as it depends on the config above.
|
||||||
secretOpts.SSHHostname = repositoryURL.Host
|
secretOpts.SSHHostname = repositoryURL.Host
|
||||||
@ -235,13 +244,9 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
RecurseSubmodules: bootstrapArgs.recurseSubmodules,
|
RecurseSubmodules: bootstrapArgs.recurseSubmodules,
|
||||||
}
|
}
|
||||||
|
|
||||||
var caBundle []byte
|
entityList, err := bootstrap.LoadEntityListFromPath(bootstrapArgs.gpgKeyRingPath)
|
||||||
if bootstrapArgs.caFile != "" {
|
|
||||||
var err error
|
|
||||||
caBundle, err = os.ReadFile(bootstrapArgs.caFile)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("unable to read TLS CA file: %w", err)
|
return err
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bootstrap config
|
// Bootstrap config
|
||||||
@ -254,7 +259,7 @@ func bootstrapGitCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
bootstrap.WithPostGenerateSecretFunc(promptPublicKey),
|
bootstrap.WithPostGenerateSecretFunc(promptPublicKey),
|
||||||
bootstrap.WithLogger(logger),
|
bootstrap.WithLogger(logger),
|
||||||
bootstrap.WithCABundle(caBundle),
|
bootstrap.WithCABundle(caBundle),
|
||||||
bootstrap.WithGitCommitSigning(bootstrapArgs.gpgKeyRingPath, bootstrapArgs.gpgPassphrase, bootstrapArgs.gpgKeyID),
|
bootstrap.WithGitCommitSigning(entityList, bootstrapArgs.gpgPassphrase, bootstrapArgs.gpgKeyID),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setup bootstrapper with constructed configs
|
// Setup bootstrapper with constructed configs
|
||||||
|
|||||||
@ -204,16 +204,13 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
if bootstrapArgs.tokenAuth {
|
if bootstrapArgs.tokenAuth {
|
||||||
secretOpts.Username = "git"
|
secretOpts.Username = "git"
|
||||||
secretOpts.Password = ghToken
|
secretOpts.Password = ghToken
|
||||||
|
secretOpts.CAFile = caBundle
|
||||||
if bootstrapArgs.caFile != "" {
|
|
||||||
secretOpts.CAFilePath = bootstrapArgs.caFile
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(bootstrapArgs.keyAlgorithm)
|
secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(bootstrapArgs.keyAlgorithm)
|
||||||
secretOpts.RSAKeyBits = int(bootstrapArgs.keyRSABits)
|
secretOpts.RSAKeyBits = int(bootstrapArgs.keyRSABits)
|
||||||
secretOpts.ECDSACurve = bootstrapArgs.keyECDSACurve.Curve
|
secretOpts.ECDSACurve = bootstrapArgs.keyECDSACurve.Curve
|
||||||
secretOpts.SSHHostname = githubArgs.hostname
|
|
||||||
|
|
||||||
|
secretOpts.SSHHostname = githubArgs.hostname
|
||||||
if bootstrapArgs.sshHostname != "" {
|
if bootstrapArgs.sshHostname != "" {
|
||||||
secretOpts.SSHHostname = bootstrapArgs.sshHostname
|
secretOpts.SSHHostname = bootstrapArgs.sshHostname
|
||||||
}
|
}
|
||||||
@ -232,6 +229,11 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
RecurseSubmodules: bootstrapArgs.recurseSubmodules,
|
RecurseSubmodules: bootstrapArgs.recurseSubmodules,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entityList, err := bootstrap.LoadEntityListFromPath(bootstrapArgs.gpgKeyRingPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Bootstrap config
|
// Bootstrap config
|
||||||
bootstrapOpts := []bootstrap.GitProviderOption{
|
bootstrapOpts := []bootstrap.GitProviderOption{
|
||||||
bootstrap.WithProviderRepository(githubArgs.owner, githubArgs.repository, githubArgs.personal),
|
bootstrap.WithProviderRepository(githubArgs.owner, githubArgs.repository, githubArgs.personal),
|
||||||
@ -244,7 +246,7 @@ func bootstrapGitHubCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
bootstrap.WithKubeconfig(kubeconfigArgs, kubeclientOptions),
|
bootstrap.WithKubeconfig(kubeconfigArgs, kubeclientOptions),
|
||||||
bootstrap.WithLogger(logger),
|
bootstrap.WithLogger(logger),
|
||||||
bootstrap.WithCABundle(caBundle),
|
bootstrap.WithCABundle(caBundle),
|
||||||
bootstrap.WithGitCommitSigning(bootstrapArgs.gpgKeyRingPath, bootstrapArgs.gpgPassphrase, bootstrapArgs.gpgKeyID),
|
bootstrap.WithGitCommitSigning(entityList, bootstrapArgs.gpgPassphrase, bootstrapArgs.gpgKeyID),
|
||||||
}
|
}
|
||||||
if bootstrapArgs.sshHostname != "" {
|
if bootstrapArgs.sshHostname != "" {
|
||||||
bootstrapOpts = append(bootstrapOpts, bootstrap.WithSSHHostname(bootstrapArgs.sshHostname))
|
bootstrapOpts = append(bootstrapOpts, bootstrap.WithSSHHostname(bootstrapArgs.sshHostname))
|
||||||
|
|||||||
@ -215,19 +215,18 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
if bootstrapArgs.tokenAuth {
|
if bootstrapArgs.tokenAuth {
|
||||||
secretOpts.Username = "git"
|
secretOpts.Username = "git"
|
||||||
secretOpts.Password = glToken
|
secretOpts.Password = glToken
|
||||||
|
secretOpts.CAFile = caBundle
|
||||||
if bootstrapArgs.caFile != "" {
|
|
||||||
secretOpts.CAFilePath = bootstrapArgs.caFile
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
|
keypair, err := sourcesecret.LoadKeyPairFromPath(bootstrapArgs.privateKeyFile, gitArgs.password)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
secretOpts.Keypair = keypair
|
||||||
secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(bootstrapArgs.keyAlgorithm)
|
secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(bootstrapArgs.keyAlgorithm)
|
||||||
secretOpts.RSAKeyBits = int(bootstrapArgs.keyRSABits)
|
secretOpts.RSAKeyBits = int(bootstrapArgs.keyRSABits)
|
||||||
secretOpts.ECDSACurve = bootstrapArgs.keyECDSACurve.Curve
|
secretOpts.ECDSACurve = bootstrapArgs.keyECDSACurve.Curve
|
||||||
secretOpts.SSHHostname = gitlabArgs.hostname
|
|
||||||
|
|
||||||
if bootstrapArgs.privateKeyFile != "" {
|
secretOpts.SSHHostname = gitlabArgs.hostname
|
||||||
secretOpts.PrivateKeyPath = bootstrapArgs.privateKeyFile
|
|
||||||
}
|
|
||||||
if bootstrapArgs.sshHostname != "" {
|
if bootstrapArgs.sshHostname != "" {
|
||||||
secretOpts.SSHHostname = bootstrapArgs.sshHostname
|
secretOpts.SSHHostname = bootstrapArgs.sshHostname
|
||||||
}
|
}
|
||||||
@ -246,6 +245,11 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
RecurseSubmodules: bootstrapArgs.recurseSubmodules,
|
RecurseSubmodules: bootstrapArgs.recurseSubmodules,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
entityList, err := bootstrap.LoadEntityListFromPath(bootstrapArgs.gpgKeyRingPath)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Bootstrap config
|
// Bootstrap config
|
||||||
bootstrapOpts := []bootstrap.GitProviderOption{
|
bootstrapOpts := []bootstrap.GitProviderOption{
|
||||||
bootstrap.WithProviderRepository(gitlabArgs.owner, gitlabArgs.repository, gitlabArgs.personal),
|
bootstrap.WithProviderRepository(gitlabArgs.owner, gitlabArgs.repository, gitlabArgs.personal),
|
||||||
@ -258,7 +262,7 @@ func bootstrapGitLabCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
bootstrap.WithKubeconfig(kubeconfigArgs, kubeclientOptions),
|
bootstrap.WithKubeconfig(kubeconfigArgs, kubeclientOptions),
|
||||||
bootstrap.WithLogger(logger),
|
bootstrap.WithLogger(logger),
|
||||||
bootstrap.WithCABundle(caBundle),
|
bootstrap.WithCABundle(caBundle),
|
||||||
bootstrap.WithGitCommitSigning(bootstrapArgs.gpgKeyRingPath, bootstrapArgs.gpgPassphrase, bootstrapArgs.gpgKeyID),
|
bootstrap.WithGitCommitSigning(entityList, bootstrapArgs.gpgPassphrase, bootstrapArgs.gpgKeyID),
|
||||||
}
|
}
|
||||||
if bootstrapArgs.sshHostname != "" {
|
if bootstrapArgs.sshHostname != "" {
|
||||||
bootstrapOpts = append(bootstrapOpts, bootstrap.WithSSHHostname(bootstrapArgs.sshHostname))
|
bootstrapOpts = append(bootstrapOpts, bootstrap.WithSSHHostname(bootstrapArgs.sshHostname))
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import (
|
|||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
@ -135,8 +136,12 @@ func createSecretGitCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
switch u.Scheme {
|
switch u.Scheme {
|
||||||
case "ssh":
|
case "ssh":
|
||||||
|
keypair, err := sourcesecret.LoadKeyPairFromPath(secretGitArgs.privateKeyFile, secretGitArgs.password)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
opts.Keypair = keypair
|
||||||
opts.SSHHostname = u.Host
|
opts.SSHHostname = u.Host
|
||||||
opts.PrivateKeyPath = secretGitArgs.privateKeyFile
|
|
||||||
opts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(secretGitArgs.keyAlgorithm)
|
opts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(secretGitArgs.keyAlgorithm)
|
||||||
opts.RSAKeyBits = int(secretGitArgs.rsaBits)
|
opts.RSAKeyBits = int(secretGitArgs.rsaBits)
|
||||||
opts.ECDSACurve = secretGitArgs.ecdsaCurve.Curve
|
opts.ECDSACurve = secretGitArgs.ecdsaCurve.Curve
|
||||||
@ -147,7 +152,13 @@ func createSecretGitCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
opts.Username = secretGitArgs.username
|
opts.Username = secretGitArgs.username
|
||||||
opts.Password = secretGitArgs.password
|
opts.Password = secretGitArgs.password
|
||||||
opts.CAFilePath = secretGitArgs.caFile
|
if secretGitArgs.caFile != "" {
|
||||||
|
caBundle, err := os.ReadFile(secretGitArgs.caFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to read TLS CA file: %w", err)
|
||||||
|
}
|
||||||
|
opts.CAFile = caBundle
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("git URL scheme '%s' not supported, can be: ssh, http and https", u.Scheme)
|
return fmt.Errorf("git URL scheme '%s' not supported, can be: ssh, http and https", u.Scheme)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,6 +18,8 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
@ -74,15 +76,34 @@ func createSecretHelmCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
caBundle := []byte{}
|
||||||
|
if secretHelmArgs.caFile != "" {
|
||||||
|
var err error
|
||||||
|
caBundle, err = os.ReadFile(secretHelmArgs.caFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to read TLS CA file: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var certFile, keyFile []byte
|
||||||
|
if secretHelmArgs.certFile != "" && secretHelmArgs.keyFile != "" {
|
||||||
|
if certFile, err = os.ReadFile(secretHelmArgs.certFile); err != nil {
|
||||||
|
return fmt.Errorf("failed to read cert file: %w", err)
|
||||||
|
}
|
||||||
|
if keyFile, err = os.ReadFile(secretHelmArgs.keyFile); err != nil {
|
||||||
|
return fmt.Errorf("failed to read key file: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
opts := sourcesecret.Options{
|
opts := sourcesecret.Options{
|
||||||
Name: name,
|
Name: name,
|
||||||
Namespace: *kubeconfigArgs.Namespace,
|
Namespace: *kubeconfigArgs.Namespace,
|
||||||
Labels: labels,
|
Labels: labels,
|
||||||
Username: secretHelmArgs.username,
|
Username: secretHelmArgs.username,
|
||||||
Password: secretHelmArgs.password,
|
Password: secretHelmArgs.password,
|
||||||
CAFilePath: secretHelmArgs.caFile,
|
CAFile: caBundle,
|
||||||
CertFilePath: secretHelmArgs.certFile,
|
CertFile: certFile,
|
||||||
KeyFilePath: secretHelmArgs.keyFile,
|
KeyFile: keyFile,
|
||||||
}
|
}
|
||||||
secret, err := sourcesecret.Generate(opts)
|
secret, err := sourcesecret.Generate(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -18,6 +18,8 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
@ -73,13 +75,32 @@ func createSecretTLSCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
caBundle := []byte{}
|
||||||
|
if secretTLSArgs.caFile != "" {
|
||||||
|
var err error
|
||||||
|
caBundle, err = os.ReadFile(secretTLSArgs.caFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to read TLS CA file: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var certFile, keyFile []byte
|
||||||
|
if secretTLSArgs.certFile != "" && secretTLSArgs.keyFile != "" {
|
||||||
|
if certFile, err = os.ReadFile(secretTLSArgs.certFile); err != nil {
|
||||||
|
return fmt.Errorf("failed to read cert file: %w", err)
|
||||||
|
}
|
||||||
|
if keyFile, err = os.ReadFile(secretTLSArgs.keyFile); err != nil {
|
||||||
|
return fmt.Errorf("failed to read key file: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
opts := sourcesecret.Options{
|
opts := sourcesecret.Options{
|
||||||
Name: name,
|
Name: name,
|
||||||
Namespace: *kubeconfigArgs.Namespace,
|
Namespace: *kubeconfigArgs.Namespace,
|
||||||
Labels: labels,
|
Labels: labels,
|
||||||
CAFilePath: secretTLSArgs.caFile,
|
CAFile: caBundle,
|
||||||
CertFilePath: secretTLSArgs.certFile,
|
CertFile: certFile,
|
||||||
KeyFilePath: secretTLSArgs.keyFile,
|
KeyFile: keyFile,
|
||||||
}
|
}
|
||||||
secret, err := sourcesecret.Generate(opts)
|
secret, err := sourcesecret.Generate(opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@ -259,16 +259,26 @@ func createSourceGitCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
switch u.Scheme {
|
switch u.Scheme {
|
||||||
case "ssh":
|
case "ssh":
|
||||||
|
keypair, err := sourcesecret.LoadKeyPairFromPath(sourceGitArgs.privateKeyFile, sourceGitArgs.password)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
secretOpts.Keypair = keypair
|
||||||
secretOpts.SSHHostname = u.Host
|
secretOpts.SSHHostname = u.Host
|
||||||
secretOpts.PrivateKeyPath = sourceGitArgs.privateKeyFile
|
|
||||||
secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(sourceGitArgs.keyAlgorithm)
|
secretOpts.PrivateKeyAlgorithm = sourcesecret.PrivateKeyAlgorithm(sourceGitArgs.keyAlgorithm)
|
||||||
secretOpts.RSAKeyBits = int(sourceGitArgs.keyRSABits)
|
secretOpts.RSAKeyBits = int(sourceGitArgs.keyRSABits)
|
||||||
secretOpts.ECDSACurve = sourceGitArgs.keyECDSACurve.Curve
|
secretOpts.ECDSACurve = sourceGitArgs.keyECDSACurve.Curve
|
||||||
secretOpts.Password = sourceGitArgs.password
|
secretOpts.Password = sourceGitArgs.password
|
||||||
case "https":
|
case "https":
|
||||||
|
if sourceGitArgs.caFile != "" {
|
||||||
|
caBundle, err := os.ReadFile(sourceGitArgs.caFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to read TLS CA file: %w", err)
|
||||||
|
}
|
||||||
|
secretOpts.CAFile = caBundle
|
||||||
|
}
|
||||||
secretOpts.Username = sourceGitArgs.username
|
secretOpts.Username = sourceGitArgs.username
|
||||||
secretOpts.Password = sourceGitArgs.password
|
secretOpts.Password = sourceGitArgs.password
|
||||||
secretOpts.CAFilePath = sourceGitArgs.caFile
|
|
||||||
case "http":
|
case "http":
|
||||||
logger.Warningf("insecure configuration: credentials configured for an HTTP URL")
|
logger.Warningf("insecure configuration: credentials configured for an HTTP URL")
|
||||||
secretOpts.Username = sourceGitArgs.username
|
secretOpts.Username = sourceGitArgs.username
|
||||||
|
|||||||
@ -168,6 +168,25 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
caBundle := []byte{}
|
||||||
|
if sourceHelmArgs.caFile != "" {
|
||||||
|
var err error
|
||||||
|
caBundle, err = os.ReadFile(sourceHelmArgs.caFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("unable to read TLS CA file: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var certFile, keyFile []byte
|
||||||
|
if sourceHelmArgs.certFile != "" && sourceHelmArgs.keyFile != "" {
|
||||||
|
if certFile, err = os.ReadFile(sourceHelmArgs.certFile); err != nil {
|
||||||
|
return fmt.Errorf("failed to read cert file: %w", err)
|
||||||
|
}
|
||||||
|
if keyFile, err = os.ReadFile(sourceHelmArgs.keyFile); err != nil {
|
||||||
|
return fmt.Errorf("failed to read key file: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
logger.Generatef("generating HelmRepository source")
|
logger.Generatef("generating HelmRepository source")
|
||||||
if sourceHelmArgs.secretRef == "" {
|
if sourceHelmArgs.secretRef == "" {
|
||||||
secretName := fmt.Sprintf("helm-%s", name)
|
secretName := fmt.Sprintf("helm-%s", name)
|
||||||
@ -176,9 +195,9 @@ func createSourceHelmCmdRun(cmd *cobra.Command, args []string) error {
|
|||||||
Namespace: *kubeconfigArgs.Namespace,
|
Namespace: *kubeconfigArgs.Namespace,
|
||||||
Username: sourceHelmArgs.username,
|
Username: sourceHelmArgs.username,
|
||||||
Password: sourceHelmArgs.password,
|
Password: sourceHelmArgs.password,
|
||||||
CertFilePath: sourceHelmArgs.certFile,
|
CAFile: caBundle,
|
||||||
KeyFilePath: sourceHelmArgs.keyFile,
|
CertFile: certFile,
|
||||||
CAFilePath: sourceHelmArgs.caFile,
|
KeyFile: keyFile,
|
||||||
ManifestFile: sourcesecret.MakeDefaultOptions().ManifestFile,
|
ManifestFile: sourcesecret.MakeDefaultOptions().ManifestFile,
|
||||||
}
|
}
|
||||||
secret, err := sourcesecret.Generate(secretOpts)
|
secret, err := sourcesecret.Generate(secretOpts)
|
||||||
|
|||||||
@ -24,6 +24,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/ProtonMail/go-crypto/openpgp"
|
||||||
gogit "github.com/go-git/go-git/v5"
|
gogit "github.com/go-git/go-git/v5"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||||
@ -56,7 +57,7 @@ type PlainGitBootstrapper struct {
|
|||||||
author git.Author
|
author git.Author
|
||||||
commitMessageAppendix string
|
commitMessageAppendix string
|
||||||
|
|
||||||
gpgKeyRingPath string
|
gpgKeyRing openpgp.EntityList
|
||||||
gpgPassphrase string
|
gpgPassphrase string
|
||||||
gpgKeyID string
|
gpgKeyID string
|
||||||
|
|
||||||
@ -139,7 +140,7 @@ func (b *PlainGitBootstrapper) ReconcileComponents(ctx context.Context, manifest
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Git commit generated
|
// Git commit generated
|
||||||
gpgOpts := git.WithGpgSigningOption(b.gpgKeyRingPath, b.gpgPassphrase, b.gpgKeyID)
|
gpgOpts := git.WithGpgSigningOption(b.gpgKeyRing, b.gpgPassphrase, b.gpgKeyID)
|
||||||
commitMsg := fmt.Sprintf("Add Flux %s component manifests", options.Version)
|
commitMsg := fmt.Sprintf("Add Flux %s component manifests", options.Version)
|
||||||
if b.commitMessageAppendix != "" {
|
if b.commitMessageAppendix != "" {
|
||||||
commitMsg = commitMsg + "\n\n" + b.commitMessageAppendix
|
commitMsg = commitMsg + "\n\n" + b.commitMessageAppendix
|
||||||
@ -195,7 +196,7 @@ func (b *PlainGitBootstrapper) ReconcileSourceSecret(ctx context.Context, option
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return early if exists and no custom config is passed
|
// Return early if exists and no custom config is passed
|
||||||
if ok && len(options.CAFilePath+options.PrivateKeyPath+options.Username+options.Password) == 0 {
|
if ok && options.Keypair == nil && len(options.CAFile) == 0 && len(options.Username+options.Password) == 0 {
|
||||||
b.logger.Successf("source secret up to date")
|
b.logger.Successf("source secret up to date")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -284,7 +285,7 @@ func (b *PlainGitBootstrapper) ReconcileSyncConfig(ctx context.Context, options
|
|||||||
b.logger.Successf("generated sync manifests")
|
b.logger.Successf("generated sync manifests")
|
||||||
|
|
||||||
// Git commit generated
|
// Git commit generated
|
||||||
gpgOpts := git.WithGpgSigningOption(b.gpgKeyRingPath, b.gpgPassphrase, b.gpgKeyID)
|
gpgOpts := git.WithGpgSigningOption(b.gpgKeyRing, b.gpgPassphrase, b.gpgKeyID)
|
||||||
commitMsg := fmt.Sprintf("Add Flux sync manifests")
|
commitMsg := fmt.Sprintf("Add Flux sync manifests")
|
||||||
if b.commitMessageAppendix != "" {
|
if b.commitMessageAppendix != "" {
|
||||||
commitMsg = commitMsg + "\n\n" + b.commitMessageAppendix
|
commitMsg = commitMsg + "\n\n" + b.commitMessageAppendix
|
||||||
|
|||||||
@ -1,5 +1,9 @@
|
|||||||
package git
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/ProtonMail/go-crypto/openpgp"
|
||||||
|
)
|
||||||
|
|
||||||
// Option is a some configuration that modifies options for a commit.
|
// Option is a some configuration that modifies options for a commit.
|
||||||
type Option interface {
|
type Option interface {
|
||||||
// ApplyToCommit applies this configuration to a given commit option.
|
// ApplyToCommit applies this configuration to a given commit option.
|
||||||
@ -13,7 +17,7 @@ type CommitOptions struct {
|
|||||||
|
|
||||||
// GPGSigningInfo contains information for signing a commit.
|
// GPGSigningInfo contains information for signing a commit.
|
||||||
type GPGSigningInfo struct {
|
type GPGSigningInfo struct {
|
||||||
KeyRingPath string
|
KeyRing openpgp.EntityList
|
||||||
Passphrase string
|
Passphrase string
|
||||||
KeyID string
|
KeyID string
|
||||||
}
|
}
|
||||||
@ -26,15 +30,15 @@ func (w GpgSigningOption) ApplyToCommit(in *CommitOptions) {
|
|||||||
in.GPGSigningInfo = w.GPGSigningInfo
|
in.GPGSigningInfo = w.GPGSigningInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithGpgSigningOption(path, passphrase, keyID string) Option {
|
func WithGpgSigningOption(keyRing openpgp.EntityList, passphrase, keyID string) Option {
|
||||||
// Return nil if no path is set, even if other options are configured.
|
// Return nil if no path is set, even if other options are configured.
|
||||||
if path == "" {
|
if len(keyRing) == 0 {
|
||||||
return GpgSigningOption{}
|
return GpgSigningOption{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return GpgSigningOption{
|
return GpgSigningOption{
|
||||||
GPGSigningInfo: &GPGSigningInfo{
|
GPGSigningInfo: &GPGSigningInfo{
|
||||||
KeyRingPath: path,
|
KeyRing: keyRing,
|
||||||
Passphrase: passphrase,
|
Passphrase: passphrase,
|
||||||
KeyID: keyID,
|
KeyID: keyID,
|
||||||
},
|
},
|
||||||
|
|||||||
@ -258,23 +258,13 @@ func isRemoteBranchNotFoundErr(err error, ref string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getOpenPgpEntity(info git.GPGSigningInfo) (*openpgp.Entity, error) {
|
func getOpenPgpEntity(info git.GPGSigningInfo) (*openpgp.Entity, error) {
|
||||||
r, err := os.Open(info.KeyRingPath)
|
if len(info.KeyRing) == 0 {
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("unable to open GPG key ring: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
entityList, err := openpgp.ReadKeyRing(r)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(entityList) == 0 {
|
|
||||||
return nil, fmt.Errorf("empty GPG key ring")
|
return nil, fmt.Errorf("empty GPG key ring")
|
||||||
}
|
}
|
||||||
|
|
||||||
var entity *openpgp.Entity
|
var entity *openpgp.Entity
|
||||||
if info.KeyID != "" {
|
if info.KeyID != "" {
|
||||||
for _, ent := range entityList {
|
for _, ent := range info.KeyRing {
|
||||||
if ent.PrimaryKey.KeyIdString() == info.KeyID {
|
if ent.PrimaryKey.KeyIdString() == info.KeyID {
|
||||||
entity = ent
|
entity = ent
|
||||||
}
|
}
|
||||||
@ -284,10 +274,10 @@ func getOpenPgpEntity(info git.GPGSigningInfo) (*openpgp.Entity, error) {
|
|||||||
return nil, fmt.Errorf("no GPG private key matching key id '%s' found", info.KeyID)
|
return nil, fmt.Errorf("no GPG private key matching key id '%s' found", info.KeyID)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
entity = entityList[0]
|
entity = info.KeyRing[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
err = entity.PrivateKey.Decrypt([]byte(info.Passphrase))
|
err := entity.PrivateKey.Decrypt([]byte(info.Passphrase))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to decrypt GPG private key: %w", err)
|
return nil, fmt.Errorf("unable to decrypt GPG private key: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,8 +4,10 @@
|
|||||||
package gogit
|
package gogit
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/ProtonMail/go-crypto/openpgp"
|
||||||
"github.com/fluxcd/flux2/pkg/bootstrap/git"
|
"github.com/fluxcd/flux2/pkg/bootstrap/git"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -49,8 +51,19 @@ func TestGetOpenPgpEntity(t *testing.T) {
|
|||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
var entityList openpgp.EntityList
|
||||||
|
if tt.keyPath != "" {
|
||||||
|
r, err := os.Open(tt.keyPath)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
entityList, err = openpgp.ReadKeyRing(r)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
gpgInfo := git.GPGSigningInfo{
|
gpgInfo := git.GPGSigningInfo{
|
||||||
KeyRingPath: tt.keyPath,
|
KeyRing: entityList,
|
||||||
Passphrase: tt.passphrase,
|
Passphrase: tt.passphrase,
|
||||||
KeyID: tt.id,
|
KeyID: tt.id,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,8 +17,12 @@ limitations under the License.
|
|||||||
package bootstrap
|
package bootstrap
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||||
|
|
||||||
|
"github.com/ProtonMail/go-crypto/openpgp"
|
||||||
runclient "github.com/fluxcd/pkg/runtime/client"
|
runclient "github.com/fluxcd/pkg/runtime/client"
|
||||||
|
|
||||||
"github.com/fluxcd/flux2/pkg/bootstrap/git"
|
"github.com/fluxcd/flux2/pkg/bootstrap/git"
|
||||||
@ -131,22 +135,22 @@ func (o loggerOption) applyGitProvider(b *GitProviderBootstrapper) {
|
|||||||
b.logger = o.logger
|
b.logger = o.logger
|
||||||
}
|
}
|
||||||
|
|
||||||
func WithGitCommitSigning(path, passphrase, keyID string) Option {
|
func WithGitCommitSigning(gpgKeyRing openpgp.EntityList, passphrase, keyID string) Option {
|
||||||
return gitCommitSigningOption{
|
return gitCommitSigningOption{
|
||||||
gpgKeyRingPath: path,
|
gpgKeyRing: gpgKeyRing,
|
||||||
gpgPassphrase: passphrase,
|
gpgPassphrase: passphrase,
|
||||||
gpgKeyID: keyID,
|
gpgKeyID: keyID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type gitCommitSigningOption struct {
|
type gitCommitSigningOption struct {
|
||||||
gpgKeyRingPath string
|
gpgKeyRing openpgp.EntityList
|
||||||
gpgPassphrase string
|
gpgPassphrase string
|
||||||
gpgKeyID string
|
gpgKeyID string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o gitCommitSigningOption) applyGit(b *PlainGitBootstrapper) {
|
func (o gitCommitSigningOption) applyGit(b *PlainGitBootstrapper) {
|
||||||
b.gpgKeyRingPath = o.gpgKeyRingPath
|
b.gpgKeyRing = o.gpgKeyRing
|
||||||
b.gpgPassphrase = o.gpgPassphrase
|
b.gpgPassphrase = o.gpgPassphrase
|
||||||
b.gpgKeyID = o.gpgKeyID
|
b.gpgKeyID = o.gpgKeyID
|
||||||
}
|
}
|
||||||
@ -154,3 +158,18 @@ func (o gitCommitSigningOption) applyGit(b *PlainGitBootstrapper) {
|
|||||||
func (o gitCommitSigningOption) applyGitProvider(b *GitProviderBootstrapper) {
|
func (o gitCommitSigningOption) applyGitProvider(b *GitProviderBootstrapper) {
|
||||||
o.applyGit(b.PlainGitBootstrapper)
|
o.applyGit(b.PlainGitBootstrapper)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func LoadEntityListFromPath(path string) (openpgp.EntityList, error) {
|
||||||
|
if path == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
r, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to open GPG key ring: %w", err)
|
||||||
|
}
|
||||||
|
entityList, err := openpgp.ReadKeyRing(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return entityList, nil
|
||||||
|
}
|
||||||
|
|||||||
@ -18,6 +18,8 @@ package sourcesecret
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/elliptic"
|
"crypto/elliptic"
|
||||||
|
|
||||||
|
"github.com/fluxcd/pkg/ssh"
|
||||||
)
|
)
|
||||||
|
|
||||||
type PrivateKeyAlgorithm string
|
type PrivateKeyAlgorithm string
|
||||||
@ -48,12 +50,12 @@ type Options struct {
|
|||||||
PrivateKeyAlgorithm PrivateKeyAlgorithm
|
PrivateKeyAlgorithm PrivateKeyAlgorithm
|
||||||
RSAKeyBits int
|
RSAKeyBits int
|
||||||
ECDSACurve elliptic.Curve
|
ECDSACurve elliptic.Curve
|
||||||
PrivateKeyPath string
|
Keypair *ssh.KeyPair
|
||||||
Username string
|
Username string
|
||||||
Password string
|
Password string
|
||||||
CAFilePath string
|
CAFile []byte
|
||||||
CertFilePath string
|
CertFile []byte
|
||||||
KeyFilePath string
|
KeyFile []byte
|
||||||
TargetPath string
|
TargetPath string
|
||||||
ManifestFile string
|
ManifestFile string
|
||||||
}
|
}
|
||||||
@ -64,12 +66,11 @@ func MakeDefaultOptions() Options {
|
|||||||
Namespace: "flux-system",
|
Namespace: "flux-system",
|
||||||
Labels: map[string]string{},
|
Labels: map[string]string{},
|
||||||
PrivateKeyAlgorithm: RSAPrivateKeyAlgorithm,
|
PrivateKeyAlgorithm: RSAPrivateKeyAlgorithm,
|
||||||
PrivateKeyPath: "",
|
|
||||||
Username: "",
|
Username: "",
|
||||||
Password: "",
|
Password: "",
|
||||||
CAFilePath: "",
|
CAFile: []byte{},
|
||||||
CertFilePath: "",
|
CertFile: []byte{},
|
||||||
KeyFilePath: "",
|
KeyFile: []byte{},
|
||||||
ManifestFile: "secret.yaml",
|
ManifestFile: "secret.yaml",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -66,10 +66,8 @@ func Generate(options Options) (*manifestgen.Manifest, error) {
|
|||||||
switch {
|
switch {
|
||||||
case options.Username != "" && options.Password != "":
|
case options.Username != "" && options.Password != "":
|
||||||
// noop
|
// noop
|
||||||
case len(options.PrivateKeyPath) > 0:
|
case options.Keypair != nil:
|
||||||
if keypair, err = loadKeyPair(options.PrivateKeyPath, options.Password); err != nil {
|
keypair = options.Keypair
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
case len(options.PrivateKeyAlgorithm) > 0:
|
case len(options.PrivateKeyAlgorithm) > 0:
|
||||||
if keypair, err = generateKeyPair(options); err != nil {
|
if keypair, err = generateKeyPair(options); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -83,23 +81,6 @@ func Generate(options Options) (*manifestgen.Manifest, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var caFile []byte
|
|
||||||
if options.CAFilePath != "" {
|
|
||||||
if caFile, err = os.ReadFile(options.CAFilePath); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to read CA file: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var certFile, keyFile []byte
|
|
||||||
if options.CertFilePath != "" && options.KeyFilePath != "" {
|
|
||||||
if certFile, err = os.ReadFile(options.CertFilePath); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to read cert file: %w", err)
|
|
||||||
}
|
|
||||||
if keyFile, err = os.ReadFile(options.KeyFilePath); err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to read key file: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var dockerCfgJson []byte
|
var dockerCfgJson []byte
|
||||||
if options.Registry != "" {
|
if options.Registry != "" {
|
||||||
dockerCfgJson, err = generateDockerConfigJson(options.Registry, options.Username, options.Password)
|
dockerCfgJson, err = generateDockerConfigJson(options.Registry, options.Username, options.Password)
|
||||||
@ -108,7 +89,7 @@ func Generate(options Options) (*manifestgen.Manifest, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
secret := buildSecret(keypair, hostKey, caFile, certFile, keyFile, dockerCfgJson, options)
|
secret := buildSecret(keypair, hostKey, options.CAFile, options.CertFile, options.KeyFile, dockerCfgJson, options)
|
||||||
b, err := yaml.Marshal(secret)
|
b, err := yaml.Marshal(secret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -120,6 +101,35 @@ func Generate(options Options) (*manifestgen.Manifest, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func LoadKeyPairFromPath(path, password string) (*ssh.KeyPair, error) {
|
||||||
|
if path == "" {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := os.ReadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to open private key file: %w", err)
|
||||||
|
}
|
||||||
|
return LoadKeyPair(b, password)
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadKeyPair(privateKey []byte, password string) (*ssh.KeyPair, error) {
|
||||||
|
var ppk cryptssh.Signer
|
||||||
|
var err error
|
||||||
|
if password != "" {
|
||||||
|
ppk, err = cryptssh.ParsePrivateKeyWithPassphrase(privateKey, []byte(password))
|
||||||
|
} else {
|
||||||
|
ppk, err = cryptssh.ParsePrivateKey(privateKey)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &ssh.KeyPair{
|
||||||
|
PublicKey: cryptssh.MarshalAuthorizedKey(ppk.PublicKey()),
|
||||||
|
PrivateKey: privateKey,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func buildSecret(keypair *ssh.KeyPair, hostKey, caFile, certFile, keyFile, dockerCfg []byte, options Options) (secret corev1.Secret) {
|
func buildSecret(keypair *ssh.KeyPair, hostKey, caFile, certFile, keyFile, dockerCfg []byte, options Options) (secret corev1.Secret) {
|
||||||
secret.TypeMeta = metav1.TypeMeta{
|
secret.TypeMeta = metav1.TypeMeta{
|
||||||
APIVersion: "v1",
|
APIVersion: "v1",
|
||||||
@ -143,16 +153,16 @@ func buildSecret(keypair *ssh.KeyPair, hostKey, caFile, certFile, keyFile, docke
|
|||||||
secret.StringData[PasswordSecretKey] = options.Password
|
secret.StringData[PasswordSecretKey] = options.Password
|
||||||
}
|
}
|
||||||
|
|
||||||
if caFile != nil {
|
if len(caFile) != 0 {
|
||||||
secret.StringData[CAFileSecretKey] = string(caFile)
|
secret.StringData[CAFileSecretKey] = string(caFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
if certFile != nil && keyFile != nil {
|
if len(certFile) != 0 && len(keyFile) != 0 {
|
||||||
secret.StringData[CertFileSecretKey] = string(certFile)
|
secret.StringData[CertFileSecretKey] = string(certFile)
|
||||||
secret.StringData[KeyFileSecretKey] = string(keyFile)
|
secret.StringData[KeyFileSecretKey] = string(keyFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
if keypair != nil && hostKey != nil {
|
if keypair != nil && len(hostKey) != 0 {
|
||||||
secret.StringData[PrivateKeySecretKey] = string(keypair.PrivateKey)
|
secret.StringData[PrivateKeySecretKey] = string(keypair.PrivateKey)
|
||||||
secret.StringData[PublicKeySecretKey] = string(keypair.PublicKey)
|
secret.StringData[PublicKeySecretKey] = string(keypair.PublicKey)
|
||||||
secret.StringData[KnownHostsSecretKey] = string(hostKey)
|
secret.StringData[KnownHostsSecretKey] = string(hostKey)
|
||||||
@ -165,29 +175,6 @@ func buildSecret(keypair *ssh.KeyPair, hostKey, caFile, certFile, keyFile, docke
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadKeyPair(path string, password string) (*ssh.KeyPair, error) {
|
|
||||||
b, err := os.ReadFile(path)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("failed to open private key file: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var ppk cryptssh.Signer
|
|
||||||
if password != "" {
|
|
||||||
ppk, err = cryptssh.ParsePrivateKeyWithPassphrase(b, []byte(password))
|
|
||||||
} else {
|
|
||||||
ppk, err = cryptssh.ParsePrivateKey(b)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &ssh.KeyPair{
|
|
||||||
PublicKey: cryptssh.MarshalAuthorizedKey(ppk.PublicKey()),
|
|
||||||
PrivateKey: b,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func generateKeyPair(options Options) (*ssh.KeyPair, error) {
|
func generateKeyPair(options Options) (*ssh.KeyPair, error) {
|
||||||
var keyGen ssh.KeyPairGenerator
|
var keyGen ssh.KeyPairGenerator
|
||||||
switch options.PrivateKeyAlgorithm {
|
switch options.PrivateKeyAlgorithm {
|
||||||
|
|||||||
@ -48,7 +48,7 @@ func Test_passwordLoadKeyPair(t *testing.T) {
|
|||||||
pk, _ := os.ReadFile(tt.privateKeyPath)
|
pk, _ := os.ReadFile(tt.privateKeyPath)
|
||||||
ppk, _ := os.ReadFile(tt.publicKeyPath)
|
ppk, _ := os.ReadFile(tt.publicKeyPath)
|
||||||
|
|
||||||
got, err := loadKeyPair(tt.privateKeyPath, tt.password)
|
got, err := LoadKeyPair(pk, tt.password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("loadKeyPair() error = %v", err)
|
t.Errorf("loadKeyPair() error = %v", err)
|
||||||
return
|
return
|
||||||
@ -67,24 +67,13 @@ func Test_passwordLoadKeyPair(t *testing.T) {
|
|||||||
func Test_PasswordlessLoadKeyPair(t *testing.T) {
|
func Test_PasswordlessLoadKeyPair(t *testing.T) {
|
||||||
for algo, privateKey := range testdata.PEMBytes {
|
for algo, privateKey := range testdata.PEMBytes {
|
||||||
t.Run(algo, func(t *testing.T) {
|
t.Run(algo, func(t *testing.T) {
|
||||||
f, err := os.CreateTemp("", "test-private-key-")
|
got, err := LoadKeyPair(privateKey, "")
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("unable to create temporary file. err: %s", err)
|
|
||||||
}
|
|
||||||
defer os.Remove(f.Name())
|
|
||||||
|
|
||||||
if _, err = f.Write(privateKey); err != nil {
|
|
||||||
t.Fatalf("unable to write private key to file. err: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
got, err := loadKeyPair(f.Name(), "")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("loadKeyPair() error = %v", err)
|
t.Errorf("loadKeyPair() error = %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
pk, _ := os.ReadFile(f.Name())
|
if !reflect.DeepEqual(got.PrivateKey, privateKey) {
|
||||||
if !reflect.DeepEqual(got.PrivateKey, pk) {
|
|
||||||
t.Errorf("PrivateKey %s != %s", got.PrivateKey, string(privateKey))
|
t.Errorf("PrivateKey %s != %s", got.PrivateKey, string(privateKey))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user