-
Notifications
You must be signed in to change notification settings - Fork 553
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add -k8s flag to generate-key-pair (#345)
* Add -k8s flag to generate-key-pair This command will: 1. generate the key-pair in memory 2. prompt the user for a password 3. store cosign.pub, cosign.key and cosign.password as a Kubernetes secret 4. store cosign.pub to disk Signed-off-by: Priya Wadhwa <[email protected]> * Add integration test Signed-off-by: Priya Wadhwa <[email protected]> * make password private, expose via function Signed-off-by: Priya Wadhwa <[email protected]>
- Loading branch information
priyawadhwa
authored
Jun 2, 2021
1 parent
620c41d
commit 8b0bcec
Showing
8 changed files
with
916 additions
and
10 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,6 +47,10 @@ jobs: | |
run: | | ||
curl -L https://github.com/google/ko/releases/download/v0.8.1/ko_0.8.1_Linux_x86_64.tar.gz | tar xzf - ko && \ | ||
chmod +x ./ko && sudo mv ko /usr/local/bin/ | ||
- name: setup kind cluster | ||
run: | | ||
go install sigs.k8s.io/[email protected] | ||
kind create cluster | ||
# Required for `make cosign-pivkey` | ||
# - name: deps | ||
# run: sudo apt-get update && sudo apt-get install -yq libpcsclite-dev | ||
|
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
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,86 @@ | ||
// Copyright 2021 The Sigstore 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 kubernetes | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"io/ioutil" | ||
"os" | ||
"strings" | ||
|
||
kubernetesclient "github.com/GoogleContainerTools/skaffold/pkg/skaffold/kubernetes/client" | ||
"github.com/pkg/errors" | ||
"github.com/sigstore/cosign/pkg/cosign" | ||
v1 "k8s.io/api/core/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
) | ||
|
||
func KeyPairSecret(k8sRef string, pf cosign.PassFunc) error { | ||
namespace, name, err := parseRef(k8sRef) | ||
if err != nil { | ||
return err | ||
} | ||
// now, generate the key in memory | ||
keys, err := cosign.GenerateKeyPair(pf) | ||
if err != nil { | ||
return errors.Wrap(err, "generating key pair") | ||
} | ||
|
||
ctx := context.TODO() | ||
// create the client | ||
client, err := kubernetesclient.Client() | ||
if err != nil { | ||
return errors.Wrap(err, "new for config") | ||
} | ||
s, err := client.CoreV1().Secrets(namespace).Create(ctx, secret(keys, namespace, name), metav1.CreateOptions{}) | ||
if err != nil { | ||
return errors.Wrapf(err, "creating secret %s in ns %s", name, namespace) | ||
} | ||
|
||
fmt.Fprintf(os.Stderr, "Successfully created secret %s in namespace %s\n", s.Name, s.Namespace) | ||
if err := ioutil.WriteFile("cosign.pub", keys.PublicBytes, 0600); err != nil { | ||
return err | ||
} | ||
fmt.Fprintln(os.Stderr, "Public key written to cosign.pub") | ||
return nil | ||
} | ||
|
||
// creates a secret with the following data: | ||
// * cosign.key | ||
// * cosign.pub | ||
// * cosign.password | ||
func secret(keys *cosign.Keys, namespace, name string) *v1.Secret { | ||
return &v1.Secret{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: name, | ||
Namespace: namespace, | ||
}, | ||
Data: map[string][]byte{ | ||
"cosign.key": keys.PrivateBytes, | ||
"cosign.pub": keys.PublicBytes, | ||
"cosign.password": keys.Password(), | ||
}, | ||
} | ||
} | ||
|
||
// the reference should be formatted as <namespace>/<secret name> | ||
func parseRef(k8sRef string) (string, string, error) { | ||
s := strings.Split(k8sRef, "/") | ||
if len(s) != 2 { | ||
return "", "", errors.New("please format the k8s secret reference as <namespace>/<secret name>") | ||
} | ||
return s[0], s[1], nil | ||
} |
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,90 @@ | ||
// Copyright 2021 The Sigstore 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 kubernetes | ||
|
||
import ( | ||
"reflect" | ||
"testing" | ||
|
||
"github.com/sigstore/cosign/pkg/cosign" | ||
v1 "k8s.io/api/core/v1" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
) | ||
|
||
func TestSecret(t *testing.T) { | ||
keys := &cosign.Keys{ | ||
PrivateBytes: []byte("private"), | ||
PublicBytes: []byte("public"), | ||
} | ||
name := "secret" | ||
namespace := "default" | ||
expect := &v1.Secret{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: "secret", | ||
Namespace: "default", | ||
}, | ||
Data: map[string][]byte{ | ||
"cosign.key": []byte("private"), | ||
"cosign.pub": []byte("public"), | ||
"cosign.password": nil, | ||
}, | ||
} | ||
actual := secret(keys, namespace, name) | ||
if !reflect.DeepEqual(actual, expect) { | ||
t.Errorf("secret: %v, want %v", expect, actual) | ||
} | ||
} | ||
|
||
func TestParseRef(t *testing.T) { | ||
tests := []struct { | ||
desc string | ||
ref string | ||
name string | ||
namespace string | ||
shouldErr bool | ||
}{ | ||
{ | ||
desc: "valid", | ||
ref: "default/cosign-secret", | ||
name: "cosign-secret", | ||
namespace: "default", | ||
}, { | ||
desc: "invalid, 1 field", | ||
ref: "something", | ||
shouldErr: true, | ||
}, { | ||
desc: "invalid, more than 2 fields", | ||
ref: "yet/another/arg", | ||
shouldErr: true, | ||
}, | ||
} | ||
for _, test := range tests { | ||
t.Run(test.desc, func(t *testing.T) { | ||
ns, name, err := parseRef(test.ref) | ||
if (err == nil) == test.shouldErr { | ||
t.Fatal("unexpected error") | ||
} | ||
if test.shouldErr { | ||
return | ||
} | ||
if name != test.name { | ||
t.Fatalf("unexpected name: got %v expected %v", name, test.name) | ||
} | ||
if ns != test.namespace { | ||
t.Fatalf("unexpected name: got %v expected %v", ns, test.namespace) | ||
} | ||
}) | ||
} | ||
} |
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