Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kubectl volsync rsync tls #1238

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
60 changes: 40 additions & 20 deletions custom-scorecard-tests/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,26 +75,6 @@ stages:
storage:
spec:
mountPath: {}
- entrypoint:
- volsync-custom-scorecard-tests
- test_replication_sched_snap.yml
image: quay.io/backube/volsync-custom-scorecard-tests:latest
labels:
suite: volsync-e2e
test: test_replication_sched_snap.yml
storage:
spec:
mountPath: {}
- entrypoint:
- volsync-custom-scorecard-tests
- test_replication_sync_direct.yml
image: quay.io/backube/volsync-custom-scorecard-tests:latest
labels:
suite: volsync-e2e
test: test_replication_sync_direct.yml
storage:
spec:
mountPath: {}
- entrypoint:
- volsync-custom-scorecard-tests
- test_restic_manual_normal.yml
Expand Down Expand Up @@ -257,6 +237,46 @@ stages:
storage:
spec:
mountPath: {}
- entrypoint:
- volsync-custom-scorecard-tests
- test_replication_sched_snap.yml
image: quay.io/backube/volsync-custom-scorecard-tests:latest
labels:
suite: volsync-e2e
test: test_replication_sched_snap.yml
storage:
spec:
mountPath: {}
- entrypoint:
- volsync-custom-scorecard-tests
- test_replication_sync_direct.yml
image: quay.io/backube/volsync-custom-scorecard-tests:latest
labels:
suite: volsync-e2e
test: test_replication_sync_direct.yml
storage:
spec:
mountPath: {}
- entrypoint:
- volsync-custom-scorecard-tests
- test_replication_sync_direct_tls_normal.yml
image: quay.io/backube/volsync-custom-scorecard-tests:latest
labels:
suite: volsync-e2e
test: test_replication_sync_direct_tls_normal.yml
storage:
spec:
mountPath: {}
- entrypoint:
- volsync-custom-scorecard-tests
- test_replication_sync_direct_tls_priv.yml
image: quay.io/backube/volsync-custom-scorecard-tests:latest
labels:
suite: volsync-e2e
test: test_replication_sync_direct_tls_priv.yml
storage:
spec:
mountPath: {}
- entrypoint:
- volsync-custom-scorecard-tests
- test_roles.yml
Expand Down
6 changes: 4 additions & 2 deletions custom-scorecard-tests/generateE2ETestsConfig.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ TESTS=$(echo "${TESTS_UNSORTED}" | LC_ALL=C sort)

# Group tests into 2 stages (each stage gets run sequentially but
# all tests in a stage can run in parallel)
E2E_TESTS_GROUP1=$(echo "${TESTS}" | grep -v -e role -e syncthing)
E2E_TESTS_GROUP2=$(echo "${TESTS}" | grep -e role -e syncthing)
# Group1 contains most e2e tests
# Group2 contains syncthing tests, cli tests and role tests
E2E_TESTS_GROUP1=$(echo "${TESTS}" | grep -v -e role -e syncthing -e test_replication_ )
E2E_TESTS_GROUP2=$(echo "${TESTS}" | grep -e role -e syncthing -e test_replication_ )

echo "####################"
echo "# E2E test list is: "
Expand Down
20 changes: 0 additions & 20 deletions custom-scorecard-tests/scorecard/patches/e2e-tests-stage1.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,26 +61,6 @@
storage:
spec:
mountPath: {}
- entrypoint:
- volsync-custom-scorecard-tests
- test_replication_sched_snap.yml
image: quay.io/backube/volsync-custom-scorecard-tests:latest
labels:
suite: volsync-e2e
test: test_replication_sched_snap.yml
storage:
spec:
mountPath: {}
- entrypoint:
- volsync-custom-scorecard-tests
- test_replication_sync_direct.yml
image: quay.io/backube/volsync-custom-scorecard-tests:latest
labels:
suite: volsync-e2e
test: test_replication_sync_direct.yml
storage:
spec:
mountPath: {}
- entrypoint:
- volsync-custom-scorecard-tests
- test_restic_manual_normal.yml
Expand Down
40 changes: 40 additions & 0 deletions custom-scorecard-tests/scorecard/patches/e2e-tests-stage2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,46 @@
storage:
spec:
mountPath: {}
- entrypoint:
- volsync-custom-scorecard-tests
- test_replication_sched_snap.yml
image: quay.io/backube/volsync-custom-scorecard-tests:latest
labels:
suite: volsync-e2e
test: test_replication_sched_snap.yml
storage:
spec:
mountPath: {}
- entrypoint:
- volsync-custom-scorecard-tests
- test_replication_sync_direct.yml
image: quay.io/backube/volsync-custom-scorecard-tests:latest
labels:
suite: volsync-e2e
test: test_replication_sync_direct.yml
storage:
spec:
mountPath: {}
- entrypoint:
- volsync-custom-scorecard-tests
- test_replication_sync_direct_tls_normal.yml
image: quay.io/backube/volsync-custom-scorecard-tests:latest
labels:
suite: volsync-e2e
test: test_replication_sync_direct_tls_normal.yml
storage:
spec:
mountPath: {}
- entrypoint:
- volsync-custom-scorecard-tests
- test_replication_sync_direct_tls_priv.yml
image: quay.io/backube/volsync-custom-scorecard-tests:latest
labels:
suite: volsync-e2e
test: test_replication_sync_direct_tls_priv.yml
storage:
spec:
mountPath: {}
- entrypoint:
- volsync-custom-scorecard-tests
- test_roles.yml
Expand Down
144 changes: 80 additions & 64 deletions kubectl-volsync/cmd/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,11 @@ package cmd
import (
"context"
"fmt"
"time"

"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/klog/v2"
corev1 "k8s.io/api/core/v1"
"k8s.io/component-base/logs"
"k8s.io/kubectl/pkg/util/i18n"
"k8s.io/kubectl/pkg/util/templates"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand All @@ -36,20 +34,43 @@ import (
// MigrationRelationship defines the "type" of migration Relationships
const MigrationRelationshipType RelationshipType = "migration"

const (
defaultLocalStunnelPort = 9000
defaultDestinationStunnelPort = 8000
)

// migrationRelationship holds the config state for migration-type
// relationships
type migrationRelationship struct {
Relationship
data *migrationRelationshipData
data *migrationRelationshipDataV2
mh migrationHandler
}

// migrationRelationshipData is the state that will be saved to the
// relationship config file
type migrationHandler interface {
EnsureReplicationDestination(ctx context.Context, c client.Client,
destConfig *migrationRelationshipDestinationV2) (*volsyncv1alpha1.ReplicationDestination, error)
WaitForRDStatus(ctx context.Context, c client.Client,
replicationDestination *volsyncv1alpha1.ReplicationDestination) (*volsyncv1alpha1.ReplicationDestination, error)
RunMigration(ctx context.Context, c client.Client, source string, destConfig *migrationRelationshipDestinationV2,
sTunnelLocalPort int32) error
}

// Old v1 version of the data
type migrationRelationshipData struct {
Version int
Destination *migrationRelationshipDestination
}

// migrationRelationshipData is the state that will be saved to the
// relationship config file
type migrationRelationshipDataV2 struct {
Version int
// True if the ReplicationDestination should use RsyncTLS
IsRsyncTLS bool
Destination *migrationRelationshipDestinationV2
}

type migrationRelationshipDestination struct {
// Cluster context name
Cluster string
Expand All @@ -65,20 +86,50 @@ type migrationRelationshipDestination struct {
Destination volsyncv1alpha1.ReplicationDestinationRsyncSpec
}

type migrationRelationshipDestinationV2 struct {
// Cluster context name
Cluster string
// Namespace on destination cluster
Namespace string
// Name of PVC being replicated
PVCName string
// Name of the ReplicationDestination object
RDName string
// Name of Secret holding ssh or psk secret
//RsyncSecretName string //TODO: is this necessary? doesn't seem to get written to conf file in ~/.volsync
// Service Type for the ReplicationDestination
ServiceType *corev1.ServiceType
// Copy Method for the ReplicationDestination (will always be Direct for migration)
CopyMethod volsyncv1alpha1.CopyMethodType
// MoverSecurityContext allows specifying the PodSecurityContext that will
// be used by the data mover
MoverSecurityContext *corev1.PodSecurityContext
}

func (mr *migrationRelationship) Save() error {
err := mr.SetData(mr.data)
if err != nil {
return err
}

if mr.data.Destination != nil && mr.data.Destination.Destination.Capacity != nil {
mr.Set("data.destination.destination.replicationdestinationvolumeoptions.capacity",
mr.data.Destination.Destination.Capacity.String())
}

return mr.Relationship.Save()
}

func (mr *migrationRelationship) convertDataToV2(datav1 *migrationRelationshipData) {
mr.data = &migrationRelationshipDataV2{
Version: 2,
IsRsyncTLS: false, // Rsync TLS support wasn't there in v1
Destination: &migrationRelationshipDestinationV2{
RDName: datav1.Destination.RDName,
PVCName: datav1.Destination.PVCName,
Namespace: datav1.Destination.Namespace,
Cluster: datav1.Destination.Cluster,
ServiceType: datav1.Destination.Destination.ServiceType,
CopyMethod: volsyncv1alpha1.CopyMethodDirect, // Default, but wasn't specified in v1
},
}
}

func newMigrationRelationship(cmd *cobra.Command) (*migrationRelationship, error) {
r, err := CreateRelationshipFromCommand(cmd, MigrationRelationshipType)
if err != nil {
Expand All @@ -87,8 +138,8 @@ func newMigrationRelationship(cmd *cobra.Command) (*migrationRelationship, error

return &migrationRelationship{
Relationship: *r,
data: &migrationRelationshipData{
Version: 1,
data: &migrationRelationshipDataV2{
Version: 2,
},
}, nil
}
Expand All @@ -108,6 +159,9 @@ var migrationCmd = &cobra.Command{
func init() {
rootCmd.AddCommand(migrationCmd)

// Add logging flags to all sub-commands
logs.AddFlags(migrationCmd.PersistentFlags())

migrationCmd.PersistentFlags().StringP("relationship", "r", "", "relationship name")
cobra.CheckErr(migrationCmd.MarkPersistentFlagRequired("relationship"))
cobra.CheckErr(viper.BindPFlag("relationship", migrationCmd.PersistentFlags().Lookup("relationship")))
Expand All @@ -127,63 +181,25 @@ func loadMigrationRelationship(cmd *cobra.Command) (*migrationRelationship, erro
version := mr.GetInt("data.version")
switch version {
case 1:
// version2 is now the default, read in the v1 data and migrate to v2
datav1 := &migrationRelationshipData{}
if err := mr.GetData(&datav1); err != nil {
return nil, err
}
mr.convertDataToV2(datav1) // Convert from v1 to v2
case 2:
if err := mr.GetData(&mr.data); err != nil {
return nil, err
}
default:
return nil, fmt.Errorf("unsupported config file version %d", version)
}
return mr, nil
}

func (mrd *migrationRelationshipDestination) waitForRDStatus(ctx context.Context, client client.Client) (
*volsyncv1alpha1.ReplicationDestination, error) {
// wait for migrationdestination to become ready
var (
rd *volsyncv1alpha1.ReplicationDestination
err error
)
klog.Infof("waiting for keys & address of destination to be available")
err = wait.PollUntilContextTimeout(ctx, 5*time.Second, defaultRsyncKeyTimeout, true, /*immediate*/
func(ctx context.Context) (bool, error) {
rd, err = mrd.getDestination(ctx, client)
if err != nil {
return false, err
}
if rd.Status == nil || rd.Status.Rsync == nil {
return false, nil
}
if rd.Status.Rsync.Address == nil {
klog.V(2).Infof("Waiting for MigrationDestination %s RSync address to populate", rd.Name)
return false, nil
}

if rd.Status.Rsync.SSHKeys == nil {
klog.V(2).Infof("Waiting for MigrationDestination %s RSync sshkeys to populate", rd.Name)
return false, nil
}

klog.V(2).Infof("Found MigrationDestination RSync Address: %s", *rd.Status.Rsync.Address)
return true, nil
})
if err != nil {
return nil, fmt.Errorf("failed to fetch rd status: %w,", err)
}

return rd, nil
}

func (mrd *migrationRelationshipDestination) getDestination(ctx context.Context, client client.Client) (
*volsyncv1alpha1.ReplicationDestination, error) {
nsName := types.NamespacedName{
Namespace: mrd.Namespace,
Name: mrd.RDName,
}
rd := &volsyncv1alpha1.ReplicationDestination{}
err := client.Get(ctx, nsName, rd)
if err != nil {
return nil, err
if mr.data.IsRsyncTLS {
mr.mh = &migrationHandlerRsyncTLS{}
} else {
mr.mh = &migrationHandlerRsync{}
}

return rd, nil
return mr, nil
}