Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #377 from adisky/barbican-kms-final
Implement Barbican as KMS provider for kubernetes
- Loading branch information
Showing
13 changed files
with
585 additions
and
5 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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,7 @@ | ||
FROM alpine:3.7 | ||
LABEL maintainers="Kubernetes Authors" | ||
LABEL description="Barbican KMS Plugin" | ||
|
||
ADD barbican-kms-plugin /bin/ | ||
|
||
CMD ["sh", "-c", "/bin/barbican-kms-plugin --socketpath ${socketpath} --cloud-config ${cloudconfig}"] |
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,67 @@ | ||
/* | ||
Copyright 2017 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 main | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
"os" | ||
"os/signal" | ||
|
||
"github.com/spf13/cobra" | ||
"golang.org/x/sys/unix" | ||
"k8s.io/cloud-provider-openstack/pkg/kms/server" | ||
) | ||
|
||
var ( | ||
socketpath string | ||
cloudconfig string | ||
) | ||
|
||
func init() { | ||
flag.Set("logtostderr", "true") | ||
} | ||
|
||
func main() { | ||
flag.CommandLine.Parse([]string{}) | ||
|
||
cmd := &cobra.Command{ | ||
Use: "barbican-kms-plugin", | ||
Short: "Barbican KMS plugin for kubernetes", | ||
RunE: func(cmd *cobra.Command, args []string) error { | ||
sigchan := make(chan os.Signal, 1) | ||
signal.Notify(sigchan, unix.SIGTERM, unix.SIGINT) | ||
err := server.Run(cloudconfig, socketpath, sigchan) | ||
return err | ||
}, | ||
} | ||
|
||
cmd.Flags().AddGoFlagSet(flag.CommandLine) | ||
|
||
cmd.PersistentFlags().StringVar(&socketpath, "socketpath", "", "Barbican KMS Plugin unix socket endpoint") | ||
cmd.MarkPersistentFlagRequired("socketpath") | ||
|
||
cmd.PersistentFlags().StringVar(&cloudconfig, "cloud-config", "", "Barbican KMS Plugin cloud config") | ||
cmd.MarkPersistentFlagRequired("cloud-config") | ||
|
||
if err := cmd.Execute(); err != nil { | ||
fmt.Fprintf(os.Stderr, "%s", err.Error()) | ||
os.Exit(1) | ||
} | ||
|
||
os.Exit(0) | ||
} |
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,11 @@ | ||
kind: EncryptionConfig | ||
apiVersion: v1 | ||
resources: | ||
- resources: | ||
- secrets | ||
providers: | ||
- kms: | ||
name : barbican | ||
endpoint: unix:///var/lib/kms/kms.sock | ||
cachesize: 20 | ||
- identity: {} |
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,24 @@ | ||
apiVersion: v1 | ||
kind: Pod | ||
metadata: | ||
name: barbican-kms | ||
spec: | ||
containers: | ||
- name: barbican-kms | ||
image: docker.io/k8scloudprovider/barbican-kms-plugin:latest | ||
args: | ||
- "--socketpath=/kms/kms.sock" | ||
- "--cloud-config=/etc/kubernetes/cloud-config" | ||
volumeMounts: | ||
- name: cloud-config | ||
mountPath: /etc/kubernetes/ | ||
- name: socket-dir | ||
mountPath: /kms/ | ||
volumes: | ||
- name: config | ||
hostPath: | ||
path: /etc/kubernetes | ||
- name: socket-dir | ||
hostPath: | ||
path: /var/lib/kms/ | ||
type: DirectoryOrCreate |
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,95 @@ | ||
package barbican | ||
|
||
import ( | ||
"github.com/golang/glog" | ||
"github.com/gophercloud/gophercloud" | ||
"github.com/gophercloud/gophercloud/openstack" | ||
"github.com/gophercloud/gophercloud/openstack/keymanager/v1/secrets" | ||
) | ||
|
||
type BarbicanService interface { | ||
GetSecret(cfg Config) ([]byte, error) | ||
} | ||
|
||
type KMSOpts struct { | ||
KeyID string `gcfg:"key-id"` | ||
} | ||
|
||
//Config to read config options | ||
type Config struct { | ||
Global struct { | ||
AuthURL string `gcfg:"auth-url"` | ||
Username string | ||
UserID string `gcfg:"user-id"` | ||
Password string | ||
TenantID string `gcfg:"tenant-id"` | ||
TenantName string `gcfg:"tenant-name"` | ||
DomainID string `gcfg:"domain-id"` | ||
DomainName string `gcfg:"domain-name"` | ||
Region string | ||
} | ||
KeyManager KMSOpts | ||
} | ||
|
||
// Barbican is gophercloud service client | ||
type Barbican struct { | ||
} | ||
|
||
func (cfg Config) toAuthOptions() gophercloud.AuthOptions { | ||
return gophercloud.AuthOptions{ | ||
IdentityEndpoint: cfg.Global.AuthURL, | ||
Username: cfg.Global.Username, | ||
UserID: cfg.Global.UserID, | ||
Password: cfg.Global.Password, | ||
TenantID: cfg.Global.TenantID, | ||
TenantName: cfg.Global.TenantName, | ||
DomainID: cfg.Global.DomainID, | ||
DomainName: cfg.Global.DomainName, | ||
|
||
// Persistent service, so we need to be able to renew tokens. | ||
AllowReauth: true, | ||
} | ||
} | ||
|
||
// NewBarbicanClient creates new BarbicanClient | ||
func newBarbicanClient(cfg Config) (client *gophercloud.ServiceClient, err error) { | ||
|
||
provider, err := openstack.AuthenticatedClient(cfg.toAuthOptions()) | ||
|
||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
client, err = openstack.NewKeyManagerV1(provider, gophercloud.EndpointOpts{ | ||
Region: cfg.Global.Region, | ||
}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return client, nil | ||
} | ||
|
||
// GetSecret gets unencrypted secret | ||
func (barbican *Barbican) GetSecret(cfg Config) ([]byte, error) { | ||
|
||
client, err := newBarbicanClient(cfg) | ||
|
||
keyID := cfg.KeyManager.KeyID | ||
|
||
if err != nil { | ||
glog.V(4).Infof("Failed to get Barbican client %v: ", err) | ||
return nil, err | ||
} | ||
|
||
opts := secrets.GetPayloadOpts{ | ||
PayloadContentType: "application/octet-stream", | ||
} | ||
|
||
key, err := secrets.GetPayload(client, keyID, opts).Extract() | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return key, 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,11 @@ | ||
package barbican | ||
|
||
import "encoding/hex" | ||
|
||
type FakeBarbican struct { | ||
} | ||
|
||
func (client *FakeBarbican) GetSecret(cfg Config) ([]byte, error) { | ||
return hex.DecodeString("6368616e676520746869732070617373") | ||
|
||
} |
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,54 @@ | ||
package main | ||
|
||
import ( | ||
"fmt" | ||
"golang.org/x/net/context" | ||
"google.golang.org/grpc" | ||
pb "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/v1beta1" | ||
"os" | ||
) | ||
|
||
//This client is for test purpose only, Kubernetes api server will call to kms plugin grpc server | ||
|
||
func main() { | ||
|
||
connection, err := grpc.Dial("unix:///var/lib/kms/kms.sock", grpc.WithInsecure()) | ||
defer connection.Close() | ||
if err != nil { | ||
fmt.Printf("\nConnection to KMS plugin failed, error: %v", err) | ||
} | ||
|
||
kmsClient := pb.NewKeyManagementServiceClient(connection) | ||
request := &pb.VersionRequest{Version: "v1beta1"} | ||
_, err = kmsClient.Version(context.TODO(), request) | ||
|
||
if err != nil { | ||
fmt.Printf("\nError in getting version from KMS Plugin: %v", err) | ||
} | ||
|
||
secretBytes := []byte("mypassword") | ||
|
||
//Encryption Request to KMS Plugin | ||
encRequest := &pb.EncryptRequest{ | ||
Version: "v1beta1", | ||
Plain: secretBytes} | ||
encResponse, err := kmsClient.Encrypt(context.TODO(), encRequest) | ||
|
||
if err != nil { | ||
fmt.Printf("\nEncrypt Request Failed: %v", err) | ||
os.Exit(1) | ||
} | ||
|
||
cipher := string(encResponse.Cipher) | ||
fmt.Println("cipher:", cipher) | ||
|
||
//Decryption Request to KMS plugin | ||
decRequest := &pb.DecryptRequest{ | ||
Version: "v1beta1", | ||
Cipher: encResponse.Cipher, | ||
} | ||
|
||
decResponse, err := kmsClient.Decrypt(context.TODO(), decRequest) | ||
|
||
fmt.Printf("\n\ndecryption response %v", decResponse) | ||
} |
Oops, something went wrong.