Skip to content

Commit

Permalink
fix: Adding in resourceGroup and bucketName to get Velero Azure plugi…
Browse files Browse the repository at this point in the history
…n operational

feat: Added in half implementation of AKSBucketProvider

Encapsulated the storage account parsing down close the CLI which appears to be the only part that requires them as separate arguments
... to get Velero boot operational

Signed-off-by: Chris Mellard <[email protected]>

Fixing up cherry pick empty commit error that has different response for cherry-pick vs rebase
  • Loading branch information
Chris Mellard committed Jul 24, 2020
1 parent 5317712 commit 65853ed
Show file tree
Hide file tree
Showing 10 changed files with 471 additions and 2 deletions.
116 changes: 116 additions & 0 deletions pkg/cloud/aks/aks.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ package aks
import (
b64 "encoding/base64"
"encoding/json"
"fmt"
"regexp"
"strings"

"github.com/jenkins-x/jx-logging/pkg/log"
"github.com/jenkins-x/jx/v2/pkg/util"
"github.com/pkg/errors"
)

// AzureRunner an Azure CLI runner to interact with Azure
Expand All @@ -28,6 +31,10 @@ type acr struct {
Name string `json:"name"`
}

type containerExists struct {
Exists bool `json:"exists"`
}

type password struct {
Name string `json:"name"`
Value string `json:"value"`
Expand All @@ -46,6 +53,10 @@ type config struct {
Auths map[string]*auth `json:"auths,omitempty"`
}

var (
azureContainerURIRegExp = regexp.MustCompile(`https://(?P<first>\w+)\.blob\.core\.windows\.net/(?P<second>\w+)`)
)

// NewAzureRunnerWithCommander specific the command runner for Azure CLI.
func NewAzureRunnerWithCommander(runner util.Commander) *AzureRunner {
return &AzureRunner{
Expand Down Expand Up @@ -242,3 +253,108 @@ func (az *AzureRunner) azureCLI(args ...string) (string, error) {
az.Runner.SetArgs(args)
return az.Runner.RunWithoutRetry()
}

func parseContainerURL(bucketURL string) (string, string, error) {
match := azureContainerURIRegExp.FindStringSubmatch(bucketURL)
if len(match) == 3 {
return match[1], match[2], nil
}
return "", "", errors.New(fmt.Sprintf("Azure Blob Container Url %s could not be parsed to determine storage account and container name", bucketURL))
}

// ContainerExists checks if an Azure Storage Container exists
func (az *AzureRunner) ContainerExists(bucketURL string) (bool, error) {
storageAccount, bucketName, err := parseContainerURL(bucketURL)
if err != nil {
return false, err
}

accessKey, err := az.GetStorageAccessKey(storageAccount)
if err != nil {
return false, err
}

bucketExistsArgs := []string{
"storage",
"container",
"exists",
"-n",
bucketName,
"--account-name",
storageAccount,
"--account-key",
accessKey,
}

cmdResult, err := az.azureCLI(bucketExistsArgs...)

if err != nil {
log.Logger().Infof("Error checking bucket exists: %s, %s", cmdResult, err)
return false, err
}

containerExists := containerExists{}
err = json.Unmarshal([]byte(cmdResult), &containerExists)
if err != nil {
return false, errors.Wrap(err, "unmarshalling Azure container exists command")
}
return containerExists.Exists, nil

}

// CreateContainer creates a Blob container within Azure Storage
func (az *AzureRunner) CreateContainer(bucketURL string) error {
storageAccount, bucketName, err := parseContainerURL(bucketURL)
if err != nil {
return err
}

accessKey, err := az.GetStorageAccessKey(storageAccount)
if err != nil {
return err
}

createContainerArgs := []string{
"storage",
"container",
"create",
"-n",
bucketName,
"--account-name",
storageAccount,
"--fail-on-exist",
"--account-key",
accessKey,
}

cmdResult, err := az.azureCLI(createContainerArgs...)

if err != nil {
log.Logger().Infof("Error creating bucket: %s, %s", cmdResult, err)
return err
}

return nil
}

// GetStorageAccessKey retrieves access keys for an Azure storage account
func (az *AzureRunner) GetStorageAccessKey(storageAccount string) (string, error) {
getStorageAccessKeyArgs := []string{
"storage",
"account",
"keys",
"list",
"-n",
storageAccount,
"--query",
"[?keyName=='key1'].value | [0]",
}

cmdResult, err := az.azureCLI(getStorageAccessKeyArgs...)

if err != nil {
return "", err
}

return cmdResult, nil
}
8 changes: 8 additions & 0 deletions pkg/cloud/aks/interface.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package aks

// AzureStorage Interface for Azure Storage commands
type AzureStorage interface {
ContainerExists(bucketURL string) (bool, error)
CreateContainer(bucketURL string) error
GetStorageAccessKey(storageAccount string) (string, error)
}
197 changes: 197 additions & 0 deletions pkg/cloud/aks/mocks/azurestorage.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 65853ed

Please sign in to comment.