copy secret without relying on cat being installed in the container
This commit is contained in:
119
cli/app/move.go
119
cli/app/move.go
@ -13,10 +13,9 @@ import (
|
|||||||
"coopcloud.tech/abra/pkg/client"
|
"coopcloud.tech/abra/pkg/client"
|
||||||
containerPkg "coopcloud.tech/abra/pkg/container"
|
containerPkg "coopcloud.tech/abra/pkg/container"
|
||||||
"coopcloud.tech/abra/pkg/log"
|
"coopcloud.tech/abra/pkg/log"
|
||||||
"coopcloud.tech/abra/pkg/upstream/container"
|
"coopcloud.tech/abra/pkg/secret"
|
||||||
"coopcloud.tech/abra/pkg/upstream/convert"
|
"coopcloud.tech/abra/pkg/upstream/convert"
|
||||||
"coopcloud.tech/abra/pkg/upstream/stack"
|
"coopcloud.tech/abra/pkg/upstream/stack"
|
||||||
"github.com/docker/cli/cli/command"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
containertypes "github.com/docker/docker/api/types/container"
|
containertypes "github.com/docker/docker/api/types/container"
|
||||||
"github.com/docker/docker/api/types/filters"
|
"github.com/docker/docker/api/types/filters"
|
||||||
@ -78,15 +77,53 @@ checkout as-is. Recipe commit hashes are also supported as values for
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
dcli, err := command.NewDockerCli()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
secretsToStore := map[string]string{}
|
secretsToStore := map[string]string{}
|
||||||
volumes := map[string]containertypes.MountPoint{}
|
volumes := map[string]containertypes.MountPoint{}
|
||||||
|
|
||||||
|
composeFiles, err := app.Recipe.GetComposeFiles(app.Env)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
filtersSecret, err := app.Filters(false, false)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
secretList, err := cl.SecretList(context.Background(), types.SecretListOptions{Filters: filtersSecret})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
secretConfigs, err := secret.ReadSecretsConfig(app.Path, composeFiles, app.StackName())
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
opts := stack.Deploy{Composefiles: composeFiles, Namespace: app.StackName()}
|
||||||
|
compose, err := appPkg.GetAppComposeConfig(app.Name, opts, app.Env)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
for _, s := range services {
|
for _, s := range services {
|
||||||
log.Info("service", s.Spec.Name)
|
log.Info("service", s.Spec.Name)
|
||||||
// stackAndServiceName := fmt.Sprintf("^%s_%s", app.StackName(), s.Spec.Name)
|
|
||||||
|
secretNames := map[string]string{}
|
||||||
|
for _, serviceCompose := range compose.Services {
|
||||||
|
if app.StackName()+"_"+serviceCompose.Name != s.Spec.Name {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, secret := range serviceCompose.Secrets {
|
||||||
|
for _, s := range secretList {
|
||||||
|
if s.Spec.Name == app.StackName()+"_"+secret.Source+"_"+secretConfigs[secret.Source].Version {
|
||||||
|
secretNames[secret.Source] = s.ID
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
f := filters.NewArgs()
|
f := filters.NewArgs()
|
||||||
f.Add("name", s.Spec.Name)
|
f.Add("name", s.Spec.Name)
|
||||||
targetContainer, err := containerPkg.GetContainer(context.Background(), cl, f, true)
|
targetContainer, err := containerPkg.GetContainer(context.Background(), cl, f, true)
|
||||||
@ -100,51 +137,27 @@ checkout as-is. Recipe commit hashes are also supported as values for
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
execCreateOpts := containertypes.ExecOptions{
|
for secretName, secretID := range secretNames {
|
||||||
AttachStderr: false,
|
if _, ok := secretsToStore[secretName]; ok {
|
||||||
AttachStdin: false,
|
|
||||||
AttachStdout: true,
|
|
||||||
Cmd: []string{"ls", "/run/secrets"},
|
|
||||||
Detach: false,
|
|
||||||
Tty: false,
|
|
||||||
}
|
|
||||||
out, err := container.RunExec(dcli, cl, targetContainer.ID, &execCreateOpts, false)
|
|
||||||
if err != nil {
|
|
||||||
log.Error(out)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
for _, secret := range strings.Split(strings.TrimSpace(out), "\n") {
|
|
||||||
if _, ok := secretsToStore[secret]; ok {
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
log.Debugf("extracting secret %s", secret)
|
log.Debugf("extracting secret %s", secretName)
|
||||||
|
|
||||||
execCreateOpts := containertypes.ExecOptions{
|
out, err := exec.Command("ssh", app.Server, "-tt", fmt.Sprintf("sudo cat /var/lib/docker/containers/%s/mounts/secrets/%s", targetContainer.ID, secretID)).Output()
|
||||||
AttachStderr: false,
|
|
||||||
AttachStdin: false,
|
|
||||||
AttachStdout: true,
|
|
||||||
Cmd: []string{"cat", fmt.Sprintf("/run/secrets/%s", secret)},
|
|
||||||
Detach: false,
|
|
||||||
Tty: false,
|
|
||||||
}
|
|
||||||
out, err := container.RunExec(dcli, cl, targetContainer.ID, &execCreateOpts, false)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
fmt.Println(string(out))
|
||||||
|
fmt.Println(err)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
secretsToStore[secret] = out
|
secretsToStore[secretName] = string(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
composeFiles, err := app.Recipe.GetComposeFiles(app.Env)
|
if internal.Dry {
|
||||||
if err != nil {
|
fmt.Println(secretsToStore)
|
||||||
log.Fatal(err)
|
fmt.Println(volumes)
|
||||||
}
|
return nil
|
||||||
|
|
||||||
opts := stack.Deploy{Composefiles: composeFiles, Namespace: app.StackName()}
|
|
||||||
compose, err := appPkg.GetAppComposeConfig(app.Name, opts, app.Env)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
}
|
||||||
stack.WaitTimeout, err = appPkg.GetTimeoutFromLabel(compose, app.StackName())
|
stack.WaitTimeout, err = appPkg.GetTimeoutFromLabel(compose, app.StackName())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -162,19 +175,10 @@ checkout as-is. Recipe commit hashes are also supported as values for
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
filters, err := app.Filters(false, false)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
secretList, err := cl.SecretList(context.Background(), types.SecretListOptions{Filters: filters})
|
|
||||||
for _, s := range secretList {
|
for _, s := range secretList {
|
||||||
sname := strings.Split(strings.TrimPrefix(s.Spec.Name, app.StackName()+"_"), "_")
|
sname := strings.Split(strings.TrimPrefix(s.Spec.Name, app.StackName()+"_"), "_")
|
||||||
secretName := strings.Join(sname[:len(sname)-1], "_")
|
secretName := strings.Join(sname[:len(sname)-1], "_")
|
||||||
data := secretsToStore[secretName]
|
data := secretsToStore[secretName]
|
||||||
fmt.Println(s.Spec.Name)
|
|
||||||
fmt.Println(secretName)
|
|
||||||
fmt.Println(data)
|
|
||||||
if err := client.StoreSecret(cl2, s.Spec.Name, data); err != nil {
|
if err := client.StoreSecret(cl2, s.Spec.Name, data); err != nil {
|
||||||
log.Info(err)
|
log.Info(err)
|
||||||
}
|
}
|
||||||
@ -220,7 +224,6 @@ checkout as-is. Recipe commit hashes are also supported as values for
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println(strings.ReplaceAll(app.Path, app.Server, args[1]))
|
|
||||||
if err := copyFile(app.Path, strings.ReplaceAll(app.Path, app.Server, args[1])); err != nil {
|
if err := copyFile(app.Path, strings.ReplaceAll(app.Path, app.Server, args[1])); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -290,3 +293,13 @@ func copyFile(src string, dst string) error {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
AppMoveCommand.Flags().BoolVarP(
|
||||||
|
&internal.Dry,
|
||||||
|
"dry-run",
|
||||||
|
"r",
|
||||||
|
false,
|
||||||
|
"report changes that would be made",
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user