Skip to content

Commit

Permalink
Add GCP snapshot volume support to kanister (#4788)
Browse files Browse the repository at this point in the history
* copy k10/blockstorage/gcepd to kansiter

* Modify blockstorage for GCP Volume snapshot

* remove kasten reference

* Use poll.Wait() instead of time.Sleep()

* Fix space b/w comments & serviceKey assignment

* nit fix

* set label in initial CreateSnapshot() call
  • Loading branch information
SupriyaKasten authored and Ilya Kislenko committed Jan 29, 2019
1 parent 6c1db66 commit 87783f0
Show file tree
Hide file tree
Showing 6 changed files with 550 additions and 24 deletions.
52 changes: 28 additions & 24 deletions pkg/blockstorage/blockstorage_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,11 @@ type BlockStorageProviderSuite struct {
}

var _ = Suite(&BlockStorageProviderSuite{storageType: blockstorage.TypeEBS, storageRegion: clusterRegionAWS})
var _ = Suite(&BlockStorageProviderSuite{storageType: blockstorage.TypeGPD, storageRegion: ""})

func (s *BlockStorageProviderSuite) SetUpSuite(c *C) {
config := make(map[string]string)
var err error
if s.storageType == blockstorage.TypeEBS {
config[awsebs.ConfigRegion] = s.storageRegion
accessKey, ok := os.LookupEnv(awsebs.AccessKeyID)
if !ok {
c.Skip("The necessary env variable AWS_ACCESS_KEY_ID is not set.")
}
secretAccessKey, ok := os.LookupEnv(awsebs.SecretAccessKey)
if !ok {
c.Skip("The necessary env variable AWS_SECRET_ACCESS_KEY is not set.")
}
config[awsebs.AccessKeyID] = accessKey
config[awsebs.SecretAccessKey] = secretAccessKey
}
config := s.getConfig(c, s.storageRegion)
s.provider, err = getter.New().Get(s.storageType, config)
c.Assert(err, IsNil)
}
Expand Down Expand Up @@ -147,16 +135,7 @@ func (s *BlockStorageProviderSuite) TestSnapshotCopy(c *C) {

log.Infof("Copied snapshot %v to %v", srcSnapshot.ID, snap.ID)

config := make(map[string]string)
if s.storageType == blockstorage.TypeEBS {
config[awsebs.ConfigRegion] = dstSnapshot.Region
accessKey := os.Getenv(awsebs.AccessKeyID)
c.Assert(len(accessKey) > 0, Equals, true)
secretAccessKey := os.Getenv(awsebs.SecretAccessKey)
c.Assert(len(secretAccessKey) > 0, Equals, true)
config[awsebs.AccessKeyID] = accessKey
config[awsebs.SecretAccessKey] = secretAccessKey
}
config := s.getConfig(c, dstSnapshot.Region)
provider, err := getter.New().Get(s.storageType, config)
c.Assert(err, IsNil)

Expand Down Expand Up @@ -267,3 +246,28 @@ func (s *BlockStorageProviderSuite) checkStdTagsExist(c *C, actual map[string]st
c.Check(actual[k], NotNil)
}
}

func (s *BlockStorageProviderSuite) getConfig(c *C, region string) map[string]string {
config := make(map[string]string)
switch s.storageType {
case blockstorage.TypeEBS:
config[awsebs.ConfigRegion] = region
accessKey, ok := os.LookupEnv(awsebs.AccessKeyID)
if !ok {
c.Skip("The necessary env variable AWS_ACCESS_KEY_ID is not set.")
}
secretAccessKey, ok := os.LookupEnv(awsebs.SecretAccessKey)
if !ok {
c.Skip("The necessary env variable AWS_SECRET_ACCESS_KEY is not set.")
}
config[awsebs.AccessKeyID] = accessKey
config[awsebs.SecretAccessKey] = secretAccessKey
case blockstorage.TypeGPD:
creds, ok := os.LookupEnv(blockstorage.GoogleCloudCreds)
if !ok {
c.Skip("The necessary env variable GOOGLE_APPLICATION_CREDENTIALS is not set.")
}
config[blockstorage.GoogleCloudCreds] = creds
}
return config
}
49 changes: 49 additions & 0 deletions pkg/blockstorage/gcepd/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package gcepd

import (
"context"
"net/http"

"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
compute "google.golang.org/api/compute/v1"
)

// Client is a wrapper for Client client
type Client struct {
Service *compute.Service
ProjectID string
}

// NewClient returns a Client struct
func NewClient(ctx context.Context, servicekey string) (*Client, error) {
var err error
var creds *google.Credentials
if len(servicekey) > 0 {
creds, err = google.CredentialsFromJSON(ctx, []byte(servicekey), compute.ComputeScope)
} else {
creds, err = google.FindDefaultCredentials(ctx, compute.ComputeScope)
}

if err != nil {
return nil, err
}
// NOTE: Ashlie is not sure how long this will work for since a comment at
// https://godoc.org/golang.org/x/oauth2#NewClient
// states that the client in the context will only be used for getting a
// token.
httpClient := &http.Client{Transport: http.DefaultTransport}
ctx = context.WithValue(ctx, oauth2.HTTPClient, httpClient)

client := oauth2.NewClient(ctx, creds.TokenSource)

service, err := compute.New(client)
if err != nil {
return nil, err
}

return &Client{
Service: service,
ProjectID: creds.ProjectID,
}, nil
}
45 changes: 45 additions & 0 deletions pkg/blockstorage/gcepd/client_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package gcepd

import (
"context"
"io/ioutil"
"os"
"testing"

. "gopkg.in/check.v1"

"github.com/kanisterio/kanister/pkg/blockstorage"
)

// Hook up gocheck into the "go test" runner.
func Test(t *testing.T) { TestingT(t) }

type ClientSuite struct{}

var _ = Suite(&ClientSuite{})

func (s *ClientSuite) SetUpSuite(c *C) {}

func (s *ClientSuite) TestClient(c *C) {
var zone string
filename := s.GetEnvOrSkip(c, blockstorage.GoogleCloudCreds)
b, err := ioutil.ReadFile(filename)
c.Assert(err, IsNil)
gCli, err := NewClient(context.Background(), string(b))
c.Assert(err, IsNil)
c.Assert(gCli.Service, NotNil)
c.Assert(*gCli, FitsTypeOf, Client{})
// Get zone
zone = s.GetEnvOrSkip(c, blockstorage.GoogleCloudZone)
_, err = gCli.Service.Disks.List(gCli.ProjectID, zone).Do()
c.Assert(err, IsNil)
}

func (s *ClientSuite) GetEnvOrSkip(c *C, varName string) string {
v := os.Getenv(varName)
// Ensure the variable is set
if v == "" {
c.Skip("Required environment variable " + varName + " is not set")
}
return v
}
Loading

0 comments on commit 87783f0

Please sign in to comment.