Add public repos and semver support to create cmd

pull/1/head
stefanprodan 5 years ago
parent 1371b4d4d3
commit 9cec671f6c

@ -4,9 +4,12 @@ import (
"bufio"
"bytes"
"fmt"
"io"
"io/ioutil"
"net/url"
"os"
"os/exec"
"strings"
"text/template"
"github.com/manifoldco/promptui"
@ -18,19 +21,29 @@ var createSourceCmd = &cobra.Command{
Short: "Create source resource",
Long: `
The create source command generates a source.fluxcd.io resource and waits for it to sync.
If a Git repository is specified, it will create a SSH deploy key.`,
Example: ` create source podinfo --git-url ssh://git@github.com/stefanprodan/podinfo-deploy`,
RunE: createSourceCmdRun,
For Git over SSH, host and SSH keys are automatically generated.`,
Example: ` # Create a gitrepository.source.fluxcd.io for a public repository
create source podinfo --git-url https://github.com/stefanprodan/podinfo-deploy --git-branch master
# Create a gitrepository.source.fluxcd.io that syncs tags based on a semver range
create source podinfo --git-url https://github.com/stefanprodan/podinfo-deploy --git-semver=">=0.0.1-rc.1 <0.1.0"
# Create a gitrepository.source.fluxcd.io with SSH authentication
create source podinfo --git-url ssh://git@github.com/stefanprodan/podinfo-deploy
`,
RunE: createSourceCmdRun,
}
var (
sourceGitURL string
sourceGitBranch string
sourceGitSemver string
)
func init() {
createSourceCmd.Flags().StringVar(&sourceGitURL, "git-url", "", "git SSH address, in the format ssh://git@host/org/repository")
createSourceCmd.Flags().StringVar(&sourceGitURL, "git-url", "", "git address, e.g. ssh://git@host/org/repository")
createSourceCmd.Flags().StringVar(&sourceGitBranch, "git-branch", "master", "git branch")
createSourceCmd.Flags().StringVar(&sourceGitSemver, "git-semver", "", "git tag semver range")
createCmd.AddCommand(createSourceCmd)
}
@ -56,44 +69,11 @@ func createSourceCmdRun(cmd *cobra.Command, args []string) error {
return fmt.Errorf("git URL parse failed: %w", err)
}
fmt.Println(``, "generating host key for", u.Host)
keyscan := fmt.Sprintf("ssh-keyscan %s > %s/known_hosts", u.Host, tmpDir)
if output, err := execCommand(keyscan); err != nil {
return fmt.Errorf("ssh-keyscan failed: %s", output)
}
fmt.Println(``, "generating deploy key")
keygen := fmt.Sprintf("ssh-keygen -b 2048 -t rsa -f %s/identity -q -N \"\"", tmpDir)
if output, err := execCommand(keygen); err != nil {
return fmt.Errorf("ssh-keygen failed: %s", output)
}
deployKey, err := execCommand(fmt.Sprintf("cat %s/identity.pub", tmpDir))
if err != nil {
return fmt.Errorf("unable to read identity.pub: %w", err)
}
fmt.Print(deployKey)
prompt := promptui.Prompt{
Label: "Have you added the deploy key to your repository",
IsConfirm: true,
}
if _, err := prompt.Run(); err != nil {
fmt.Println(``, "aborting")
return nil
}
fmt.Println(``, "saving deploy key")
files := fmt.Sprintf("--from-file=%s/identity --from-file=%s/identity.pub --from-file=%s/known_hosts",
tmpDir, tmpDir, tmpDir)
secret := fmt.Sprintf("kubectl -n %s create secret generic %s %s --dry-run=client -oyaml | kubectl apply -f-",
namespace, name, files)
if output, err := execCommand(secret); err != nil {
return fmt.Errorf("kubectl create secret failed: %s", output)
} else {
fmt.Print(output)
isSSH := strings.HasPrefix(sourceGitURL, "ssh")
if isSSH {
if err := generateSSH(name, u.Host, tmpDir); err != nil {
return err
}
}
fmt.Println(``, "generating source resource")
@ -106,13 +86,19 @@ func createSourceCmdRun(cmd *cobra.Command, args []string) error {
source := struct {
Name string
Namespace string
GitURL string
URL string
Branch string
Semver string
Interval string
IsSSH bool
}{
Name: name,
Namespace: namespace,
GitURL: sourceGitURL,
URL: sourceGitURL,
Branch: sourceGitBranch,
Semver: sourceGitSemver,
Interval: interval,
IsSSH: isSSH,
}
var data bytes.Buffer
@ -123,11 +109,19 @@ func createSourceCmdRun(cmd *cobra.Command, args []string) error {
if err := writer.Flush(); err != nil {
return fmt.Errorf("source flush failed: %w", err)
}
fmt.Print(data.String())
if output, err := execCommand(fmt.Sprintf("echo '%s' | kubectl apply -f-", data.String())); err != nil {
return fmt.Errorf("kubectl create source failed: %s", output)
} else {
fmt.Print(output)
command := fmt.Sprintf("echo '%s' | kubectl apply -f-", data.String())
c := exec.Command("/bin/sh", "-c", command)
var stdoutBuf, stderrBuf bytes.Buffer
c.Stdout = io.MultiWriter(os.Stdout, &stdoutBuf)
c.Stderr = io.MultiWriter(os.Stderr, &stderrBuf)
err = c.Run()
if err != nil {
fmt.Println(``, "source apply failed")
os.Exit(1)
}
fmt.Println(``, "waiting for source sync")
@ -142,6 +136,49 @@ func createSourceCmdRun(cmd *cobra.Command, args []string) error {
return nil
}
func generateSSH(name, host, tmpDir string) error {
fmt.Println(``, "generating host key for", host)
keyscan := fmt.Sprintf("ssh-keyscan %s > %s/known_hosts", host, tmpDir)
if output, err := execCommand(keyscan); err != nil {
return fmt.Errorf("ssh-keyscan failed: %s", output)
}
fmt.Println(``, "generating deploy key")
keygen := fmt.Sprintf("ssh-keygen -b 2048 -t rsa -f %s/identity -q -N \"\"", tmpDir)
if output, err := execCommand(keygen); err != nil {
return fmt.Errorf("ssh-keygen failed: %s", output)
}
deployKey, err := execCommand(fmt.Sprintf("cat %s/identity.pub", tmpDir))
if err != nil {
return fmt.Errorf("unable to read identity.pub: %w", err)
}
fmt.Print(deployKey)
prompt := promptui.Prompt{
Label: "Have you added the deploy key to your repository",
IsConfirm: true,
}
if _, err := prompt.Run(); err != nil {
fmt.Println(``, "aborting")
os.Exit(1)
}
fmt.Println(``, "saving deploy key")
files := fmt.Sprintf("--from-file=%s/identity --from-file=%s/identity.pub --from-file=%s/known_hosts",
tmpDir, tmpDir, tmpDir)
secret := fmt.Sprintf("kubectl -n %s create secret generic %s %s --dry-run=client -oyaml | kubectl apply -f-",
namespace, name, files)
if output, err := execCommand(secret); err != nil {
return fmt.Errorf("kubectl create secret failed: %s", output)
} else {
fmt.Print(output)
}
return nil
}
var gitSource = `---
apiVersion: source.fluxcd.io/v1alpha1
kind: GitRepository
@ -150,7 +187,15 @@ metadata:
namespace: {{.Namespace}}
spec:
interval: {{.Interval}}
url: {{.GitURL}}
url: {{.URL}}
ref:
{{- if .Semver }}
semver: "{{.Semver}}"
{{- else }}
branch: {{.Branch}}
{{- end }}
{{- if .IsSSH }}
secretRef:
name: {{.Name}}
{{- end }}
`

@ -2,24 +2,24 @@ package main
import (
"fmt"
"log"
"os"
"os/exec"
"path/filepath"
"strings"
"github.com/spf13/cobra"
"k8s.io/client-go/kubernetes"
_ "k8s.io/client-go/plugin/pkg/client/auth"
"k8s.io/client-go/tools/clientcmd"
"log"
"os"
"os/exec"
"path/filepath"
)
var VERSION = "0.0.1"
var rootCmd = &cobra.Command{
Use: "tk",
Short: "Kubernetes CD assembler",
Version: VERSION,
Use: "tk",
Short: "Kubernetes CD assembler",
Version: VERSION,
SilenceUsage: true,
SilenceErrors: true,
}
var (
@ -41,11 +41,8 @@ func init() {
func main() {
log.SetFlags(0)
rootCmd.SetArgs(os.Args[1:])
if err := rootCmd.Execute(); err != nil {
e := err.Error()
fmt.Println(strings.ToUpper(e[:1]) + e[1:])
fmt.Println(err)
os.Exit(1)
}
}

Loading…
Cancel
Save