Skip to content

Commit

Permalink
- drop *bool in status
Browse files Browse the repository at this point in the history
- refactor if condition for len of containerStatuses
- store rsync password in secret
- drop get from get* methods
- use more constants

Signed-off-by: Alay Patel <[email protected]>
  • Loading branch information
alaypatel07 committed Mar 1, 2022
1 parent 02b3cf9 commit 6ff5ca4
Show file tree
Hide file tree
Showing 6 changed files with 178 additions and 32 deletions.
74 changes: 56 additions & 18 deletions transfer/rsync/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,23 +59,23 @@ func (tc *client) Status(ctx context.Context, c ctrlclient.Client) (*transfer.St
}

for _, pod := range podList.Items {
if pod.Status.ContainerStatuses != nil || len(pod.Status.ContainerStatuses) > 0 {
if len(pod.Status.ContainerStatuses) > 0 {
for _, containerStatus := range pod.Status.ContainerStatuses {
if containerStatus.Name == "rsync" && containerStatus.State.Terminated != nil {
if containerStatus.State.Terminated.ExitCode == 0 {
return &transfer.Status{
Completed: &transfer.Completed{
Successful: pointer.BoolPtr(true),
Failure: pointer.BoolPtr(false),
Successful: true,
Failure: false,
FinishedAt: &containerStatus.State.Terminated.FinishedAt,
},
}, nil
} else {
return &transfer.Status{
Running: nil,
Completed: &transfer.Completed{
Successful: pointer.Bool(false),
Failure: pointer.Bool(true),
Successful: false,
Failure: true,
FinishedAt: &containerStatus.State.Terminated.FinishedAt,
},
}, nil
Expand Down Expand Up @@ -141,7 +141,19 @@ func (tc *client) MarkForCleanup(ctx context.Context, c ctrlclient.Client, key,
Namespace: tc.namespace,
},
}
return utils.UpdateWithLabel(ctx, c, roleBinding, key, value)
err = utils.UpdateWithLabel(ctx, c, roleBinding, key, value)
if err != nil {
return err
}

// update secret
secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s-%s", rsyncPassword, tc.nameSuffix),
Namespace: tc.namespace,
},
}
return utils.UpdateWithLabel(ctx, c, secret, key, value)
}

// NewClient takes PVCList, transport and endpoint object and creates all
Expand All @@ -154,7 +166,7 @@ func (tc *client) MarkForCleanup(ctx context.Context, c ctrlclient.Client, key,
// to retry with a different suffix until retries are added to the client package

// In order to generate the right RBAC, add the following lines to the Reconcile function annotations.
// +kubebuilder:rbac:groups=core,resources=pods;serviceaccounts,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=core,resources=pods;serviceaccounts;secrets,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=roles;rolebindings,verbs=get;list;watch;create;update;patch;delete
func NewClient(ctx context.Context, c ctrlclient.Client,
pvcList transfer.PVCList,
Expand All @@ -179,7 +191,7 @@ func NewClient(ctx context.Context, c ctrlclient.Client,
var namespace string
namespaces := pvcList.Namespaces()
if len(namespaces) > 0 {
namespace = pvcList.Namespaces()[0]
namespace = namespaces[0]
}

for _, ns := range namespaces {
Expand All @@ -198,6 +210,7 @@ func NewClient(ctx context.Context, c ctrlclient.Client,
tc.reconcileServiceAccount,
tc.reconcileRole,
tc.reconcileRoleBinding,
tc.reconcilePassword,
tc.reconcilePod,
}

Expand All @@ -215,7 +228,7 @@ func NewClient(ctx context.Context, c ctrlclient.Client,
// TODO: add retries
func (tc *client) reconcilePod(ctx context.Context, c ctrlclient.Client, ns string) error {
var errs []error
rsyncOptions, err := GetRsyncCommandDefaultFlags()
rsyncOptions, err := rsyncCommandWithDefaultFlags()
if err != nil {
tc.logger.Error(err, "unable to get default flags for rsync command")
return err
Expand All @@ -231,8 +244,14 @@ func (tc *client) reconcilePod(ctx context.Context, c ctrlclient.Client, ns stri
Command: rsyncContainerCommand,
Env: []corev1.EnvVar{
{
Name: "RSYNC_PASSWORD",
Value: tc.password,
Name: rsyncPasswordKey,
ValueFrom: &corev1.EnvVarSource{
SecretKeyRef: &corev1.SecretKeySelector{
LocalObjectReference: corev1.LocalObjectReference{},
Key: rsyncPasswordKey,
Optional: pointer.Bool(true),
},
},
},
},

Expand All @@ -243,7 +262,7 @@ func (tc *client) reconcilePod(ctx context.Context, c ctrlclient.Client, ns stri
},
{
Name: "rsync-communication",
MountPath: "/usr/share/rsync",
MountPath: rsyncCommunicationMountPath,
},
},
},
Expand All @@ -268,7 +287,7 @@ func (tc *client) reconcilePod(ctx context.Context, c ctrlclient.Client, ns stri
{
Name: "rsync-communication",
VolumeSource: corev1.VolumeSource{
EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumDefault},
EmptyDir: &corev1.EmptyDirVolumeSource{Medium: corev1.StorageMediumMemory},
},
},
}
Expand Down Expand Up @@ -319,7 +338,8 @@ func (tc *client) getCommand(rsyncOptions []string, pvc transfer.PVC) []string {
tc.Transport().Hostname(),
pvc.LabelSafeName(), tc.Transport().ListenPort()))
rsyncCommandBashScript := fmt.Sprintf(
"trap \"touch /usr/share/rsync/rsync-client-container-done\" EXIT SIGINT SIGTERM; timeout=120; SECONDS=0; while [ $SECONDS -lt $timeout ]; do nc -z localhost %d; rc=$?; if [ $rc -eq 0 ]; then %s; rc=$?; break; fi; done; exit $rc;",
"trap \"touch %s/rsync-client-container-done\" EXIT SIGINT SIGTERM; timeout=120; SECONDS=0; while [ $SECONDS -lt $timeout ]; do nc -z localhost %d; rc=$?; if [ $rc -eq 0 ]; then %s; rc=$?; break; fi; done; exit $rc;",
rsyncCommunicationMountPath,
tc.Transport().ListenPort(),
strings.Join(rsyncCommand, " "))
rsyncContainerCommand := []string{
Expand Down Expand Up @@ -347,21 +367,21 @@ func customizeTransportClientContainers(transportClient transport.Transport) err
stunnelContainer.Command = []string{
"/bin/bash",
"-c",
`/bin/stunnel /etc/stunnel/stunnel.conf
fmt.Sprintf(`/bin/stunnel /etc/stunnel/stunnel.conf
while true
do test -f /usr/share/rsync/rsync-client-container-done
do test -f %s/rsync-client-container-done
if [ $? -eq 0 ]
then
break
fi
done
exit 0`,
exit 0`, rsyncCommunicationMountPath),
}
stunnelContainer.VolumeMounts = append(
stunnelContainer.VolumeMounts,
corev1.VolumeMount{
Name: "rsync-communication",
MountPath: "/usr/share/rsync",
MountPath: rsyncCommunicationMountPath,
})
}
return nil
Expand Down Expand Up @@ -429,3 +449,21 @@ func (tc *client) reconcileRoleBinding(ctx context.Context, c ctrlclient.Client,
})
return err
}

func (tc *client) reconcilePassword(ctx context.Context, c ctrlclient.Client, namespace string) error {
secret := &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s-%s", rsyncPassword, tc.nameSuffix),
Namespace: namespace,
},
}
_, err := ctrlutil.CreateOrUpdate(ctx, c, secret, func() error {
secret.OwnerReferences = tc.ownerRefs
secret.Labels = tc.labels
secret.Data = map[string][]byte{
rsyncPasswordKey: []byte(tc.password),
}
return nil
})
return err
}
105 changes: 105 additions & 0 deletions transfer/rsync/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -458,3 +458,108 @@ func Test_client_reconcilePod(t *testing.T) {
})
}
}

func Test_client_reconcileSecret(t *testing.T) {
tests := []struct {
name string
password string
labels map[string]string
ownerRefs []metav1.OwnerReference
namespace string
wantErr bool
nameSuffix string
objects []ctrlclient.Object
}{
{
name: "test with missing secret",
namespace: "foo",
password: "testme123",
labels: map[string]string{"test": "me"},
ownerRefs: testOwnerReferences(),
wantErr: false,
nameSuffix: "foo",
objects: []ctrlclient.Object{},
},
{
name: "test with invalid secret data",
namespace: "foo",
password: "testme123",
labels: map[string]string{"test": "me"},
ownerRefs: testOwnerReferences(),
wantErr: false,
nameSuffix: "foo",
objects: []ctrlclient.Object{
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s-%s", rsyncPassword, "foo"),
Namespace: "foo",
Labels: map[string]string{"foo": "bar"},
OwnerReferences: []metav1.OwnerReference{},
},
Data: map[string][]byte{
rsyncPasswordKey: []byte("badPassword"),
},
},
},
},
{
name: "test with valid secret",
namespace: "foo",
password: "testme123",
labels: map[string]string{"test": "me"},
ownerRefs: testOwnerReferences(),
wantErr: false,
nameSuffix: "foo",
objects: []ctrlclient.Object{
&corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: fmt.Sprintf("%s-%s", rsyncPassword, "foo"),
Namespace: "foo",
Labels: map[string]string{"foo": "bar"},
OwnerReferences: []metav1.OwnerReference{},
},
Data: map[string][]byte{
rsyncPasswordKey: []byte("testme123"),
},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &client{
logger: logrtesting.TestLogger{t},
nameSuffix: tt.nameSuffix,
labels: tt.labels,
ownerRefs: tt.ownerRefs,
password: tt.password,
}

fakeClient := fakeClientWithObjects(tt.objects...)
ctx := context.WithValue(context.Background(), "test", tt.name)

if err := s.reconcilePassword(ctx, fakeClient, tt.namespace); (err != nil) != tt.wantErr {
t.Errorf("reconcilePassword() error = %v, wantErr %v", err, tt.wantErr)
}
secret := &corev1.Secret{}
err := fakeClient.Get(context.Background(), types.NamespacedName{
Namespace: tt.namespace,
Name: rsyncPassword + "-" + tt.nameSuffix,
}, secret)
if err != nil {
panic(fmt.Errorf("%#v should not be getting error from fake client", err))
}

if !reflect.DeepEqual(secret.Labels, tt.labels) {
t.Error("secret does not have the right labels")
}
if !reflect.DeepEqual(secret.OwnerReferences, tt.ownerRefs) {
t.Error("secret does not have the right owner references")
}

if !reflect.DeepEqual(secret.Data, map[string][]byte{rsyncPasswordKey: []byte("testme123")}) {
t.Errorf("secret does not have the right password")
}
})
}
}
6 changes: 3 additions & 3 deletions transfer/rsync/command_options.go
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ func filterRsyncExtraOptions(options []string) (validatedOptions []string, err e
return validatedOptions, errorsutil.NewAggregate(errs)
}

func getRsyncCommandDefaultOptions() []Applier {
func rsyncCommandDefaultOptions() []Applier {
return []Applier{
ArchiveFiles(true),
StandardProgress(true),
Expand All @@ -162,9 +162,9 @@ func (c *CommandOptions) Apply(opts ...Applier) error {
return errorsutil.NewAggregate(errs)
}

func GetRsyncCommandDefaultFlags() ([]string, error) {
func rsyncCommandWithDefaultFlags() ([]string, error) {
c := CommandOptions{}
defaultOptions := getRsyncCommandDefaultOptions()
defaultOptions := rsyncCommandDefaultOptions()
err := c.Apply(defaultOptions...)
if err != nil {
return nil, err
Expand Down
19 changes: 11 additions & 8 deletions transfer/rsync/rsync.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,17 @@ const (
)

const (
rsyncImage = "quay.io/konveyor/rsync-transfer:latest"
rsyncConfig = "backube-rsync-config"
rsyncSecretPrefix = "backube-rsync"
rsyncServiceAccount = "backube-rsync-sa"
rsyncRole = "backube-rsync-role"
rsyncRoleBinding = "backube-rsync-rolebinding"
rsyncdLogDir = "rsyncd-logs"
rsyncdLogDirPath = "/var/log/rsyncd/"
rsyncImage = "quay.io/konveyor/rsync-transfer:latest"
rsyncConfig = "backube-rsync-config"
rsyncSecretPrefix = "backube-rsync"
rsyncServiceAccount = "backube-rsync-sa"
rsyncRole = "backube-rsync-role"
rsyncPassword = "backube-rsync-password"
rsyncPasswordKey = "RSYNC_PASSWORD"
rsyncCommunicationMountPath = "/usr/share/rsync"
rsyncRoleBinding = "backube-rsync-rolebinding"
rsyncdLogDir = "rsyncd-logs"
rsyncdLogDirPath = "/var/log/rsyncd/"
)

// applyPodOptions take a PodSpec and PodOptions, applies
Expand Down
2 changes: 1 addition & 1 deletion transfer/rsync/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ func Test_server_reconcileSecret(t *testing.T) {
}
err := s.reconcileSecret(ctx, fakeClient, tt.namespace)
if (err != nil) != tt.wantErr {
t.Errorf("reconcileSecret() error = %v, wantErr %v", err, tt.wantErr)
t.Errorf("reconcilePassword() error = %v, wantErr %v", err, tt.wantErr)
}
if tt.wantErr {
return
Expand Down
4 changes: 2 additions & 2 deletions transfer/transfer.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ type Running struct {
}

type Completed struct {
Successful *bool
Failure *bool
Successful bool
Failure bool
FinishedAt *metav1.Time
}

Expand Down

0 comments on commit 6ff5ca4

Please sign in to comment.