Skip to content

Commit

Permalink
Implement UpdateParam in web
Browse files Browse the repository at this point in the history
  • Loading branch information
whywaita committed Oct 14, 2021
1 parent 4b8c15f commit 3db2b75
Show file tree
Hide file tree
Showing 7 changed files with 219 additions and 42 deletions.
2 changes: 1 addition & 1 deletion pkg/datastore/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type Datastore interface {
UpdateTargetStatus(ctx context.Context, targetID uuid.UUID, newStatus TargetStatus, description string) error
UpdateToken(ctx context.Context, targetID uuid.UUID, newToken string, newExpiredAt time.Time) error

UpdateResourceType(ctx context.Context, targetID uuid.UUID, newResourceType ResourceType) error
UpdateTargetParam(ctx context.Context, targetID uuid.UUID, newResourceType ResourceType, newRunnerVersion, newRunnerUser, newProviderURL string) error

EnqueueJob(ctx context.Context, job Job) error
ListJobs(ctx context.Context) ([]Job, error)
Expand Down
17 changes: 15 additions & 2 deletions pkg/datastore/memory/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package memory

import (
"context"
"database/sql"
"fmt"
"sync"
"time"
Expand Down Expand Up @@ -141,8 +142,8 @@ func (m *Memory) UpdateToken(ctx context.Context, targetID uuid.UUID, newToken s
return nil
}

// UpdateResourceType update resource_type in target
func (m *Memory) UpdateResourceType(ctx context.Context, targetID uuid.UUID, newResourceType datastore.ResourceType) error {
// UpdateTargetParam update parameter of target
func (m *Memory) UpdateTargetParam(ctx context.Context, targetID uuid.UUID, newResourceType datastore.ResourceType, newRunnerVersion, newRunnerUser, newProviderURL string) error {
m.mu.Lock()
defer m.mu.Unlock()

Expand All @@ -151,6 +152,18 @@ func (m *Memory) UpdateResourceType(ctx context.Context, targetID uuid.UUID, new
return fmt.Errorf("not found")
}
t.ResourceType = newResourceType
t.RunnerVersion = sql.NullString{
String: newRunnerVersion,
Valid: true,
}
t.RunnerUser = sql.NullString{
String: newRunnerUser,
Valid: true,
}
t.ProviderURL = sql.NullString{
String: newProviderURL,
Valid: true,
}

m.targets[targetID] = t
return nil
Expand Down
27 changes: 23 additions & 4 deletions pkg/datastore/mysql/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"database/sql"
"errors"
"fmt"
"strings"
"time"

uuid "github.com/satori/go.uuid"
Expand Down Expand Up @@ -109,12 +110,30 @@ func (m *MySQL) UpdateToken(ctx context.Context, targetID uuid.UUID, newToken st
return nil
}

// UpdateResourceType update resource type in target
func (m *MySQL) UpdateResourceType(ctx context.Context, targetID uuid.UUID, newResourceType datastore.ResourceType) error {
query := `UPDATE targets SET resource_type = ? WHERE uuid = ?`
if _, err := m.Conn.ExecContext(ctx, query, newResourceType, targetID.String()); err != nil {
// UpdateTargetParam update parameter of target
func (m *MySQL) UpdateTargetParam(ctx context.Context, targetID uuid.UUID, newResourceType datastore.ResourceType, newRunnerVersion, newRunnerUser, newProviderURL string) error {
newRV := toSQLNullString(newRunnerVersion)
newRU := toSQLNullString(newRunnerUser)
newPU := toSQLNullString(newProviderURL)

query := `UPDATE targets SET resource_type = ?, runner_version = ?, runner_user = ?, provider_url = ? WHERE uuid = ?`
if _, err := m.Conn.ExecContext(ctx, query, newResourceType, newRV, newRU, newPU, targetID.String()); err != nil {
return fmt.Errorf("failed to execute UPDATE query: %w", err)
}

return nil
}

func toSQLNullString(input string) sql.NullString {
if strings.EqualFold(input, "") {
return sql.NullString{
Valid: false,
String: "",
}
}

return sql.NullString{
Valid: true,
String: input,
}
}
79 changes: 68 additions & 11 deletions pkg/datastore/mysql/target_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ var testScopeOrg = "octocat"
var testScopeRepo = "octocat/hello-world"
var testGitHubToken = "this-code-is-github-token"
var testRunnerVersion = "v999.99.9"
var testRunnerUser = "testing-super-user"
var testProviderURL = "/shoes-mock"
var testTime = time.Date(2037, 9, 3, 0, 0, 0, 0, time.UTC)

Expand Down Expand Up @@ -702,18 +703,57 @@ func TestMySQL_UpdateToken(t *testing.T) {
}
}

func TestMySQL_UpdateResourceType(t *testing.T) {
func TestMySQL_UpdateTargetParam(t *testing.T) {
testDatastore, teardown := testutils.GetTestDatastore()
defer teardown()
testDB, _ := testutils.GetTestDB()

type input struct {
resourceType datastore.ResourceType
runnerVersion string
runnerUser string
providerURL string
}

tests := []struct {
input datastore.ResourceType
input input
want *datastore.Target
err bool
}{
{
input: datastore.ResourceTypeNano,
input: input{
resourceType: datastore.ResourceTypeLarge,
runnerVersion: "",
runnerUser: "",
providerURL: "",
},
want: &datastore.Target{
Scope: testScopeRepo,
GitHubToken: testGitHubToken,
ResourceType: datastore.ResourceTypeLarge,
RunnerVersion: sql.NullString{
String: "",
Valid: false,
},
ProviderURL: sql.NullString{
String: "",
Valid: false,
},
Status: datastore.TargetStatusActive,
StatusDescription: sql.NullString{
String: "",
Valid: false,
},
},
err: false,
},
{
input: input{
resourceType: datastore.ResourceTypeLarge,
runnerVersion: testRunnerVersion,
runnerUser: testRunnerUser,
providerURL: testProviderURL,
},
want: &datastore.Target{
Scope: testScopeRepo,
GitHubToken: testGitHubToken,
Expand All @@ -722,6 +762,10 @@ func TestMySQL_UpdateResourceType(t *testing.T) {
String: testRunnerVersion,
Valid: true,
},
RunnerUser: sql.NullString{
String: testRunnerUser,
Valid: true,
},
ProviderURL: sql.NullString{
String: testProviderURL,
Valid: true,
Expand All @@ -735,7 +779,12 @@ func TestMySQL_UpdateResourceType(t *testing.T) {
err: false,
},
{
input: datastore.ResourceType4XLarge,
input: input{
resourceType: datastore.ResourceTypeLarge,
runnerVersion: testRunnerVersion,
runnerUser: testRunnerUser,
providerURL: "",
},
want: &datastore.Target{
Scope: testScopeRepo,
GitHubToken: testGitHubToken,
Expand All @@ -744,10 +793,14 @@ func TestMySQL_UpdateResourceType(t *testing.T) {
String: testRunnerVersion,
Valid: true,
},
ProviderURL: sql.NullString{
String: testProviderURL,
RunnerUser: sql.NullString{
String: testRunnerUser,
Valid: true,
},
ProviderURL: sql.NullString{
String: "",
Valid: false,
},
Status: datastore.TargetStatusActive,
StatusDescription: sql.NullString{
String: "",
Expand All @@ -765,20 +818,24 @@ func TestMySQL_UpdateResourceType(t *testing.T) {
Scope: testScopeRepo,
GitHubToken: testGitHubToken,
TokenExpiredAt: testTime,
ResourceType: test.input,
ResourceType: datastore.ResourceTypeNano,
RunnerVersion: sql.NullString{
String: testRunnerVersion,
Valid: true,
String: "",
Valid: false,
},
RunnerUser: sql.NullString{
String: "",
Valid: false,
},
ProviderURL: sql.NullString{
String: testProviderURL,
String: "test-default-string",
Valid: true,
},
}); err != nil {
t.Fatalf("failed to create target: %+v", err)
}

if err := testDatastore.UpdateResourceType(context.Background(), tID, test.want.ResourceType); err != nil {
if err := testDatastore.UpdateTargetParam(context.Background(), tID, test.input.resourceType, test.input.runnerVersion, test.input.runnerUser, test.input.providerURL); err != nil {
t.Fatalf("failed to UpdateResourceTyoe: %+v", err)
}

Expand Down
59 changes: 53 additions & 6 deletions pkg/web/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,14 +218,25 @@ func handleTargetUpdate(w http.ResponseWriter, r *http.Request, ds datastore.Dat
outputErrorMsg(w, http.StatusBadRequest, "incorrect target id (not found)")
return
}
if err := validateUpdateTarget(oldTarget, &newTarget); err != nil {
if err := validateUpdateTarget(*oldTarget, newTarget); err != nil {
logger.Logf(false, "input error in validateUpdateTarget: %+v", err)
outputErrorMsg(w, http.StatusBadRequest, "request parameter has value of not updatable")
return
}

if err := ds.UpdateResourceType(ctx, targetID, inputTarget.ResourceType); err != nil {
logger.Logf(false, "failed to ds.UpdateResourceType: %+v", err)
updateParam := getWillUpdateTargetVariable(updatableVariable{
resourceType: oldTarget.ResourceType,
runnerVersion: oldTarget.RunnerVersion.String,
runnerUser: oldTarget.RunnerUser.String,
providerURL: oldTarget.ProviderURL.String,
}, updatableVariable{
resourceType: inputTarget.ResourceType,
runnerVersion: inputTarget.RunnerVersion,
runnerUser: inputTarget.RunnerUser,
providerURL: inputTarget.ProviderURL,
})
if err := ds.UpdateTargetParam(ctx, targetID, updateParam.resourceType, updateParam.runnerVersion, updateParam.runnerUser, updateParam.providerURL); err != nil {
logger.Logf(false, "failed to ds.UpdateTargetParam: %+v", err)
outputErrorMsg(w, http.StatusInternalServerError, "datastore update error")
return
}
Expand Down Expand Up @@ -301,12 +312,18 @@ func outputErrorMsg(w http.ResponseWriter, status int, msg string) {
}

// validateUpdateTarget check input target that can valid input in update.
func validateUpdateTarget(old, new *datastore.Target) error {
for _, t := range []*datastore.Target{old, new} {
func validateUpdateTarget(old, new datastore.Target) error {
oldv := old
newv := new

for _, t := range []*datastore.Target{&oldv, &newv} {
t.UUID = uuid.UUID{}

// can update variables
t.ResourceType = datastore.ResourceTypeUnknown
t.RunnerVersion = sql.NullString{}
t.RunnerUser = sql.NullString{}
t.ProviderURL = sql.NullString{}

// time
t.TokenExpiredAt = time.Time{}
Expand All @@ -319,9 +336,39 @@ func validateUpdateTarget(old, new *datastore.Target) error {
t.GitHubToken = ""
}

if diff := cmp.Diff(old, new); diff != "" {
if diff := cmp.Diff(oldv, newv); diff != "" {
return fmt.Errorf("mismatch (-want +got):\n%s", diff)
}

return nil
}

type updatableVariable struct {
resourceType datastore.ResourceType
runnerVersion string
runnerUser string
providerURL string
}

func getWillUpdateTargetVariable(oldParam, newParam updatableVariable) updatableVariable {
var result updatableVariable

if newParam.resourceType == datastore.ResourceTypeUnknown {
result.resourceType = oldParam.resourceType
} else {
result.resourceType = newParam.resourceType
}

result.runnerVersion = getWillUpdateTargetVariableString(oldParam.runnerVersion, newParam.runnerVersion)
result.runnerUser = getWillUpdateTargetVariableString(oldParam.runnerUser, newParam.runnerUser)
result.providerURL = getWillUpdateTargetVariableString(oldParam.providerURL, newParam.providerURL)

return result
}

func getWillUpdateTargetVariableString(old, new string) string {
if strings.EqualFold(new, "") {
return old
}
return new
}
13 changes: 12 additions & 1 deletion pkg/web/target_create.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,18 @@ func handleTargetCreate(w http.ResponseWriter, r *http.Request, ds datastore.Dat
outputErrorMsg(w, http.StatusInternalServerError, "datastore recreate error")
return
}
if err := ds.UpdateResourceType(ctx, target.UUID, t.ResourceType); err != nil {
updateParam := getWillUpdateTargetVariable(updatableVariable{
resourceType: target.ResourceType,
runnerVersion: target.RunnerVersion.String,
runnerUser: target.RunnerUser.String,
providerURL: target.ProviderURL.String,
}, updatableVariable{
resourceType: inputTarget.ResourceType,
runnerVersion: inputTarget.RunnerVersion,
runnerUser: inputTarget.RunnerUser,
providerURL: inputTarget.ProviderURL,
})
if err := ds.UpdateTargetParam(ctx, target.UUID, updateParam.resourceType, updateParam.runnerVersion, updateParam.runnerUser, updateParam.providerURL); err != nil {
logger.Logf(false, "failed to update resource type in recreating target: %+v", err)
outputErrorMsg(w, http.StatusInternalServerError, "update resource type error")
return
Expand Down
Loading

0 comments on commit 3db2b75

Please sign in to comment.