From b64c3eb341143213509568a6a734892ffab08bd8 Mon Sep 17 00:00:00 2001 From: em Date: Tue, 11 Feb 2025 23:58:25 +0100 Subject: [PATCH] Implement log downloading for fileserver --- README.md | 6 ++++++ examples/filserverService.yaml | 20 ++++++++++++++++++++ examples/pluginConfigMap.yaml | 6 ++++++ pkg/plugin/kubernetes.go | 5 ++++- pkg/plugin/plugin.go | 23 +++++++++++++++++++---- 5 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 examples/filserverService.yaml diff --git a/README.md b/README.md index e1a4664..15e4dba 100644 --- a/README.md +++ b/README.md @@ -65,6 +65,12 @@ data: securityContextFsGroup: "1001" # If provided, will clean up all other volumes on the Velero and Node Agent pods preserveVolumes: "my-bucket,my-other-bucket" + # use this if you deployed an ingress for the fileserver running on 3000 to access logs from outside the cluster network + # e.g. via ur velero cli. You will need to deploy the service/ingress yourself. See examples/filserverService.yaml + externalDownloadHostname: "www.velero-logs.domain.com" + # using https currently seems not to be supported by the velero client + externalDownloadScheme: "http" + externalDownloadPort: 80 ``` ## Removing the plugin diff --git a/examples/filserverService.yaml b/examples/filserverService.yaml new file mode 100644 index 0000000..4d5483e --- /dev/null +++ b/examples/filserverService.yaml @@ -0,0 +1,20 @@ +apiVersion: v1 +kind: Service +metadata: + name: fileserver + namespace: velero +spec: + ports: + - name: fileserver + protocol: TCP + port: 3000 + targetPort: 3000 + selector: + app.kubernetes.io/instance: velero + app.kubernetes.io/name: velero + type: ClusterIP + sessionAffinity: None + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + internalTrafficPolicy: Cluster diff --git a/examples/pluginConfigMap.yaml b/examples/pluginConfigMap.yaml index d8e4b0e..e51e8c1 100644 --- a/examples/pluginConfigMap.yaml +++ b/examples/pluginConfigMap.yaml @@ -11,3 +11,9 @@ data: fileserverImage: ttl.sh/dans/local-volume-provider:12h securityContextRunAsUser: "1001" securityContextFsGroup: "1001" + # use this if you deployed an ingress for the fileserver running on 3000 to access logs from outside the cluster network + # e.g. via ur velero cli. You will need to deploy the service/ingress yourself. See examples/filserverService.yaml + externalDownloadHostname: "www.velero-logs.domain.com" + # using https currently seems not to be supported by the velero client + externalDownloadScheme: "http" + externalDownloadPort: 80 diff --git a/pkg/plugin/kubernetes.go b/pkg/plugin/kubernetes.go index 662214b..6fce2f4 100644 --- a/pkg/plugin/kubernetes.go +++ b/pkg/plugin/kubernetes.go @@ -25,6 +25,9 @@ type localVolumeObjectStoreOpts struct { securityContextRunAsGroup string securityContextFSGroup string preserveVolumes map[string]bool + externalDownloadHostname string + externalDownloadPort string + externalDownloadScheme string } const ( @@ -163,7 +166,7 @@ func ensureDeploymentHasVolume(deployment *appsv1.Deployment, volumeSpec *corev1 } veleroContainer.VolumeMounts = append(veleroContainer.VolumeMounts, *volumeMountSpec) - // Add the POD_IP for servering the signed URLs + // Add the POD_IP for serving the signed URLs if !containerHasEnvVar(veleroContainer, "POD_IP") { veleroContainer.Env = append(veleroContainer.Env, corev1.EnvVar{ Name: "POD_IP", diff --git a/pkg/plugin/plugin.go b/pkg/plugin/plugin.go index 9328141..87789d9 100644 --- a/pkg/plugin/plugin.go +++ b/pkg/plugin/plugin.go @@ -7,6 +7,7 @@ import ( "net/url" "os" "path/filepath" + "strconv" "strings" "time" @@ -249,14 +250,25 @@ func (o *LocalVolumeObjectStore) CreateSignedURL(bucket, key string, ttl time.Du }) log.Debug("LocalVolumeObjectStore.CreateSignedURL called") - namespace := os.Getenv("VELERO_NAMESPACE") - + downloadHostname := os.Getenv("POD_IP") + if o.opts.externalDownloadHostname != "" { + downloadHostname = o.opts.externalDownloadHostname + } + downloadScheme := "http" + if o.opts.externalDownloadScheme != "" { + downloadScheme = o.opts.externalDownloadScheme + } + downloadPort := 3000 + if o.opts.externalDownloadPort != "" { + downloadPort, _ = strconv.Atoi(o.opts.externalDownloadPort) + } signedUrl := url.URL{ - Scheme: "http", - Host: fmt.Sprintf("%s:%d", os.Getenv("POD_IP"), 3000), + Scheme: downloadScheme, + Host: fmt.Sprintf("%s:%d", downloadHostname, downloadPort), Path: fmt.Sprintf("/%s/%s", bucket, key), } + namespace := os.Getenv("VELERO_NAMESPACE") err := SignURL(&signedUrl, namespace, ttl) if err != nil { return "", errors.Wrap(err, "failed to create signed url") @@ -292,6 +304,9 @@ func (o *LocalVolumeObjectStore) getLocalVolumeStoreOpts() error { securityContextRunAsGroup: pluginConfigMap.Data["securityContextRunAsGroup"], securityContextFSGroup: pluginConfigMap.Data["securityContextFsGroup"], preserveVolumes: preserveVolumes, + externalDownloadHostname: pluginConfigMap.Data["externalDownloadHostname"], + externalDownloadScheme: pluginConfigMap.Data["externalDownloadScheme"], + externalDownloadPort: pluginConfigMap.Data["externalDownloadPort"], } } return nil