Skip to content

Commit

Permalink
Merge pull request spiffe#446 from evan2645/implement-update-entry-me…
Browse files Browse the repository at this point in the history
…thod-in-datastore-plugin

Implement UpdateRegistrationEntry method in datastore plugin
  • Loading branch information
evan2645 authored May 2, 2018
2 parents 0b21347 + f291b5a commit 2a923b7
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 11 deletions.
86 changes: 76 additions & 10 deletions pkg/server/plugin/datastore/sqlite/sqlite.go
Original file line number Diff line number Diff line change
Expand Up @@ -553,12 +553,11 @@ func (ds *sqlitePlugin) CreateRegistrationEntry(
// TODO: Validations should be done in the ProtoBuf level [https://github.com/spiffe/spire/issues/44]
if request.RegisteredEntry == nil {
return nil, errors.New("Invalid request: missing registered entry")
} else if request.RegisteredEntry.Selectors == nil || len(request.RegisteredEntry.Selectors) == 0 {
return nil, errors.New("Invalid request: missing selector list")
} else if len(request.RegisteredEntry.SpiffeId) == 0 {
return nil, errors.New("Invalid request: missing SPIFFE ID")
} else if request.RegisteredEntry.Ttl < 0 {
return nil, errors.New("Invalid request: TTL < 0")
}

err := ds.validateRegistrationEntry(request.RegisteredEntry)
if err != nil {
return nil, fmt.Errorf("Invalid registration entry: %v", err)
}

entryID, err := uuid.NewV4()
Expand Down Expand Up @@ -675,9 +674,60 @@ func (ds *sqlitePlugin) FetchRegistrationEntries(
return res, nil
}

func (sqlitePlugin) UpdateRegistrationEntry(
*datastore.UpdateRegistrationEntryRequest) (*datastore.UpdateRegistrationEntryResponse, error) {
return &datastore.UpdateRegistrationEntryResponse{}, errors.New("Not Implemented")
func (ds sqlitePlugin) UpdateRegistrationEntry(
request *datastore.UpdateRegistrationEntryRequest) (*datastore.UpdateRegistrationEntryResponse, error) {

if request.RegisteredEntry == nil {
return nil, errors.New("No registration entry provided")
}

err := ds.validateRegistrationEntry(request.RegisteredEntry)
if err != nil {
return nil, fmt.Errorf("Invalid registration entry: %v", err)
}

tx := ds.db.Begin()

// Get the existing entry
// TODO: Refactor message type to take EntryID directly from the entry - see #449
entry := RegisteredEntry{}
if err = tx.Find(&entry, "entry_id = ?", request.RegisteredEntryId).Error; err != nil {
tx.Rollback()
return nil, err
}

// Delete existing selectors - we will write new ones
if err = tx.Exec("DELETE FROM selectors WHERE registered_entry_id = ?", entry.ID).Error; err != nil {
tx.Rollback()
return nil, err
}

selectors := []Selector{}
for _, s := range request.RegisteredEntry.Selectors {
selector := Selector{
Type: s.Type,
Value: s.Value,
}

selectors = append(selectors, selector)
}

entry.SpiffeID = request.RegisteredEntry.SpiffeId
entry.ParentID = request.RegisteredEntry.ParentId
entry.TTL = request.RegisteredEntry.Ttl
entry.Selectors = selectors
if err = tx.Save(&entry).Error; err != nil {
tx.Rollback()
return nil, err
}

if err = tx.Commit().Error; err != nil {
tx.Rollback()
return nil, err
}

request.RegisteredEntry.EntryId = entry.EntryID
return &datastore.UpdateRegistrationEntryResponse{RegisteredEntry: request.RegisteredEntry}, nil
}

func (ds *sqlitePlugin) DeleteRegistrationEntry(
Expand Down Expand Up @@ -1007,6 +1057,22 @@ func (ds *sqlitePlugin) modelToBundle(model *Bundle) (*datastore.Bundle, error)
return pb, nil
}

func (ds *sqlitePlugin) validateRegistrationEntry(entry *common.RegistrationEntry) error {
if entry.Selectors == nil || len(entry.Selectors) == 0 {
return errors.New("missing selector list")
}

if len(entry.SpiffeId) == 0 {
return errors.New("missing SPIFFE ID")
}

if entry.Ttl < 0 {
return errors.New("TTL is not set")
}

return nil
}

// validateTrustDomain converts the given string to a URL, and ensures that it is a correctly
// formatted SPIFFE trust domain. String is taken as the argument here since neither Protobuf nor
// GORM natively support the url.URL type.
Expand Down Expand Up @@ -1128,5 +1194,5 @@ func NewTemp() (datastore.DataStore, error) {
}

p.db.LogMode(true)
return p, p.restart()
return p, nil
}
34 changes: 33 additions & 1 deletion pkg/server/plugin/datastore/sqlite/sqlite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,39 @@ func Test_FetchRegistrationEntries(t *testing.T) {
}

func Test_UpdateRegistrationEntry(t *testing.T) {
t.Skipf("TODO")
ds := createDefault(t)

entry1 := &common.RegistrationEntry{
Selectors: []*common.Selector{
{Type: "Type1", Value: "Value1"},
{Type: "Type2", Value: "Value2"},
{Type: "Type3", Value: "Value3"},
},
SpiffeId: "spiffe://example.org/foo",
ParentId: "spiffe://example.org/bar",
Ttl: 1,
}

createRegistrationEntryResponse, err := ds.CreateRegistrationEntry(&datastore.CreateRegistrationEntryRequest{entry1})
require.NoError(t, err)
require.NotNil(t, createRegistrationEntryResponse)

// TODO: Refactor message type to take EntryID directly from the entry - see #449
entry1.Ttl = 2
updReq := &datastore.UpdateRegistrationEntryRequest{
RegisteredEntryId: createRegistrationEntryResponse.RegisteredEntryId,
RegisteredEntry: entry1,
}
updateRegistrationEntryResponse, err := ds.UpdateRegistrationEntry(updReq)
require.NoError(t, err)
require.NotNil(t, updateRegistrationEntryResponse)

fetchRegistrationEntryResponse, err := ds.FetchRegistrationEntry(&datastore.FetchRegistrationEntryRequest{RegisteredEntryId: updReq.RegisteredEntryId})
require.NoError(t, err)
require.NotNil(t, fetchRegistrationEntryResponse)

expectedResponse := &datastore.FetchRegistrationEntryResponse{RegisteredEntry: entry1}
assert.Equal(t, expectedResponse, fetchRegistrationEntryResponse)
}

func Test_DeleteRegistrationEntry(t *testing.T) {
Expand Down

0 comments on commit 2a923b7

Please sign in to comment.