-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add kbs-init scripts to KBS docker image
Signed-off-by: Jiale Zhang <[email protected]>
- Loading branch information
Showing
10 changed files
with
760 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
|
||
|
||
build: | ||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags '-extldflags "-static"' -o kbs-init main.go | ||
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags '-extldflags "-static"' -o kbs-watcher watcher/main.go |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
module gitlab.alibaba-inc.com/cos/coco-charts/dockerfiles/kbs-init | ||
|
||
go 1.17 | ||
|
||
require ( | ||
k8s.io/api v0.28.2 | ||
k8s.io/apimachinery v0.28.2 | ||
k8s.io/client-go v0.28.2 | ||
sigs.k8s.io/controller-runtime v0.16.2 | ||
) | ||
|
||
require ( | ||
github.com/beorn7/perks v1.0.1 // indirect | ||
github.com/cespare/xxhash/v2 v2.2.0 // indirect | ||
github.com/davecgh/go-spew v1.1.1 // indirect | ||
github.com/emicklei/go-restful/v3 v3.9.0 // indirect | ||
github.com/evanphx/json-patch/v5 v5.6.0 // indirect | ||
github.com/fsnotify/fsnotify v1.6.0 // indirect | ||
github.com/go-logr/logr v1.2.4 // indirect | ||
github.com/go-logr/zapr v1.2.4 // indirect | ||
github.com/go-openapi/jsonpointer v0.19.6 // indirect | ||
github.com/go-openapi/jsonreference v0.20.2 // indirect | ||
github.com/go-openapi/swag v0.22.3 // indirect | ||
github.com/gogo/protobuf v1.3.2 // indirect | ||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect | ||
github.com/golang/protobuf v1.5.3 // indirect | ||
github.com/google/gnostic-models v0.6.8 // indirect | ||
github.com/google/go-cmp v0.5.9 // indirect | ||
github.com/google/gofuzz v1.2.0 // indirect | ||
github.com/google/uuid v1.3.0 // indirect | ||
github.com/imdario/mergo v0.3.6 // indirect | ||
github.com/josharian/intern v1.0.0 // indirect | ||
github.com/json-iterator/go v1.1.12 // indirect | ||
github.com/mailru/easyjson v0.7.7 // indirect | ||
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect | ||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | ||
github.com/modern-go/reflect2 v1.0.2 // indirect | ||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect | ||
github.com/pkg/errors v0.9.1 // indirect | ||
github.com/prometheus/client_golang v1.16.0 // indirect | ||
github.com/prometheus/client_model v0.4.0 // indirect | ||
github.com/prometheus/common v0.44.0 // indirect | ||
github.com/prometheus/procfs v0.10.1 // indirect | ||
github.com/spf13/pflag v1.0.5 // indirect | ||
go.uber.org/multierr v1.11.0 // indirect | ||
go.uber.org/zap v1.25.0 // indirect | ||
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect | ||
golang.org/x/net v0.13.0 // indirect | ||
golang.org/x/oauth2 v0.8.0 // indirect | ||
golang.org/x/sys v0.11.0 // indirect | ||
golang.org/x/term v0.10.0 // indirect | ||
golang.org/x/text v0.11.0 // indirect | ||
golang.org/x/time v0.3.0 // indirect | ||
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect | ||
google.golang.org/appengine v1.6.7 // indirect | ||
google.golang.org/protobuf v1.30.0 // indirect | ||
gopkg.in/inf.v0 v0.9.1 // indirect | ||
gopkg.in/yaml.v2 v2.4.0 // indirect | ||
gopkg.in/yaml.v3 v3.0.1 // indirect | ||
k8s.io/apiextensions-apiserver v0.28.0 // indirect | ||
k8s.io/component-base v0.28.1 // indirect | ||
k8s.io/klog/v2 v2.100.1 // indirect | ||
k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect | ||
k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect | ||
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect | ||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect | ||
sigs.k8s.io/yaml v1.3.0 // indirect | ||
) |
Large diffs are not rendered by default.
Oops, something went wrong.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
package main | ||
|
||
import ( | ||
"context" | ||
"crypto/ed25519" | ||
"crypto/rand" | ||
"crypto/x509" | ||
"encoding/pem" | ||
"flag" | ||
"fmt" | ||
"log" | ||
"math/big" | ||
"os" | ||
"os/signal" | ||
"syscall" | ||
"time" | ||
|
||
"k8s.io/apimachinery/pkg/api/errors" | ||
|
||
corev1 "k8s.io/api/core/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/client-go/kubernetes" | ||
ctrl "sigs.k8s.io/controller-runtime" | ||
) | ||
|
||
type DSAKeyFormat struct { | ||
Version int | ||
P, Q, G, Y, X *big.Int | ||
} | ||
|
||
var ( | ||
namespace = "" | ||
secretNameKeys = "" | ||
secretNameAuth = "" | ||
mountPath = "" | ||
mountTimeout = time.Minute * 5 | ||
) | ||
|
||
func init() { | ||
flag.StringVar(&namespace, "namespace", "", "") | ||
flag.StringVar(&secretNameKeys, "secret-name-keys", "kbs-auth-publickey", "") | ||
flag.StringVar(&secretNameAuth, "secret-name-auth", "kbs-auth-keypair", "") | ||
flag.StringVar(&mountPath, "mount-path", "/opt/confidential-containers/kbs/user-keys/public.pub", "") | ||
flag.DurationVar(&mountTimeout, "mount-wait", time.Minute*5, "") | ||
} | ||
|
||
func main() { | ||
flag.Parse() | ||
|
||
if namespace == "" || secretNameKeys == "" || secretNameAuth == "" { | ||
log.Println("both --namespace, --secret-name-keys and --secret-name-auth are required") | ||
os.Exit(1) | ||
} | ||
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM) | ||
defer stop() | ||
|
||
log.Println("start to init client") | ||
client, err := newK8sClient() | ||
if err != nil { | ||
log.Fatalf("init k8s client failed: %+v", err) | ||
} | ||
|
||
log.Println("start to generate ed25519 keys") | ||
pub, priv, err := newEd25519() | ||
if err != nil { | ||
log.Fatalf("generate ed25519 keys failed: %+v", err) | ||
} | ||
|
||
log.Println("start to ensure secrets") | ||
if err := ensureSecrets(ctx, client, pub, priv); err != nil { | ||
log.Fatalf("ensure secretes failed: %+v", err) | ||
} | ||
|
||
log.Printf("start to check mounted file with timeout(%s): %s", mountTimeout, mountPath) | ||
|
||
if err := waitFileMounted(ctx); err != nil { | ||
log.Fatalf("check mounted file (%s) failed: %+v", mountPath, err) | ||
} | ||
} | ||
|
||
func waitFileMounted(ctx context.Context) error { | ||
ctx, cancel := context.WithTimeout(ctx, mountTimeout) | ||
defer cancel() | ||
|
||
ticket := time.NewTicker(time.Second) | ||
defer ticket.Stop() | ||
|
||
var err error | ||
loop: | ||
for { | ||
select { | ||
case <-ctx.Done(): | ||
log.Println("canceled") | ||
return ctx.Err() | ||
case <-ticket.C: | ||
err = checkMountFile() | ||
if err == nil { | ||
log.Println("the file is mounted") | ||
break loop | ||
} | ||
} | ||
} | ||
|
||
return err | ||
} | ||
|
||
func checkMountFile() error { | ||
_, err := os.Stat(mountPath) | ||
return err | ||
} | ||
|
||
func ensureSecrets(ctx context.Context, client kubernetes.Interface, pub, priv []byte) error { | ||
s1 := newSecret(pub, nil, secretNameKeys) | ||
err1 := ensureSecret(ctx, client, s1) | ||
if err1 != nil { | ||
return fmt.Errorf("ensure secret %s failed: %+v", s1.Name, err1) | ||
} | ||
log.Printf("ensured secret %s", s1.Name) | ||
|
||
s2 := newSecret(pub, priv, secretNameAuth) | ||
err2 := ensureSecret(ctx, client, s2) | ||
if err2 != nil { | ||
return fmt.Errorf("ensure secret %s failed: %+v", s2.Name, err2) | ||
} | ||
log.Printf("ensured secret %s", s2.Name) | ||
|
||
return nil | ||
} | ||
|
||
func ensureSecret(ctx context.Context, client kubernetes.Interface, s *corev1.Secret) error { | ||
_, err := client.CoreV1().Secrets(namespace).Create(ctx, s, metav1.CreateOptions{}) | ||
if err != nil { | ||
if errors.IsAlreadyExists(err) { | ||
return nil | ||
} | ||
} | ||
return err | ||
} | ||
|
||
func newSecret(pub, priv []byte, name string) *corev1.Secret { | ||
s := &corev1.Secret{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: name, | ||
Namespace: namespace, | ||
}, | ||
Data: map[string][]byte{ | ||
"public.pub": pub, | ||
}, | ||
} | ||
if len(priv) > 0 { | ||
s.Data["private.key"] = priv | ||
} | ||
|
||
return s | ||
} | ||
|
||
func newEd25519() ([]byte, []byte, error) { | ||
pub, priv, err := ed25519.GenerateKey(rand.Reader) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
return encodePublicKey(pub), encodePrivateKey(priv), nil | ||
} | ||
|
||
func encodePublicKey(key ed25519.PublicKey) []byte { | ||
k, err := x509.MarshalPKIXPublicKey(key) | ||
if err != nil { | ||
return nil | ||
} | ||
b := &pem.Block{Type: "PUBLIC KEY", Bytes: k} | ||
return pem.EncodeToMemory(b) | ||
} | ||
|
||
func encodePrivateKey(key ed25519.PrivateKey) []byte { | ||
k, err := x509.MarshalPKCS8PrivateKey(key) | ||
if err != nil { | ||
return nil | ||
} | ||
b := &pem.Block{Type: "PRIVATE KEY", Bytes: k} | ||
return pem.EncodeToMemory(b) | ||
} | ||
|
||
func newK8sClient() (kubernetes.Interface, error) { | ||
config, err := ctrl.GetConfig() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return kubernetes.NewForConfig(config) | ||
} |
Oops, something went wrong.