Skip to content

Commit

Permalink
Merge pull request #152 from kanisterio/sync
Browse files Browse the repository at this point in the history
 Add GCP snapshot volume support to kanister
  • Loading branch information
SupriyaKasten authored Mar 9, 2019
2 parents 1e86b0d + 6eb2d66 commit 6df03b7
Show file tree
Hide file tree
Showing 17 changed files with 724 additions and 82 deletions.
36 changes: 35 additions & 1 deletion docs/_static/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ h1, h2, h3, h4, h5, h6 {

body, p {
font-family: 'Open Sans', sans-serif !important;
font-weight: 400 !important;
font-weight: 400;
}

div.body p {
line-height: 1.6em;
}

li {
Expand All @@ -20,4 +24,34 @@ li {

div.admonition {
padding: 1rem 2rem;
border-width: 0 0 0 3px;
}

div.admonition.warning {
background-color: #fff3f3;
border-color: #FAA;
}

div.sphinxsidebarwrapper p.logo {
margin: -10px 0 3rem -20px;
}

img.logo {
max-width: 80%;
}

div.topic {
padding: 20px 30px;
margin: 20px 0 10px 0;
border: none;
background-color: #edf6fb;
}

div.sphinxsidebarwrapper #searchbox {
margin-top: 2rem;
}

div.sphinxsidebar #searchbox input {
padding: 0.6rem !important;
font-family: 'Open Sans', sans-serif;
}
2 changes: 1 addition & 1 deletion docs/architecture.rst
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ As a reference, below is an example of a ActionSpec.
name: example-profile
namespace: example-namespace
In addition the Spec, an ActionSet also contains an ActionSetStatus
In addition to the Spec, an ActionSet also contains an ActionSetStatus
which mirrors the Spec, but contains the phases of execution, their
state, and the overall execution progress.

Expand Down
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@

# General information about the project.
project = 'Kanister'
copyright = '2017-2018, Kanister'
copyright = '2017-2019, Kanister'
author = 'Kanister'

# The version info for the project you're documenting, acts as replacement for
Expand Down
10 changes: 5 additions & 5 deletions docs/templates.rst
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ For example, to access the Name of a Deployment use:
"{{ index .Deployment.Name }}"
Namespace
---
---------

NamespaceParams includes the name of the namespace
that is being acted on when the ActionSet `Object` is
Expand Down Expand Up @@ -573,12 +573,12 @@ or as output artifacts using templating.

For example, an output artifact can reference the output from a phase as follows:

.. code-block:: yaml
.. code-block:: go
"{{ .Phases.phase-name.Output.key-name }}"
"{{ .Phases.phase-name.Output.key-name }}"
Similarly, a phase can use Secrets as arguments:

.. code-block:: yaml
.. code-block:: go
"{{ .Phases.phase-name.Secrets.secret-name.Namespace }}"
"{{ .Phases.phase-name.Secrets.secret-name.Namespace }}"
2 changes: 1 addition & 1 deletion docs/tutorial.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ the Kanister controller.

The first Kanister CustomResource we're going to deploy is a Blueprint.
Blueprints are a set of instructions that tell the controller how to perform
actions on an application. A action consists of one or more phases. Each phase
actions on an application. An action consists of one or more phases. Each phase
invokes a :doc:`Kanister Function </functions>`. All Kanister functions accept a
list of strings. The `args` field in a Blueprint's phase is rendered and passed
into the specified Function.
Expand Down
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 6df03b7

Please sign in to comment.