Skip to content
This repository was archived by the owner on Apr 27, 2024. It is now read-only.

Commit 67c1b7a

Browse files
author
Matthew Ingle
committed
Number of fixes for SFTP File manager and Config File creation
1 parent 77d1ca0 commit 67c1b7a

File tree

9 files changed

+211
-209
lines changed

9 files changed

+211
-209
lines changed

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ WORKDIR /app/
77
COPY go.mod go.sum /app/
88
RUN go mod download
99
COPY . /app/
10-
RUN CGO_ENABLED=0 go build \
10+
RUN --mount=type=cache,target="/root/.cache/go-build" CGO_ENABLED=0 go build \
1111
-ldflags="-s -w -X github.com/kubectyl/kuber/system.Version=$VERSION" \
1212
-v \
1313
-trimpath \

environment/kubernetes/pod.go

Lines changed: 115 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package kubernetes
33
import (
44
"bufio"
55
"context"
6+
"encoding/base64"
7+
"encoding/json"
68
"fmt"
79
"io"
810
"os"
@@ -23,6 +25,7 @@ import (
2325

2426
"github.com/kubectyl/kuber/config"
2527
"github.com/kubectyl/kuber/environment"
28+
"github.com/kubectyl/kuber/parser"
2629
"github.com/kubectyl/kuber/system"
2730

2831
corev1 "k8s.io/api/core/v1"
@@ -409,45 +412,88 @@ func (e *Environment) Create() error {
409412
// Create a map to store the file data for the ConfigMap
410413
fileData := make(map[string]string)
411414

415+
fileReplaceOps := parser.FileReplaceOperations{}
416+
412417
for _, k := range cfs {
413-
// replacement := make(map[string]string)
418+
fileName := base64.URLEncoding.EncodeToString([]byte(k.FileName))
419+
fileName = strings.TrimRight(fileName, "=")
414420
for _, t := range k.Replace {
415-
// replacement[t.Match] = t.ReplaceWith.String()
416-
fileData[k.FileName] += fmt.Sprintf("%s=%s\n", t.Match, t.ReplaceWith.String())
421+
fileData[fileName] += fmt.Sprintf("%s=%s\n", t.Match, t.ReplaceWith.String())
417422
}
418-
419-
command, err := k.Parse("/config/", "/home/container/")
420-
if err != nil {
421-
return err
423+
fileOp := parser.FileReplaceOperation{
424+
SourceFile: "/config/" + fileName,
425+
TargetFile: "/home/container/" + k.FileName,
426+
TargetType: k.Parser.String(),
422427
}
423-
424-
// Add a new initContainer to the Pod
425-
newInitContainer := corev1.Container{
426-
Name: "configuration-files",
427-
Image: "busybox",
428-
ImagePullPolicy: corev1.PullIfNotPresent,
429-
SecurityContext: &corev1.SecurityContext{
430-
RunAsUser: pointer.Int64(1000),
431-
RunAsNonRoot: pointer.Bool(true),
428+
fileReplaceOps.Files = append(fileReplaceOps.Files, fileOp)
429+
}
430+
binaryFileOpData, err := json.Marshal(fileReplaceOps)
431+
binData := make(map[string][]byte)
432+
binData["config.json"] = binaryFileOpData
433+
newConfigMap := &corev1.ConfigMap{
434+
ObjectMeta: metav1.ObjectMeta{
435+
Name: e.Id + "-config-replace-ops",
436+
Namespace: cfg.Cluster.Namespace,
437+
Labels: map[string]string{
438+
"Service": "Kubectyl",
439+
"uuid": e.Id,
432440
},
433-
Command: command,
434-
Resources: corev1.ResourceRequirements{},
435-
VolumeMounts: []corev1.VolumeMount{
436-
{
437-
Name: "replacement",
438-
MountPath: "/config",
439-
ReadOnly: true,
440-
},
441-
{
442-
Name: "storage",
443-
MountPath: "/home/container",
441+
},
442+
BinaryData: binData,
443+
}
444+
445+
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{
446+
Name: "file-replace-ops",
447+
VolumeSource: corev1.VolumeSource{
448+
ConfigMap: &corev1.ConfigMapVolumeSource{
449+
LocalObjectReference: corev1.LocalObjectReference{
450+
Name: newConfigMap.Name,
444451
},
445452
},
446-
}
453+
},
454+
})
447455

448-
pod.Spec.InitContainers = append(pod.Spec.InitContainers, newInitContainer)
456+
err = e.CreateOrUpdateConfigMap(newConfigMap)
457+
if err != nil {
458+
return err
449459
}
450460

461+
// Add a new initContainer to the Pod
462+
newInitContainer := corev1.Container{
463+
Name: "configuration-files",
464+
Image: "inglemr/fileparser:latest",
465+
ImagePullPolicy: corev1.PullIfNotPresent,
466+
SecurityContext: &corev1.SecurityContext{
467+
RunAsUser: pointer.Int64(1000),
468+
RunAsNonRoot: pointer.Bool(true),
469+
},
470+
Env: []corev1.EnvVar{
471+
{
472+
Name: "CONFIG_LOCATION",
473+
Value: "/fileparserconfig/config.json",
474+
},
475+
},
476+
Resources: corev1.ResourceRequirements{},
477+
VolumeMounts: []corev1.VolumeMount{
478+
{
479+
Name: "replacement",
480+
MountPath: "/config",
481+
ReadOnly: true,
482+
},
483+
{
484+
Name: "storage",
485+
MountPath: "/home/container",
486+
},
487+
{
488+
Name: "file-replace-ops",
489+
MountPath: "/fileparserconfig",
490+
ReadOnly: true,
491+
},
492+
},
493+
}
494+
495+
pod.Spec.InitContainers = append(pod.Spec.InitContainers, newInitContainer)
496+
451497
pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{
452498
Name: "replacement",
453499
VolumeSource: corev1.VolumeSource{
@@ -464,28 +510,17 @@ func (e *Environment) Create() error {
464510
ObjectMeta: metav1.ObjectMeta{
465511
Name: e.Id + "-replacement",
466512
Namespace: cfg.Cluster.Namespace,
513+
Labels: map[string]string{
514+
"Service": "Kubectyl",
515+
"uuid": e.Id,
516+
},
467517
},
468518
Data: fileData,
469519
}
470520

471-
// Check if the ConfigMap already exists
472-
_, err := e.client.CoreV1().ConfigMaps(cfg.Cluster.Namespace).Get(context.TODO(), e.Id+"-replacement", metav1.GetOptions{})
521+
err = e.CreateOrUpdateConfigMap(configMap)
473522
if err != nil {
474-
if errors.IsNotFound(err) {
475-
_, err = e.client.CoreV1().ConfigMaps(cfg.Cluster.Namespace).Create(context.TODO(), configMap, metav1.CreateOptions{})
476-
if err != nil {
477-
return err
478-
}
479-
e.log().Info("replacement configmap created successfully")
480-
} else {
481-
return err
482-
}
483-
} else {
484-
_, err = e.client.CoreV1().ConfigMaps(cfg.Cluster.Namespace).Update(context.TODO(), configMap, metav1.UpdateOptions{})
485-
if err != nil {
486-
return err
487-
}
488-
e.log().Info("replacement configmap updated successfully")
523+
return err
489524
}
490525
}
491526

@@ -601,14 +636,12 @@ func (e *Environment) CreateService() error {
601636
Selector: map[string]string{
602637
"uuid": e.Id,
603638
},
604-
Type: corev1.ServiceType(serviceType),
605-
ExternalTrafficPolicy: corev1.ServiceExternalTrafficPolicyType(externalPolicy),
606-
HealthCheckNodePort: 0,
607-
PublishNotReadyAddresses: true,
608-
AllocateLoadBalancerNodePorts: new(bool),
639+
Type: corev1.ServiceType(serviceType),
640+
ExternalTrafficPolicy: corev1.ServiceExternalTrafficPolicyType(externalPolicy),
641+
HealthCheckNodePort: 0,
642+
PublishNotReadyAddresses: true,
609643
},
610644
}
611-
612645
udp := &corev1.Service{
613646
TypeMeta: metav1.TypeMeta{
614647
Kind: "Service",
@@ -626,15 +659,16 @@ func (e *Environment) CreateService() error {
626659
Selector: map[string]string{
627660
"uuid": e.Id,
628661
},
629-
Type: corev1.ServiceType(serviceType),
630-
ExternalTrafficPolicy: corev1.ServiceExternalTrafficPolicyType(externalPolicy),
631-
HealthCheckNodePort: 0,
632-
PublishNotReadyAddresses: true,
633-
AllocateLoadBalancerNodePorts: new(bool),
662+
Type: corev1.ServiceType(serviceType),
663+
ExternalTrafficPolicy: corev1.ServiceExternalTrafficPolicyType(externalPolicy),
664+
HealthCheckNodePort: 0,
665+
PublishNotReadyAddresses: true,
634666
},
635667
}
636668

637669
if serviceType == "LoadBalancer" && cfg.Cluster.MetalLBSharedIP {
670+
udp.Spec.AllocateLoadBalancerNodePorts = new(bool)
671+
tcp.Spec.AllocateLoadBalancerNodePorts = new(bool)
638672
tcp.Annotations = map[string]string{
639673
"metallb.universe.tf/allow-shared-ip": e.Id,
640674
}
@@ -1062,3 +1096,27 @@ func (e *Environment) convertMounts() ([]corev1.VolumeMount, []corev1.Volume) {
10621096

10631097
return out, volumes
10641098
}
1099+
1100+
func (e *Environment) CreateOrUpdateConfigMap(configMap *corev1.ConfigMap) error {
1101+
// Check if the ConfigMap already exists
1102+
cfg := config.Get()
1103+
_, err := e.client.CoreV1().ConfigMaps(cfg.Cluster.Namespace).Get(context.TODO(), configMap.Name, metav1.GetOptions{})
1104+
if err != nil {
1105+
if errors.IsNotFound(err) {
1106+
_, err = e.client.CoreV1().ConfigMaps(cfg.Cluster.Namespace).Create(context.TODO(), configMap, metav1.CreateOptions{})
1107+
if err != nil {
1108+
return err
1109+
}
1110+
e.log().Info(configMap.Name + " configmap created successfully")
1111+
} else {
1112+
return err
1113+
}
1114+
} else {
1115+
_, err = e.client.CoreV1().ConfigMaps(cfg.Cluster.Namespace).Update(context.TODO(), configMap, metav1.UpdateOptions{})
1116+
if err != nil {
1117+
return err
1118+
}
1119+
e.log().Info(configMap.Name + " configmap updated successfully")
1120+
}
1121+
return nil
1122+
}

parser/parser.go

Lines changed: 10 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package parser
22

33
import (
4-
"fmt"
5-
64
"emperror.dev/errors"
75
"github.com/apex/log"
86
"github.com/buger/jsonparser"
@@ -162,56 +160,21 @@ func (cfr *ConfigurationFileReplacement) UnmarshalJSON(data []byte) error {
162160
// in the API response from the Panel.
163161
func (f *ConfigurationFile) Parse(configDir, externalDir string) ([]string, error) {
164162
log.WithField("path", externalDir).WithField("parser", f.Parser.String()).Debug("parsing server configuration file")
165-
166163
if mb, err := json.Marshal(config.Get()); err != nil {
167164
return []string{}, err
168165
} else {
169166
f.configuration = mb
170167
}
171168

172-
switch f.Parser {
173-
case Properties:
174-
return []string{
175-
"/bin/sh",
176-
"-c",
177-
fmt.Sprintf(`
178-
configDir="%s"
179-
externalDir="%s"
180-
181-
for configFilePath in $configDir*; do
182-
filename=$(basename "$configFilePath")
183-
externalFilePath="${externalDir}${filename}"
184-
185-
if [ -f "$externalFilePath" ]; then
186-
echo "Processing config file: $filename"
187-
188-
while IFS='=' read -r key value; do
189-
if [[ -n $key && $key != "#"* ]]; then
190-
echo "Replacing $key with value $value in $externalFilePath"
191-
if grep -qE "^$key=|^$key\s*=" "$externalFilePath"; then
192-
sed -i "s|^$key=.*|$key=$value|g" "$externalFilePath"
193-
else
194-
echo "Invalid format in $externalFilePath"
195-
fi
196-
fi
197-
done < "$configFilePath"
198-
else
199-
echo "File $externalFilePath not found"
200-
fi
201-
done
202-
`, configDir, externalDir),
203-
}, nil
204-
case File:
205-
return []string{}, nil
206-
case Yaml, "yml":
207-
return []string{}, nil
208-
case Json:
209-
return []string{}, nil
210-
case Ini:
211-
return []string{}, nil
212-
case Xml:
213-
return []string{}, nil
214-
}
215-
216169
return []string{}, nil
217170
}
171+
172+
type FileReplaceOperations struct {
173+
Files []FileReplaceOperation `json:"files"`
174+
}
175+
176+
type FileReplaceOperation struct {
177+
TargetFile string `json:"target_file"`
178+
SourceFile string `json:"source_file"`
179+
TargetType string `json:"target_type"`
180+
}

0 commit comments

Comments
 (0)