parent
dc5d3a8dd6
commit
8078e91e52
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
"coopcloud.tech/abra/cli/internal"
|
"coopcloud.tech/abra/cli/internal"
|
||||||
"coopcloud.tech/abra/pkg/autocomplete"
|
"coopcloud.tech/abra/pkg/autocomplete"
|
||||||
|
"coopcloud.tech/abra/pkg/secret"
|
||||||
|
|
||||||
"coopcloud.tech/abra/pkg/client"
|
"coopcloud.tech/abra/pkg/client"
|
||||||
"coopcloud.tech/abra/pkg/config"
|
"coopcloud.tech/abra/pkg/config"
|
||||||
|
@ -91,6 +92,17 @@ recipes.
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
secStats, err := secret.PollSecretsStatus(cl, app)
|
||||||
|
if err != nil {
|
||||||
|
logrus.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, secStat := range secStats {
|
||||||
|
if !secStat.CreatedOnRemote {
|
||||||
|
logrus.Fatalf("unable to deploy, secrets not generated (%s)?", secStat.LocalName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if isDeployed {
|
if isDeployed {
|
||||||
if internal.Force || internal.Chaos {
|
if internal.Force || internal.Chaos {
|
||||||
logrus.Warnf("%s is already deployed but continuing (--force/--chaos)", app.Name)
|
logrus.Warnf("%s is already deployed but continuing (--force/--chaos)", app.Name)
|
||||||
|
|
|
@ -383,12 +383,7 @@ var appSecretLsCommand = cli.Command{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
composeFiles, err := config.GetComposeFiles(app.Recipe, app.Env)
|
cl, err := client.New(app.Server)
|
||||||
if err != nil {
|
|
||||||
logrus.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
secretsConfig, err := secret.ReadSecretsConfig(app.Env, composeFiles, app.Recipe)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -396,37 +391,18 @@ var appSecretLsCommand = cli.Command{
|
||||||
tableCol := []string{"Name", "Version", "Generated Name", "Created On Server"}
|
tableCol := []string{"Name", "Version", "Generated Name", "Created On Server"}
|
||||||
table := formatter.CreateTable(tableCol)
|
table := formatter.CreateTable(tableCol)
|
||||||
|
|
||||||
cl, err := client.New(app.Server)
|
secStats, err := secret.PollSecretsStatus(cl, app)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.Fatal(err)
|
logrus.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
filters, err := app.Filters(false, false)
|
for _, secStat := range secStats {
|
||||||
if err != nil {
|
tableRow := []string{
|
||||||
logrus.Fatal(err)
|
secStat.LocalName,
|
||||||
|
secStat.Version,
|
||||||
|
secStat.RemoteName,
|
||||||
|
strconv.FormatBool(secStat.CreatedOnRemote),
|
||||||
}
|
}
|
||||||
|
|
||||||
secretList, err := cl.SecretList(context.Background(), types.SecretListOptions{Filters: filters})
|
|
||||||
if err != nil {
|
|
||||||
logrus.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
remoteSecretNames := make(map[string]bool)
|
|
||||||
for _, cont := range secretList {
|
|
||||||
remoteSecretNames[cont.Spec.Annotations.Name] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
for secretName, secretValue := range secretsConfig {
|
|
||||||
createdRemote := false
|
|
||||||
val, err := secret.ParseSecretValue(secretValue)
|
|
||||||
if err != nil {
|
|
||||||
logrus.Fatal(err)
|
|
||||||
}
|
|
||||||
secretRemoteName := fmt.Sprintf("%s_%s_%s", app.StackName(), secretName, val.Version)
|
|
||||||
if _, ok := remoteSecretNames[secretRemoteName]; ok {
|
|
||||||
createdRemote = true
|
|
||||||
}
|
|
||||||
tableRow := []string{secretName, val.Version, secretRemoteName, strconv.FormatBool(createdRemote)}
|
|
||||||
table.Append(tableRow)
|
table.Append(tableRow)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
package secret
|
package secret
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -11,9 +12,11 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"coopcloud.tech/abra/pkg/client"
|
"coopcloud.tech/abra/pkg/client"
|
||||||
|
"coopcloud.tech/abra/pkg/config"
|
||||||
"coopcloud.tech/abra/pkg/upstream/stack"
|
"coopcloud.tech/abra/pkg/upstream/stack"
|
||||||
loader "coopcloud.tech/abra/pkg/upstream/stack"
|
loader "coopcloud.tech/abra/pkg/upstream/stack"
|
||||||
"github.com/decentral1se/passgen"
|
"github.com/decentral1se/passgen"
|
||||||
|
"github.com/docker/docker/api/types"
|
||||||
dockerClient "github.com/docker/docker/client"
|
dockerClient "github.com/docker/docker/client"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
@ -209,3 +212,66 @@ func GenerateSecrets(cl *dockerClient.Client, secretsFromConfig map[string]strin
|
||||||
|
|
||||||
return secrets, nil
|
return secrets, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type secretStatus struct {
|
||||||
|
LocalName string
|
||||||
|
RemoteName string
|
||||||
|
Version string
|
||||||
|
CreatedOnRemote bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type secretStatuses []secretStatus
|
||||||
|
|
||||||
|
// PollSecretsStatus checks status of secrets by comparing the local recipe
|
||||||
|
// config and deploymend server state.
|
||||||
|
func PollSecretsStatus(cl *dockerClient.Client, app config.App) (secretStatuses, error) {
|
||||||
|
var secStats secretStatuses
|
||||||
|
|
||||||
|
composeFiles, err := config.GetComposeFiles(app.Recipe, app.Env)
|
||||||
|
if err != nil {
|
||||||
|
return secStats, err
|
||||||
|
}
|
||||||
|
|
||||||
|
secretsConfig, err := ReadSecretsConfig(app.Env, composeFiles, app.Recipe)
|
||||||
|
if err != nil {
|
||||||
|
return secStats, err
|
||||||
|
}
|
||||||
|
|
||||||
|
filters, err := app.Filters(false, false)
|
||||||
|
if err != nil {
|
||||||
|
return secStats, err
|
||||||
|
}
|
||||||
|
|
||||||
|
secretList, err := cl.SecretList(context.Background(), types.SecretListOptions{Filters: filters})
|
||||||
|
if err != nil {
|
||||||
|
return secStats, err
|
||||||
|
}
|
||||||
|
|
||||||
|
remoteSecretNames := make(map[string]bool)
|
||||||
|
for _, cont := range secretList {
|
||||||
|
remoteSecretNames[cont.Spec.Annotations.Name] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
for secretName, secretValue := range secretsConfig {
|
||||||
|
createdRemote := false
|
||||||
|
|
||||||
|
val, err := ParseSecretValue(secretValue)
|
||||||
|
if err != nil {
|
||||||
|
return secStats, err
|
||||||
|
}
|
||||||
|
|
||||||
|
secretRemoteName := fmt.Sprintf("%s_%s_%s", app.StackName(), secretName, val.Version)
|
||||||
|
if _, ok := remoteSecretNames[secretRemoteName]; ok {
|
||||||
|
createdRemote = true
|
||||||
|
}
|
||||||
|
|
||||||
|
secStats = append(secStats, secretStatus{
|
||||||
|
LocalName: secretName,
|
||||||
|
RemoteName: secretRemoteName,
|
||||||
|
Version: val.Version,
|
||||||
|
CreatedOnRemote: createdRemote,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return secStats, nil
|
||||||
|
}
|
||||||
|
|
|
@ -328,3 +328,19 @@ teardown(){
|
||||||
_undeploy_app
|
_undeploy_app
|
||||||
_reset_app
|
_reset_app
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@test "error if no secrets generated" {
|
||||||
|
run sed -i 's/COMPOSE_FILE="compose.yml"/COMPOSE_FILE="compose.yml:compose.extra_secret.yml"/g' \
|
||||||
|
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run sed -i 's/#SECRET_EXTRA_PASS_VERSION=v1/SECRET_EXTRA_PASS_VERSION=v1/g' \
|
||||||
|
"$ABRA_DIR/servers/$TEST_SERVER/$TEST_APP_DOMAIN.env"
|
||||||
|
assert_success
|
||||||
|
|
||||||
|
run $ABRA app deploy "$TEST_APP_DOMAIN" --no-input --no-converge-checks
|
||||||
|
assert_failure
|
||||||
|
assert_output --partial 'unable to deploy, secrets not generated'
|
||||||
|
|
||||||
|
_reset_app
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue