Compare commits

...

5 Commits

Author SHA1 Message Date
Felix Han
e79639da34 feat(webhooks): fixed import package 2022-04-26 12:07:48 +12:00
Felix Han
e67555102c feat(webhooks): fixed duplicate query string parameter issue 2022-04-26 12:05:51 +12:00
Felix Han
43ad2ab22a feat(webhook): fixed formatting 2022-04-21 15:50:38 +12:00
Felix Han
2351771340 feat(webhook): pass ENV via webhook 2022-04-21 01:57:58 +12:00
Felix Han
e2e35777f5 feat(webhook): merge webhook query strings to stack env var. 2022-04-21 01:44:35 +12:00
5 changed files with 46 additions and 12 deletions

View File

@@ -19,7 +19,7 @@ func startAutoupdate(stackID portainer.StackID, interval string, scheduler *sche
}
jobID = scheduler.StartJobEvery(d, func() error {
return stacks.RedeployWhenChanged(stackID, stackDeployer, datastore, gitService)
return stacks.RedeployWhenChanged(stackID, stackDeployer, datastore, gitService, nil)
})
return jobID, nil

View File

@@ -8,6 +8,7 @@ import (
"github.com/portainer/libhttp/response"
portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/stacks"
httperror "github.com/portainer/libhttp/error"
@@ -31,6 +32,7 @@ func (handler *Handler) webhookInvoke(w http.ResponseWriter, r *http.Request) *h
}
stack, err := handler.DataStore.Stack().StackByWebhookID(webhookID.String())
if err != nil {
statusCode := http.StatusInternalServerError
if handler.DataStore.IsErrObjectNotFound(err) {
@@ -39,7 +41,15 @@ func (handler *Handler) webhookInvoke(w http.ResponseWriter, r *http.Request) *h
return &httperror.HandlerError{StatusCode: statusCode, Message: "Unable to find the stack by webhook ID", Err: err}
}
if err = stacks.RedeployWhenChanged(stack.ID, handler.StackDeployer, handler.DataStore, handler.GitService); err != nil {
envs := []portainer.Pair{}
for key, value := range r.URL.Query() {
envs = append(envs, portainer.Pair{
Name: key,
Value: value[len(value)-1],
})
}
if err = stacks.RedeployWhenChanged(stack.ID, handler.StackDeployer, handler.DataStore, handler.GitService, envs); err != nil {
if _, ok := err.(*stacks.StackAuthorMissingErr); ok {
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "Autoupdate for the stack isn't available", Err: err}
}

View File

@@ -23,7 +23,7 @@ func (e *StackAuthorMissingErr) Error() string {
// RedeployWhenChanged pull and redeploy the stack when git repo changed
// Stack will always be redeployed if force deployment is set to true
func RedeployWhenChanged(stackID portainer.StackID, deployer StackDeployer, datastore dataservices.DataStore, gitService portainer.GitService) error {
func RedeployWhenChanged(stackID portainer.StackID, deployer StackDeployer, datastore dataservices.DataStore, gitService portainer.GitService, additionalEnv []portainer.Pair) error {
logger := log.WithFields(log.Fields{"stackID": stackID})
logger.Debug("redeploying stack")
@@ -32,6 +32,28 @@ func RedeployWhenChanged(stackID portainer.StackID, deployer StackDeployer, data
return errors.WithMessagef(err, "failed to get the stack %v", stackID)
}
for _, env := range additionalEnv {
exist := false
for index, stackEnv := range stack.Env {
if env.Name == stackEnv.Name {
fmt.Println("found")
stack.Env[index] = portainer.Pair{
Name: env.Name,
Value: env.Value,
}
exist = true
break
}
}
if !exist {
stack.Env = append(stack.Env, portainer.Pair{
Name: env.Name,
Value: env.Value,
})
}
}
if stack.GitConfig == nil {
return nil // do nothing if it isn't a git-based stack
}

View File

@@ -44,7 +44,7 @@ func Test_redeployWhenChanged_FailsWhenCannotFindStack(t *testing.T) {
_, store, teardown := datastore.MustNewTestStore(true, true)
defer teardown()
err := RedeployWhenChanged(1, nil, store, nil)
err := RedeployWhenChanged(1, nil, store, nil, nil)
assert.Error(t, err)
assert.Truef(t, strings.HasPrefix(err.Error(), "failed to get the stack"), "it isn't an error we expected: %v", err.Error())
}
@@ -60,7 +60,7 @@ func Test_redeployWhenChanged_DoesNothingWhenNotAGitBasedStack(t *testing.T) {
err = store.Stack().Create(&portainer.Stack{ID: 1, CreatedBy: "admin"})
assert.NoError(t, err, "failed to create a test stack")
err = RedeployWhenChanged(1, nil, store, &gitService{nil, ""})
err = RedeployWhenChanged(1, nil, store, &gitService{nil, ""}, nil)
assert.NoError(t, err)
}
@@ -85,7 +85,7 @@ func Test_redeployWhenChanged_DoesNothingWhenNoGitChanges(t *testing.T) {
}})
assert.NoError(t, err, "failed to create a test stack")
err = RedeployWhenChanged(1, nil, store, &gitService{nil, "oldHash"})
err = RedeployWhenChanged(1, nil, store, &gitService{nil, "oldHash"}, nil)
assert.NoError(t, err)
}
@@ -108,12 +108,12 @@ func Test_redeployWhenChanged_FailsWhenCannotClone(t *testing.T) {
}})
assert.NoError(t, err, "failed to create a test stack")
err = RedeployWhenChanged(1, nil, store, &gitService{cloneErr, "newHash"})
err = RedeployWhenChanged(1, nil, store, &gitService{cloneErr, "newHash"}, nil)
assert.Error(t, err)
assert.ErrorIs(t, err, cloneErr, "should failed to clone but didn't, check test setup")
}
func Test_redeployWhenChanged(t *testing.T) {
func Test_redeployWhenChanged_WithAdditionalEnv(t *testing.T) {
_, store, teardown := datastore.MustNewTestStore(true, true)
defer teardown()
@@ -139,11 +139,13 @@ func Test_redeployWhenChanged(t *testing.T) {
err = store.Stack().Create(&stack)
assert.NoError(t, err, "failed to create a test stack")
additionalEnvs := []portainer.Pair{{Name: "version", Value: "latest"}}
t.Run("can deploy docker compose stack", func(t *testing.T) {
stack.Type = portainer.DockerComposeStack
store.Stack().UpdateStack(stack.ID, &stack)
err = RedeployWhenChanged(1, &noopDeployer{}, store, &gitService{nil, "newHash"})
err = RedeployWhenChanged(1, &noopDeployer{}, store, &gitService{nil, "newHash"}, additionalEnvs)
assert.NoError(t, err)
})
@@ -151,7 +153,7 @@ func Test_redeployWhenChanged(t *testing.T) {
stack.Type = portainer.DockerSwarmStack
store.Stack().UpdateStack(stack.ID, &stack)
err = RedeployWhenChanged(1, &noopDeployer{}, store, &gitService{nil, "newHash"})
err = RedeployWhenChanged(1, &noopDeployer{}, store, &gitService{nil, "newHash"}, additionalEnvs)
assert.NoError(t, err)
})
@@ -159,7 +161,7 @@ func Test_redeployWhenChanged(t *testing.T) {
stack.Type = portainer.KubernetesStack
store.Stack().UpdateStack(stack.ID, &stack)
err = RedeployWhenChanged(1, &noopDeployer{}, store, &gitService{nil, "newHash"})
err = RedeployWhenChanged(1, &noopDeployer{}, store, &gitService{nil, "newHash"}, additionalEnvs)
assert.NoError(t, err)
})
}

View File

@@ -21,7 +21,7 @@ func StartStackSchedules(scheduler *scheduler.Scheduler, stackdeployer StackDepl
}
stackID := stack.ID // to be captured by the scheduled function
jobID := scheduler.StartJobEvery(d, func() error {
return RedeployWhenChanged(stackID, stackdeployer, datastore, gitService)
return RedeployWhenChanged(stackID, stackdeployer, datastore, gitService, nil)
})
stack.AutoUpdate.JobID = jobID