Skip to content

Commit

Permalink
cmd: Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
smarterclayton committed Dec 25, 2020
0 parents commit 01ff330
Show file tree
Hide file tree
Showing 7 changed files with 1,295 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.kcp
kcp
11 changes: 11 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
all: build
.PHONY: all

build:
go build -ldflags "-X k8s.io/client-go/pkg/version.gitVersion=$$(git describe --abbrev=8 --dirty --always)" -o bin/kcp ./cmd/kcp
.PHONY: build

vendor:
go mod tidy
go mod vendor
.PHONY: vendor
2 changes: 2 additions & 0 deletions bin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
173 changes: 173 additions & 0 deletions cmd/kcp/kcp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
package main

import (
"context"
"flag"
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
"unicode"

"github.com/MakeNowJust/heredoc"
"github.com/muesli/reflow/wordwrap"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
terminal "github.com/wayneashleyberry/terminal-dimensions"
"go.etcd.io/etcd/clientv3"

"github.com/openshift/kcp/pkg/etcd"

"k8s.io/apiserver/pkg/storage/storagebackend"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"k8s.io/kubernetes/pkg/controlplane"
"k8s.io/kubernetes/pkg/controlplane/options"
)

var reEmptyLine = regexp.MustCompile(`(?m)([\w[:punct:]])[ ]*\n([\w[:punct:]])`)

func Helpdoc(s string) string {
s = heredoc.Doc(s)
s = reEmptyLine.ReplaceAllString(s, "$1 $2")
return s
}

func main() {
cobra.AddTemplateFunc("trimTrailingWhitespaces", func(s string) string {
w, err := terminal.Width()
if err != nil {
w = 80
}
return strings.TrimRightFunc(wordwrap.String(s, int(w)), unicode.IsSpace)
})

cmd := &cobra.Command{
Use: "kcp",
Short: "Kube for Control Plane (KCP)",
Long: Helpdoc(`
KCP is the easiest way to manage Kubernetes applications against one or
more clusters, by giving you a personal control plane that schedules your
workloads onto one or many clusters, and making it simple to pick up and
move. Advanced use cases including spreading your apps across clusters for
resiliency, scheduling batch workloads onto clusters with free capacity,
and enabling collaboration for individual teams without having access to
the underlying clusters.
To get started, launch a new cluster with 'kcp start', which will
initialize your personal control plane and write an admin kubeconfig file
to disk.
`),
SilenceUsage: true,
SilenceErrors: true,
}
startCmd := &cobra.Command{
Use: "start",
Short: "Start the control plane process",
Long: Helpdoc(`
Start the control plane process
The server process listens on port 6443 and will act like a Kubernetes
API server. It will initialize any necessary data to the provided start
location or as a '.kcp' directory in the current directory. An admin
kubeconfig file will be generated at initialization time that may be
used to access the control plane.
`),
RunE: func(cmd *cobra.Command, args []string) error {
//flag.CommandLine.Lookup("v").Value.Set("9")

dir := filepath.Join(".", ".kcp")
if fi, err := os.Stat(dir); err != nil {
if !os.IsNotExist(err) {
return err
}
if err := os.Mkdir(dir, 0755); err != nil {
return err
}
} else {
if !fi.IsDir() {
return fmt.Errorf("%q is a file, please delete or select another location", dir)
}
}
s := &etcd.Server{
Dir: filepath.Join(dir, "data"),
}
ctx := context.TODO()

return s.Run(func(cfg etcd.ClientInfo) error {
c, err := clientv3.New(clientv3.Config{
Endpoints: cfg.Endpoints,
TLS: cfg.TLS,
})
if err != nil {
return err
}
defer c.Close()
r, err := c.Cluster.MemberList(context.Background())
if err != nil {
return err
}
for _, member := range r.Members {
fmt.Fprintf(os.Stderr, "Connected to etcd %d %s\n", member.GetID(), member.GetName())
}

serverOptions := options.NewServerRunOptions()
serverOptions.SecureServing.ServerCert.CertDirectory = s.Dir
serverOptions.InsecureServing = nil
serverOptions.Etcd.StorageConfig.Transport = storagebackend.TransportConfig{
ServerList: cfg.Endpoints,
CertFile: cfg.CertFile,
KeyFile: cfg.KeyFile,
TrustedCAFile: cfg.TrustedCAFile,
}
cpOptions, err := controlplane.Complete(serverOptions)
if err != nil {
return err
}

server, err := controlplane.CreateServerChain(cpOptions, ctx.Done())
if err != nil {
return err
}

prepared := server.PrepareRun()

var clientConfig clientcmdapi.Config
clientConfig.AuthInfos = map[string]*clientcmdapi.AuthInfo{
"loopback": {Token: prepared.LoopbackClientConfig.BearerToken},
}
clientConfig.Clusters = map[string]*clientcmdapi.Cluster{
// admin is the virtual cluster running by default
"admin": {
Server: prepared.LoopbackClientConfig.Host,
CertificateAuthorityData: prepared.LoopbackClientConfig.CAData,
TLSServerName: prepared.LoopbackClientConfig.TLSClientConfig.ServerName,
},
// user is a virtual cluster that is lazily instantiated
"user": {
Server: prepared.LoopbackClientConfig.Host + "/clusters/user",
CertificateAuthorityData: prepared.LoopbackClientConfig.CAData,
TLSServerName: prepared.LoopbackClientConfig.TLSClientConfig.ServerName,
},
}
clientConfig.Contexts = map[string]*clientcmdapi.Context{
"admin": {Cluster: "admin", AuthInfo: "loopback"},
"user": {Cluster: "user", AuthInfo: "loopback"},
}
clientConfig.CurrentContext = "user"
if err := clientcmd.WriteToFile(clientConfig, filepath.Join(s.Dir, "admin.kubeconfig")); err != nil {
return err
}

return prepared.Run(ctx.Done())
})
},
}
startCmd.Flags().AddFlag(pflag.PFlagFromGoFlag(flag.CommandLine.Lookup("v")))
cmd.AddCommand(startCmd)

if err := cmd.Execute(); err != nil {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
}
}
41 changes: 41 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
module github.com/openshift/kcp

go 1.15

require (
github.com/MakeNowJust/heredoc v1.0.0
github.com/muesli/reflow v0.1.0
github.com/spf13/cobra v1.0.0
github.com/spf13/pflag v1.0.5
github.com/wayneashleyberry/terminal-dimensions v1.0.0
go.etcd.io/etcd v0.5.0-alpha.5.0.20200625115826-4488595e0534
k8s.io/apiserver v0.0.0
k8s.io/client-go v0.0.0
k8s.io/klog v1.0.0
k8s.io/kubernetes v0.0.0-00010101000000-000000000000
)

replace (
k8s.io/api => ../../../k8s.io/kubernetes/staging/src/k8s.io/api
k8s.io/apiextensions-apiserver => ../../../k8s.io/kubernetes/staging/src/k8s.io/apiextensions-apiserver
k8s.io/apimachinery => ../../../k8s.io/kubernetes/staging/src/k8s.io/apimachinery
k8s.io/apiserver => ../../../k8s.io/kubernetes/staging/src/k8s.io/apiserver
k8s.io/cli-runtime => ../../../k8s.io/kubernetes/staging/src/k8s.io/cli-runtime
k8s.io/client-go => ../../../k8s.io/kubernetes/staging/src/k8s.io/client-go
k8s.io/cloud-provider => ../../../k8s.io/kubernetes/staging/src/k8s.io/cloud-provider
k8s.io/cluster-bootstrap => ../../../k8s.io/kubernetes/staging/src/k8s.io/cluster-bootstrap
k8s.io/code-generator => ../../../k8s.io/kubernetes/staging/src/k8s.io/code-generator
k8s.io/component-base => ../../../k8s.io/kubernetes/staging/src/k8s.io/component-base
k8s.io/cri-api => ../../../k8s.io/kubernetes/staging/src/k8s.io/cri-api
k8s.io/csi-translation-lib => ../../../k8s.io/kubernetes/staging/src/k8s.io/csi-translation-lib
k8s.io/kube-aggregator => ../../../k8s.io/kubernetes/staging/src/k8s.io/kube-aggregator
k8s.io/kube-controller-manager => ../../../k8s.io/kubernetes/staging/src/k8s.io/kube-controller-manager
k8s.io/kube-proxy => ../../../k8s.io/kubernetes/staging/src/k8s.io/kube-proxy
k8s.io/kube-scheduler => ../../../k8s.io/kubernetes/staging/src/k8s.io/kube-scheduler
k8s.io/kubectl => ../../../k8s.io/kubernetes/staging/src/k8s.io/kubectl
k8s.io/kubelet => ../../../k8s.io/kubernetes/staging/src/k8s.io/kubelet
k8s.io/kubernetes => ../../../k8s.io/kubernetes
k8s.io/legacy-cloud-providers => ../../../k8s.io/kubernetes/staging/src/k8s.io/legacy-cloud-providers
k8s.io/metrics => ../../../k8s.io/kubernetes/staging/src/k8s.io/metrics
k8s.io/sample-apiserver => ../../../k8s.io/kubernetes/staging/src/k8s.io/sample-apiserver
)
Loading

0 comments on commit 01ff330

Please sign in to comment.