Skip to content

Commit

Permalink
merge write groups into read groups (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
billiford authored Jul 29, 2021
1 parent 0f63751 commit a06b14c
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 135 deletions.
46 changes: 15 additions & 31 deletions internal/api/v1/credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"strings"

"github.com/gin-gonic/gin"
"github.com/google/uuid"
"github.com/jinzhu/gorm"
"github.com/homedepot/cloud-runner/internal/fiat"
"github.com/homedepot/cloud-runner/internal/sql"
Expand Down Expand Up @@ -43,47 +42,32 @@ func (cc *Controller) CreateCredentials(c *gin.Context) {
}
}

// Make sure credentials read groups contain all write groups.
for _, wg := range creds.WriteGroups {
if !contains(creds.ReadGroups, wg) {
creds.ReadGroups = append(creds.ReadGroups, wg)
}
}

err = cc.SqlClient.CreateCredentials(creds)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})

return
}

// TODO make these calls part of the sql client to create the credentials,
// additionally they should be part of a transaction that will be rolled
// back if any fail.
for _, group := range creds.ReadGroups {
rp := cloudrunner.CredentialsReadPermission{
ID: uuid.New().String(),
Account: creds.Account,
ReadGroup: group,
}

err = cc.SqlClient.CreateReadPermission(rp)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})

return
}
}

for _, group := range creds.WriteGroups {
wp := cloudrunner.CredentialsWritePermission{
ID: uuid.New().String(),
Account: creds.Account,
WriteGroup: group,
}

err = cc.SqlClient.CreateWritePermission(wp)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
c.JSON(http.StatusCreated, creds)
}

return
// contains returns true if slice s contains element e (case insensitive).
func contains(s []string, e string) bool {
for _, a := range s {
if strings.EqualFold(a, e) {
return true
}
}

c.JSON(http.StatusCreated, creds)
return false
}

// DeleteCredentials deletes credentials from the DB by account name.
Expand Down
37 changes: 14 additions & 23 deletions internal/api/v1/credentials_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import (
"errors"
"net/http"

"github.com/homedepot/cloud-runner/internal/fiat"
"github.com/homedepot/cloud-runner/internal/sql"
cloudrunner "github.com/homedepot/cloud-runner/pkg"
"github.com/jinzhu/gorm"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/homedepot/cloud-runner/internal/fiat"
"github.com/homedepot/cloud-runner/internal/sql"
cloudrunner "github.com/homedepot/cloud-runner/pkg"
)

var _ = Describe("Credentials", func() {
Expand Down Expand Up @@ -91,38 +91,29 @@ var _ = Describe("Credentials", func() {
})
})

When("creating a read group returns an error", func() {
BeforeEach(func() {
fakeSQLClient.CreateReadPermissionReturns(errors.New("error creating read permission"))
})

It("returns status internal server error", func() {
Expect(res.StatusCode).To(Equal(http.StatusInternalServerError))
validateResponse(payloadErrorCreatingReadPermission)
})
})

When("creating a write group returns an error", func() {
When("the account is not defined", func() {
BeforeEach(func() {
fakeSQLClient.CreateWritePermissionReturns(errors.New("error creating write permission"))
body = &bytes.Buffer{}
body.Write([]byte(`{"projectID": "test-project-id"}`))
createRequest(http.MethodPost)
})

It("returns status internal server error", func() {
Expect(res.StatusCode).To(Equal(http.StatusInternalServerError))
validateResponse(payloadErrorCreatingWritePermission)
It("generates the account name", func() {
Expect(res.StatusCode).To(Equal(http.StatusCreated))
validateResponse(payloadCredentialsCreatedNoAccountProvided)
})
})

When("the account is not defined", func() {
When("the request contains write groups that are not present in read groups", func() {
BeforeEach(func() {
body = &bytes.Buffer{}
body.Write([]byte(`{"projectID": "test-project-id"}`))
body.Write([]byte(payloadRequestCredentialsMismatchedGroups))
createRequest(http.MethodPost)
})

It("generates the account name", func() {
It("merges the write groups into the read groups", func() {
Expect(res.StatusCode).To(Equal(http.StatusCreated))
validateResponse(payloadCredentialsCreatedNoAccountProvided)
validateResponse(payloadCredentialsCreatedMergedGroups)
})
})

Expand Down
25 changes: 25 additions & 0 deletions internal/api/v1/payload_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ const payloadRequestCredentials = `{
]
}`

const payloadRequestCredentialsMismatchedGroups = `{
"account": "test-account",
"projectID": "test-project-id",
"readGroups": [
"gg_test1"
],
"writeGroups": [
"gg_test1",
"gg_test2"
]
}`

const payloadRequestDeployment = `{
"account": "cr-test-project-id",
"allowUnauthenticated": false,
Expand Down Expand Up @@ -74,6 +86,19 @@ const payloadCredentialsCreatedNoAccountProvided = `{
"projectID": "test-project-id"
}`

const payloadCredentialsCreatedMergedGroups = `{
"account": "test-account",
"projectID": "test-project-id",
"readGroups": [
"gg_test1",
"gg_test2"
],
"writeGroups": [
"gg_test1",
"gg_test2"
]
}`

const payloadCredentialsCreated = `{
"account": "test-account",
"projectID": "test-project-id",
Expand Down
47 changes: 33 additions & 14 deletions internal/sql/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"sort"
"time"

"github.com/google/uuid"
"github.com/jinzhu/gorm"
cloudrunner "github.com/homedepot/cloud-runner/pkg"

Expand Down Expand Up @@ -35,8 +36,6 @@ type Client interface {
Connection() (string, string)
CreateCredentials(cloudrunner.Credentials) error
CreateDeployment(cloudrunner.Deployment) error
CreateReadPermission(cloudrunner.CredentialsReadPermission) error
CreateWritePermission(cloudrunner.CredentialsWritePermission) error
DB() *gorm.DB
DeleteCredentials(string) error
GetCredentials(string) (cloudrunner.Credentials, error)
Expand Down Expand Up @@ -100,26 +99,46 @@ func (c *client) Connection() (string, string) {
c.user, c.pass, c.host, c.name)
}

// CreateCredentials inserts a new set of credentials into the DB.
// CreateCredentials inserts a new set of credentials into the DB along with
// its associated read/write groups. It uses a transaction, so that if any
// operation fails the operations are rolled back.
func (c *client) CreateCredentials(credentials cloudrunner.Credentials) error {
return c.db.Create(&credentials).Error
return c.db.Transaction(func(tx *gorm.DB) error {
for _, group := range credentials.ReadGroups {
r := cloudrunner.CredentialsReadPermission{
ID: uuid.New().String(),
Account: credentials.Account,
ReadGroup: group,
}

err := tx.Create(&r).Error
if err != nil {
return err
}
}

for _, group := range credentials.WriteGroups {
w := cloudrunner.CredentialsWritePermission{
ID: uuid.New().String(),
Account: credentials.Account,
WriteGroup: group,
}

err := tx.Create(&w).Error
if err != nil {
return err
}
}

return tx.Create(&credentials).Error
})
}

// CreateDeployment inserts a new deployment into the DB.
func (c *client) CreateDeployment(d cloudrunner.Deployment) error {
return c.db.Create(&d).Error
}

// CreateReadPermission inserts a read permission into the database.
func (c *client) CreateReadPermission(r cloudrunner.CredentialsReadPermission) error {
return c.db.Create(&r).Error
}

// CreateWritePermission inserts a write permission into the database.
func (c *client) CreateWritePermission(w cloudrunner.CredentialsWritePermission) error {
return c.db.Create(&w).Error
}

// DB returns the underlying db.
func (c *client) DB() *gorm.DB {
return c.db
Expand Down
Loading

0 comments on commit a06b14c

Please sign in to comment.