From 1eceb788e6970d2d4fb389d2498475bd09d4977c Mon Sep 17 00:00:00 2001 From: Alexander Brandstedt Date: Mon, 21 Aug 2017 17:18:00 +0200 Subject: [PATCH] implementation of adding ssh public key using sshsecret spec --- cmd/kops/create.go | 34 +++++++++++++++++++++++ docs/cli/kops_create.md | 3 ++ docs/secrets.md | 12 ++++++++ pkg/apis/kops/register.go | 5 ++++ pkg/apis/kops/sshsecret.go | 43 +++++++++++++++++++++++++++++ pkg/apis/kops/v1alpha1/register.go | 5 ++++ pkg/apis/kops/v1alpha1/sshsecret.go | 43 +++++++++++++++++++++++++++++ pkg/apis/kops/v1alpha2/register.go | 5 ++++ pkg/apis/kops/v1alpha2/sshsecret.go | 43 +++++++++++++++++++++++++++++ 9 files changed, 193 insertions(+) create mode 100644 pkg/apis/kops/sshsecret.go create mode 100644 pkg/apis/kops/v1alpha1/sshsecret.go create mode 100644 pkg/apis/kops/v1alpha2/sshsecret.go diff --git a/cmd/kops/create.go b/cmd/kops/create.go index 75eb15147e..85d025ffd1 100644 --- a/cmd/kops/create.go +++ b/cmd/kops/create.go @@ -27,6 +27,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/kops/cmd/kops/util" kopsapi "k8s.io/kops/pkg/apis/kops" + "k8s.io/kops/pkg/apis/kops/registry" "k8s.io/kops/pkg/apis/kops/v1alpha1" "k8s.io/kops/upup/pkg/fi/cloudup" "k8s.io/kops/util/pkg/vfs" @@ -54,6 +55,9 @@ var ( # Create a cluster from the configuration specification in a YAML file kops create -f my-cluster.yaml + # Create secret from secret spec file + kops create -f secret.yaml + # Create a cluster in AWS kops create cluster --name=kubernetes-cluster.example.com \ --state=s3://kops-state-1234 --zones=eu-west-1a \ @@ -190,6 +194,36 @@ func RunCreate(f *util.Factory, out io.Writer, c *CreateOptions) error { fmt.Fprintf(&sb, "Created instancegroup/%s\n", v.ObjectMeta.Name) } + case *kopsapi.SSHSecret: + clusterName = v.ObjectMeta.Labels[kopsapi.LabelClusterName] + if clusterName == "" { + return fmt.Errorf("must specify %q label with cluster name to create instanceGroup", kopsapi.LabelClusterName) + } + if v.Spec.Username == "" { + return fmt.Errorf("spec.username is required") + } + if v.Spec.SshPublicKey == "" { + return fmt.Errorf("spec.sshPublicKey is required") + } + + cluster, err := clientset.GetCluster(clusterName) + if err != nil { + return err + } + + keyStore, err := registry.KeyStore(cluster) + if err != nil { + return err + } + + sshKeyArr := []byte(v.Spec.SshPublicKey) + err = keyStore.AddSSHPublicKey(v.Spec.Username, sshKeyArr) + if err != nil { + return err + } else { + fmt.Fprintf(&sb, "Added SSHSecret ssh key\n") + } + default: glog.V(2).Infof("Type of object was %T", v) return fmt.Errorf("Unhandled kind %q in %s", gvk, f) diff --git a/docs/cli/kops_create.md b/docs/cli/kops_create.md index c900770382..84cc1f7434 100644 --- a/docs/cli/kops_create.md +++ b/docs/cli/kops_create.md @@ -27,6 +27,9 @@ kops create -f FILENAME # Create a cluster from the configuration specification in a YAML file kops create -f my-cluster.yaml + # Create secret from secret spec file + kops create -f secret.yaml + # Create a cluster in AWS kops create cluster --name=kubernetes-cluster.example.com \ --state=s3://kops-state-1234 --zones=eu-west-1a \ diff --git a/docs/secrets.md b/docs/secrets.md index 8c6755492e..df58bf69d4 100644 --- a/docs/secrets.md +++ b/docs/secrets.md @@ -24,3 +24,15 @@ The ID form can be used when there are multiple matching keys. example: `kops delete secret sshpublickey admin` + +### adding secret from spec file +```bash +apiVersion: kops/v1alpha2 +kind: SSHSecret +metadata: + labels: + kops.k8s.io/cluster: dev.k8s.example.com +spec: + username: "admin" + sshPublicKey: "ssh-rsa AAAAB3NzaC1 dev@devbox" +``` diff --git a/pkg/apis/kops/register.go b/pkg/apis/kops/register.go index 43ce1a5e3e..cf53435237 100644 --- a/pkg/apis/kops/register.go +++ b/pkg/apis/kops/register.go @@ -65,6 +65,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { &InstanceGroupList{}, &Federation{}, &FederationList{}, + &SSHSecret{}, + &SSHSecretList{}, ) //metav1.AddToGroupVersion(scheme, SchemeGroupVersion) return nil @@ -79,3 +81,6 @@ func (obj *InstanceGroup) GetObjectKind() schema.ObjectKind { func (obj *Federation) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta } +func (obj *SSHSecret) GetObjectKind() schema.ObjectKind { + return &obj.TypeMeta +} \ No newline at end of file diff --git a/pkg/apis/kops/sshsecret.go b/pkg/apis/kops/sshsecret.go new file mode 100644 index 0000000000..44fa9ea03c --- /dev/null +++ b/pkg/apis/kops/sshsecret.go @@ -0,0 +1,43 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package kops + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient=true + +// SSHSecret represent a set of kops secrets +type SSHSecret struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec SSHSecretSpec `json:"spec,omitempty"` +} + +type SSHSecretSpec struct { + SshPublicKey string `json:"sshPublicKey,omitempty"` + Username string `json:"username,omitempty"` +} + +type SSHSecretList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + + Items []SSHSecret `json:"items"` +} diff --git a/pkg/apis/kops/v1alpha1/register.go b/pkg/apis/kops/v1alpha1/register.go index a5deefefde..8454e7449e 100644 --- a/pkg/apis/kops/v1alpha1/register.go +++ b/pkg/apis/kops/v1alpha1/register.go @@ -52,6 +52,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { &InstanceGroupList{}, &Federation{}, &FederationList{}, + &SSHSecret{}, + &SSHSecretList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) @@ -68,6 +70,9 @@ func (obj *InstanceGroup) GetObjectKind() schema.ObjectKind { func (obj *Federation) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta } +func (obj *SSHSecret) GetObjectKind() schema.ObjectKind { + return &obj.TypeMeta +} func addConversionFuncs(scheme *runtime.Scheme) error { // Add non-generated conversion functions diff --git a/pkg/apis/kops/v1alpha1/sshsecret.go b/pkg/apis/kops/v1alpha1/sshsecret.go new file mode 100644 index 0000000000..22266196f4 --- /dev/null +++ b/pkg/apis/kops/v1alpha1/sshsecret.go @@ -0,0 +1,43 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient=true + +// SSHSecret represent a set of kops secrets +type SSHSecret struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec SSHSecretSpec `json:"spec,omitempty"` +} + +type SSHSecretSpec struct { + SshPublicKey string `json:"sshPublicKey,omitempty"` + Username string `json:"username,omitempty"` +} + +type SSHSecretList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + + Items []SSHSecret `json:"items"` +} diff --git a/pkg/apis/kops/v1alpha2/register.go b/pkg/apis/kops/v1alpha2/register.go index b09059bb23..b86adbbb55 100644 --- a/pkg/apis/kops/v1alpha2/register.go +++ b/pkg/apis/kops/v1alpha2/register.go @@ -53,6 +53,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { &InstanceGroupList{}, &Federation{}, &FederationList{}, + &SSHSecret{}, + &SSHSecretList{}, ) metav1.AddToGroupVersion(scheme, SchemeGroupVersion) @@ -69,6 +71,9 @@ func (obj *InstanceGroup) GetObjectKind() schema.ObjectKind { func (obj *Federation) GetObjectKind() schema.ObjectKind { return &obj.TypeMeta } +func (obj *SSHSecret) GetObjectKind() schema.ObjectKind { + return &obj.TypeMeta +} func addConversionFuncs(scheme *runtime.Scheme) error { return nil diff --git a/pkg/apis/kops/v1alpha2/sshsecret.go b/pkg/apis/kops/v1alpha2/sshsecret.go new file mode 100644 index 0000000000..5653716afe --- /dev/null +++ b/pkg/apis/kops/v1alpha2/sshsecret.go @@ -0,0 +1,43 @@ +/* +Copyright 2016 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha2 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient=true + +// SSHSecret represent a set of kops secrets +type SSHSecret struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec SSHSecretSpec `json:"spec,omitempty"` +} + +type SSHSecretSpec struct { + SshPublicKey string `json:"sshPublicKey,omitempty"` + Username string `json:"username,omitempty"` +} + +type SSHSecretList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + + Items []SSHSecret `json:"items"` +}