Skip to content

Commit

Permalink
feat: allow customization on the rsync+ssh destination ip (#157)
Browse files Browse the repository at this point in the history
* feat: add custom annotations and loadBalancerIP support to sshd service

Signed-off-by: Utku Ozdemir <[email protected]>

* feat: add --dest-host-override flag to allow overriding rsync sshd target host

Signed-off-by: Utku Ozdemir <[email protected]>

* feat: set --dest-host-override shorthand to H

Signed-off-by: Utku Ozdemir <[email protected]>

* test: add integration test for --dest-host-override

Signed-off-by: Utku Ozdemir <[email protected]>
  • Loading branch information
utkuozdemir authored Mar 6, 2022
1 parent 62be3de commit 958e2d8
Show file tree
Hide file tree
Showing 14 changed files with 115 additions and 33 deletions.
7 changes: 4 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,12 @@ That's it.
## Editing the helm chart
The `pv-migrate` helm chart is located at `helm/pv-migrate`. It is inserted into the go code during build. The source is a helm package located in `internal/migrator/pv-migrate-X.Y.Z.tgz`.

If you want to tweak the helm chart, you must run the following command before recompiling the code in order
to update the chart:
If you want to tweak the helm chart, you must run the following commands before recompiling the code in order
to update the chart (you need [helm-docs](https://github.com/norwoodj/helm-docs) installed):
```bash
helm-docs -c helm/pv-migrate/
helm package helm/pv-migrate/
mv pv-migrate-X.Y.Z.tgz internal/migrator
mv pv-migrate-*.tgz internal/migrator/helm-chart.tgz
```

When you change the helm chart, in order to release a new version, don't forget to:
Expand Down
4 changes: 2 additions & 2 deletions helm/pv-migrate/Chart.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ apiVersion: v2
name: pv-migrate
description: The helm chart of pv-migrate
type: application
version: 0.2.2
appVersion: 0.2.2
version: 0.2.3
appVersion: 0.2.3
home: https://github.com/utkuozdemir/pv-migrate
keywords:
- pv-migrate
Expand Down
8 changes: 5 additions & 3 deletions helm/pv-migrate/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# pv-migrate

![Version: 0.2.1](https://img.shields.io/badge/Version-0.2.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.2.1](https://img.shields.io/badge/AppVersion-0.2.1-informational?style=flat-square)
![Version: 0.2.3](https://img.shields.io/badge/Version-0.2.3-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.2.3](https://img.shields.io/badge/AppVersion-0.2.3-informational?style=flat-square)

The helm chart of pv-migrate

Expand Down Expand Up @@ -65,7 +65,9 @@ The helm chart of pv-migrate
| sshd.publicKeyMountPath | string | `"/root/.ssh/authorized_keys"` | The path to mount the public key |
| sshd.pvcMounts | list | `[]` | PVC mounts into the SSHD pod. For examples, see see [values.yaml](values.yaml) |
| sshd.resources | object | `{}` | SSHD pod resources |
| sshd.securityContext | object | `{}` | SSHD deployment security context |
| sshd.securityContext | object | `{"capabilities":{"add":["CAP_SYS_CHROOT"]}}` | SSHD deployment security context |
| sshd.service.annotations | object | `{}` | SSHD service annotations |
| sshd.service.loadBalancerIP | string | `""` | SSHD service load balancer IP |
| sshd.service.port | int | `22` | SSHD service port |
| sshd.service.type | string | `"ClusterIP"` | SSHD service type |
| sshd.serviceAccount.annotations | object | `{}` | SSHD service account annotations |
Expand All @@ -74,4 +76,4 @@ The helm chart of pv-migrate
| sshd.tolerations | list | see [values.yaml](values.yaml) | SSHD pod tolerations |

----------------------------------------------
Autogenerated from chart metadata using [helm-docs v1.5.0](https://github.com/norwoodj/helm-docs/releases/v1.5.0)
Autogenerated from chart metadata using [helm-docs v1.7.0](https://github.com/norwoodj/helm-docs/releases/v1.7.0)
7 changes: 7 additions & 0 deletions helm/pv-migrate/templates/sshd/service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,15 @@ metadata:
labels:
app.kubernetes.io/component: sshd
{{- include "pv-migrate.labels" . | nindent 4 }}
{{- with .Values.sshd.service.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
type: {{ .Values.sshd.service.type }}
{{- with .Values.sshd.service.loadBalancerIP }}
loadBalancerIP: {{ . }}
{{- end }}
ports:
- port: {{ .Values.sshd.service.port }}
targetPort: 22
Expand Down
4 changes: 4 additions & 0 deletions helm/pv-migrate/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ sshd:
type: ClusterIP
# -- SSHD service port
port: 22
# -- SSHD service annotations
annotations: {}
# -- SSHD service load balancer IP
loadBalancerIP: ""
# -- SSHD pod resources
resources: {}
# -- The node name to schedule SSHD pod on
Expand Down
16 changes: 12 additions & 4 deletions internal/app/migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ const (
FlagSourceNamespace = "source-namespace"
FlagSourcePath = "source-path"

FlagDestKubeconfig = "dest-kubeconfig"
FlagDestContext = "dest-context"
FlagDestNamespace = "dest-namespace"
FlagDestPath = "dest-path"
FlagDestKubeconfig = "dest-kubeconfig"
FlagDestContext = "dest-context"
FlagDestNamespace = "dest-namespace"
FlagDestPath = "dest-path"
FlagDestHostOverride = "dest-host-override"

FlagDestDeleteExtraneousFiles = "dest-delete-extraneous-files"
FlagIgnoreMounted = "ignore-mounted"
Expand Down Expand Up @@ -72,6 +73,7 @@ func buildMigrateCmd() *cobra.Command {
helmSetString, _ := f.GetStringSlice(FlagHelmSetString)
helmSetFile, _ := f.GetStringSlice(FlagHelmSetFile)
strs, _ := f.GetStringSlice(FlagStrategies)
destHostOverride, _ := f.GetString(FlagDestHostOverride)

deleteExtraneousFiles, _ := f.GetBool(FlagDestDeleteExtraneousFiles)
m := migration.Request{
Expand Down Expand Up @@ -100,6 +102,7 @@ func buildMigrateCmd() *cobra.Command {
HelmStringValues: helmSetString,
HelmFileValues: helmSetFile,
Strategies: strs,
DestHostOverride: destHostOverride,
Logger: logger,
}

Expand Down Expand Up @@ -132,6 +135,11 @@ func buildMigrateCmd() *cobra.Command {
f.BoolP(FlagSourceMountReadOnly, "R", true, "mount the source PVC in ReadOnly mode")
f.StringSliceP(FlagStrategies, "s", strategy.DefaultStrategies, "the comma-separated list of strategies to be used in the given order")
f.StringP(FlagSSHKeyAlgorithm, "a", ssh.Ed25519KeyAlgorithm, fmt.Sprintf("ssh key algorithm to be used. Valid values are %s", strings.Join(ssh.KeyAlgorithms, ",")))
f.StringP(FlagDestHostOverride, "H", "",
"the override for the rsync host destination when it is run over SSH, "+
"in cases when you need to target a different destination IP on rsync for some reason. "+
"By default, it is determined by used strategy and differs across strategies. "+
"Has no effect for mnt2 and local strategies")

f.StringSliceP(FlagHelmValues, "f", nil, "set additional Helm values by a YAML file or a URL (can specify multiple)")
f.StringSlice(FlagHelmSet, nil, "set additional Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2)")
Expand Down
53 changes: 53 additions & 0 deletions internal/integrationtest/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"testing"
"time"

"k8s.io/apimachinery/pkg/util/intstr"

"github.com/hashicorp/go-multierror"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -222,6 +224,57 @@ func TestDifferentNS(t *testing.T) {
assert.NoError(t, err)
}

func TestLbSvcDestHostOverride(t *testing.T) {
assert.NoError(t, clearDests())

svcName := "alternative-svc"
_, err := mainClusterCli.KubeClient.CoreV1().Services(ns1).Create(context.Background(),
&corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: svcName,
},
Spec: corev1.ServiceSpec{
Selector: map[string]string{
"app.kubernetes.io/component": "sshd",
"app.kubernetes.io/name": "pv-migrate",
},
Ports: []corev1.ServicePort{
{
Name: "ssh",
Port: 22,
TargetPort: intstr.FromInt(22),
},
},
},
}, metav1.CreateOptions{})
assert.NoError(t, err)

_, err = execInPod(mainClusterCli, ns2, "dest", generateExtraDataShellCommand)
assert.NoError(t, err)

destHostOverride := svcName + "." + ns1
cmd := fmt.Sprintf(
"--log-level debug --log-format json m -i -n %s -N %s -H %s source dest",
ns1, ns2, destHostOverride)
assert.NoError(t, runCliApp(cmd))

stdout, err := execInPod(mainClusterCli, ns2, "dest", printDataUidGidContentShellCommand)
assert.NoError(t, err)

parts := strings.Split(stdout, "\n")
assert.Equal(t, len(parts), 3)
if len(parts) < 3 {
return
}

assert.Equal(t, dataFileUid, parts[0])
assert.Equal(t, dataFileGid, parts[1])
assert.Equal(t, generateDataContent, parts[2])

_, err = execInPod(mainClusterCli, ns2, "dest", checkExtraDataShellCommand)
assert.NoError(t, err)
}

func TestRSA(t *testing.T) {
assert.NoError(t, clearDests())

Expand Down
Binary file added internal/migrator/helm-chart.tgz
Binary file not shown.
2 changes: 1 addition & 1 deletion internal/migrator/migrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
"helm.sh/helm/v3/pkg/chart/loader"
)

//go:embed pv-migrate-0.2.2.tgz
//go:embed helm-chart.tgz
var chartBytes []byte

type (
Expand Down
Binary file removed internal/migrator/pv-migrate-0.2.2.tgz
Binary file not shown.
13 changes: 8 additions & 5 deletions internal/strategy/lbsvc.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ import (
type LbSvc struct{}

func (r *LbSvc) Run(a *migration.Attempt) (bool, error) {
t := a.Migration
m := a.Migration

s := t.SourceInfo
d := t.DestInfo
s := m.SourceInfo
d := m.DestInfo
sourceNs := s.Claim.Namespace
destNs := d.Claim.Namespace

t.Logger.Info(":key: Generating SSH key pair")
keyAlgorithm := t.Request.KeyAlgorithm
m.Logger.Info(":key: Generating SSH key pair")
keyAlgorithm := m.Request.KeyAlgorithm
publicKey, privateKey, err := ssh.CreateSSHKeyPair(keyAlgorithm)
if err != nil {
return true, err
Expand Down Expand Up @@ -51,6 +51,9 @@ func (r *LbSvc) Run(a *migration.Attempt) (bool, error) {
}

sshTargetHost := formatSSHTargetHost(lbSvcAddress)
if m.Request.DestHostOverride != "" {
sshTargetHost = m.Request.DestHostOverride
}

err = installOnDest(a, destReleaseName, privateKey, privateKeyMountPath,
sshTargetHost, srcMountPath, destMountPath)
Expand Down
26 changes: 13 additions & 13 deletions internal/strategy/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ func (r *Local) Run(a *migration.Attempt) (bool, error) {
return false, fmt.Errorf(":cross_mark: Error: binary not found in path: %s", "ssh")
}

t := a.Migration
s := t.SourceInfo
d := t.DestInfo
m := a.Migration
s := m.SourceInfo
d := m.DestInfo

t.Logger.Info(":key: Generating SSH key pair")
keyAlgorithm := t.Request.KeyAlgorithm
m.Logger.Info(":key: Generating SSH key pair")
keyAlgorithm := m.Request.KeyAlgorithm
publicKey, privateKey, err := ssh.CreateSSHKeyPair(keyAlgorithm)
if err != nil {
return true, err
Expand Down Expand Up @@ -74,7 +74,7 @@ func (r *Local) Run(a *migration.Attempt) (bool, error) {
return true, err
}

srcFwdPort, srcStopChan, err := portForwardForPod(t.Logger, s.ClusterClient.RestConfig,
srcFwdPort, srcStopChan, err := portForwardForPod(m.Logger, s.ClusterClient.RestConfig,
sourceSshdPod.Namespace, sourceSshdPod.Name)
if err != nil {
return true, err
Expand All @@ -86,7 +86,7 @@ func (r *Local) Run(a *migration.Attempt) (bool, error) {
return true, err
}

destFwdPort, destStopChan, err := portForwardForPod(t.Logger, d.ClusterClient.RestConfig,
destFwdPort, destStopChan, err := portForwardForPod(m.Logger, d.ClusterClient.RestConfig,
destSshdPod.Namespace, destSshdPod.Name)
if err != nil {
return true, err
Expand All @@ -101,13 +101,13 @@ func (r *Local) Run(a *migration.Attempt) (bool, error) {
return true, err
}

srcPath := srcMountPath + "/" + t.Request.Source.Path
destPath := destMountPath + "/" + t.Request.Dest.Path
srcPath := srcMountPath + "/" + m.Request.Source.Path
destPath := destMountPath + "/" + m.Request.Dest.Path

rsyncCmd := rsync.Cmd{
Port: sshReverseTunnelPort,
NoChown: t.Request.NoChown,
Delete: t.Request.DeleteExtraneousFiles,
NoChown: m.Request.NoChown,
Delete: m.Request.DeleteExtraneousFiles,
SrcPath: srcPath,
DestPath: destPath,
DestUseSsh: true,
Expand All @@ -133,14 +133,14 @@ func (r *Local) Run(a *migration.Attempt) (bool, error) {
go func() { errorCh <- cmd.Run() }()

showProgressBar := !a.Migration.Request.NoProgressBar &&
t.Logger.Context.Value(applog.FormatContextKey) == applog.FormatFancy
m.Logger.Context.Value(applog.FormatContextKey) == applog.FormatFancy
successCh := make(chan bool, 1)

logTail := rsync.LogTail{
LogReaderFunc: func() (io.ReadCloser, error) { return reader, nil },
SuccessCh: successCh,
ShowProgressBar: showProgressBar,
Logger: t.Logger,
Logger: m.Logger,
}

go logTail.Start()
Expand Down
7 changes: 5 additions & 2 deletions internal/strategy/svc.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ func (r *Svc) Run(a *migration.Attempt) (bool, error) {
releaseName := a.HelmReleaseNamePrefix
releaseNames := []string{releaseName}

sshRemoteHost := releaseName + "-sshd." + sourceNs
sshTargetHost := releaseName + "-sshd." + sourceNs
if m.Request.DestHostOverride != "" {
sshTargetHost = m.Request.DestHostOverride
}

srcMountPath := "/source"
destMountPath := "/dest"
Expand All @@ -51,7 +54,7 @@ func (r *Svc) Run(a *migration.Attempt) (bool, error) {
SrcPath: srcPath,
DestPath: destPath,
SrcUseSsh: true,
SrcSshHost: sshRemoteHost,
SrcSshHost: sshTargetHost,
}
rsyncCmdStr, err := rsyncCmd.Build()
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions migration/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type Request struct {
HelmStringValues []string
Strategies []string
Logger *log.Entry
DestHostOverride string
}

type Migration struct {
Expand Down

0 comments on commit 958e2d8

Please sign in to comment.