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

Commit

Permalink
Number of fixes for SFTP File manager and Config File creation
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthew Ingle committed Feb 4, 2024
1 parent 77d1ca0 commit 5618cbb
Show file tree
Hide file tree
Showing 9 changed files with 211 additions and 209 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ WORKDIR /app/
COPY go.mod go.sum /app/
RUN go mod download
COPY . /app/
RUN CGO_ENABLED=0 go build \
RUN --mount=type=cache,target="/root/.cache/go-build" CGO_ENABLED=0 go build \
-ldflags="-s -w -X github.com/kubectyl/kuber/system.Version=$VERSION" \
-v \
-trimpath \
Expand Down
172 changes: 115 additions & 57 deletions environment/kubernetes/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package kubernetes
import (
"bufio"
"context"
"encoding/base64"
"encoding/json"
"fmt"
"io"
"os"
Expand All @@ -23,6 +25,7 @@ import (

"github.com/kubectyl/kuber/config"
"github.com/kubectyl/kuber/environment"
"github.com/kubectyl/kuber/parser"
"github.com/kubectyl/kuber/system"

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

fileReplaceOps := parser.FileReplaceOperations{}

for _, k := range cfs {
// replacement := make(map[string]string)
fileName := base64.URLEncoding.EncodeToString([]byte(k.FileName))
fileName = strings.TrimRight(fileName, "=")
for _, t := range k.Replace {
// replacement[t.Match] = t.ReplaceWith.String()
fileData[k.FileName] += fmt.Sprintf("%s=%s\n", t.Match, t.ReplaceWith.String())
fileData[fileName] += fmt.Sprintf("%s=%s\n", t.Match, t.ReplaceWith.String())
}

command, err := k.Parse("/config/", "/home/container/")
if err != nil {
return err
fileOp := parser.FileReplaceOperation{
SourceFile: "/config/" + fileName,
TargetFile: "/home/container/" + k.FileName,
TargetType: k.Parser.String(),
}

// Add a new initContainer to the Pod
newInitContainer := corev1.Container{
Name: "configuration-files",
Image: "busybox",
ImagePullPolicy: corev1.PullIfNotPresent,
SecurityContext: &corev1.SecurityContext{
RunAsUser: pointer.Int64(1000),
RunAsNonRoot: pointer.Bool(true),
fileReplaceOps.Files = append(fileReplaceOps.Files, fileOp)
}
binaryFileOpData, err := json.Marshal(fileReplaceOps)
binData := make(map[string][]byte)
binData["config.json"] = binaryFileOpData
newConfigMap := &corev1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: e.Id + "-config-replace-ops",
Namespace: cfg.Cluster.Namespace,
Labels: map[string]string{
"Service": "Kubectyl",
"uuid": e.Id,
},
Command: command,
Resources: corev1.ResourceRequirements{},
VolumeMounts: []corev1.VolumeMount{
{
Name: "replacement",
MountPath: "/config",
ReadOnly: true,
},
{
Name: "storage",
MountPath: "/home/container",
},
BinaryData: binData,
}

pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{
Name: "file-replace-ops",
VolumeSource: corev1.VolumeSource{
ConfigMap: &corev1.ConfigMapVolumeSource{
LocalObjectReference: corev1.LocalObjectReference{
Name: newConfigMap.Name,
},
},
}
},
})

pod.Spec.InitContainers = append(pod.Spec.InitContainers, newInitContainer)
err = e.CreateOrUpdateConfigMap(newConfigMap)
if err != nil {
return err
}

// Add a new initContainer to the Pod
newInitContainer := corev1.Container{
Name: "configuration-files",
Image: "inglemr/fileparser:latest",
ImagePullPolicy: corev1.PullIfNotPresent,
SecurityContext: &corev1.SecurityContext{
RunAsUser: pointer.Int64(1000),
RunAsNonRoot: pointer.Bool(true),
},
Env: []corev1.EnvVar{
{
Name: "CONFIG_LOCATION",
Value: "/fileparserconfig/config.json",
},
},
Resources: corev1.ResourceRequirements{},
VolumeMounts: []corev1.VolumeMount{
{
Name: "replacement",
MountPath: "/config",
ReadOnly: true,
},
{
Name: "storage",
MountPath: "/home/container",
},
{
Name: "file-replace-ops",
MountPath: "/fileparserconfig",
ReadOnly: true,
},
},
}

pod.Spec.InitContainers = append(pod.Spec.InitContainers, newInitContainer)

pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{
Name: "replacement",
VolumeSource: corev1.VolumeSource{
Expand All @@ -464,28 +510,17 @@ func (e *Environment) Create() error {
ObjectMeta: metav1.ObjectMeta{
Name: e.Id + "-replacement",
Namespace: cfg.Cluster.Namespace,
Labels: map[string]string{
"Service": "Kubectyl",
"uuid": e.Id,
},
},
Data: fileData,
}

// Check if the ConfigMap already exists
_, err := e.client.CoreV1().ConfigMaps(cfg.Cluster.Namespace).Get(context.TODO(), e.Id+"-replacement", metav1.GetOptions{})
err = e.CreateOrUpdateConfigMap(configMap)
if err != nil {
if errors.IsNotFound(err) {
_, err = e.client.CoreV1().ConfigMaps(cfg.Cluster.Namespace).Create(context.TODO(), configMap, metav1.CreateOptions{})
if err != nil {
return err
}
e.log().Info("replacement configmap created successfully")
} else {
return err
}
} else {
_, err = e.client.CoreV1().ConfigMaps(cfg.Cluster.Namespace).Update(context.TODO(), configMap, metav1.UpdateOptions{})
if err != nil {
return err
}
e.log().Info("replacement configmap updated successfully")
return err
}
}

Expand Down Expand Up @@ -601,14 +636,12 @@ func (e *Environment) CreateService() error {
Selector: map[string]string{
"uuid": e.Id,
},
Type: corev1.ServiceType(serviceType),
ExternalTrafficPolicy: corev1.ServiceExternalTrafficPolicyType(externalPolicy),
HealthCheckNodePort: 0,
PublishNotReadyAddresses: true,
AllocateLoadBalancerNodePorts: new(bool),
Type: corev1.ServiceType(serviceType),
ExternalTrafficPolicy: corev1.ServiceExternalTrafficPolicyType(externalPolicy),
HealthCheckNodePort: 0,
PublishNotReadyAddresses: true,
},
}

udp := &corev1.Service{
TypeMeta: metav1.TypeMeta{
Kind: "Service",
Expand All @@ -626,15 +659,16 @@ func (e *Environment) CreateService() error {
Selector: map[string]string{
"uuid": e.Id,
},
Type: corev1.ServiceType(serviceType),
ExternalTrafficPolicy: corev1.ServiceExternalTrafficPolicyType(externalPolicy),
HealthCheckNodePort: 0,
PublishNotReadyAddresses: true,
AllocateLoadBalancerNodePorts: new(bool),
Type: corev1.ServiceType(serviceType),
ExternalTrafficPolicy: corev1.ServiceExternalTrafficPolicyType(externalPolicy),
HealthCheckNodePort: 0,
PublishNotReadyAddresses: true,
},
}

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

return out, volumes
}

func (e *Environment) CreateOrUpdateConfigMap(configMap *corev1.ConfigMap) error {
// Check if the ConfigMap already exists
cfg := config.Get()
_, err := e.client.CoreV1().ConfigMaps(cfg.Cluster.Namespace).Get(context.TODO(), configMap.Name, metav1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
_, err = e.client.CoreV1().ConfigMaps(cfg.Cluster.Namespace).Create(context.TODO(), configMap, metav1.CreateOptions{})
if err != nil {
return err
}
e.log().Info(configMap.Name + " configmap created successfully")
} else {
return err
}
} else {
_, err = e.client.CoreV1().ConfigMaps(cfg.Cluster.Namespace).Update(context.TODO(), configMap, metav1.UpdateOptions{})
if err != nil {
return err
}
e.log().Info(configMap.Name + " configmap updated successfully")
}
return nil
}
57 changes: 10 additions & 47 deletions parser/parser.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package parser

import (
"fmt"

"emperror.dev/errors"
"github.com/apex/log"
"github.com/buger/jsonparser"
Expand Down Expand Up @@ -162,56 +160,21 @@ func (cfr *ConfigurationFileReplacement) UnmarshalJSON(data []byte) error {
// in the API response from the Panel.
func (f *ConfigurationFile) Parse(configDir, externalDir string) ([]string, error) {
log.WithField("path", externalDir).WithField("parser", f.Parser.String()).Debug("parsing server configuration file")

if mb, err := json.Marshal(config.Get()); err != nil {
return []string{}, err
} else {
f.configuration = mb
}

switch f.Parser {
case Properties:
return []string{
"/bin/sh",
"-c",
fmt.Sprintf(`
configDir="%s"
externalDir="%s"
for configFilePath in $configDir*; do
filename=$(basename "$configFilePath")
externalFilePath="${externalDir}${filename}"
if [ -f "$externalFilePath" ]; then
echo "Processing config file: $filename"
while IFS='=' read -r key value; do
if [[ -n $key && $key != "#"* ]]; then
echo "Replacing $key with value $value in $externalFilePath"
if grep -qE "^$key=|^$key\s*=" "$externalFilePath"; then
sed -i "s|^$key=.*|$key=$value|g" "$externalFilePath"
else
echo "Invalid format in $externalFilePath"
fi
fi
done < "$configFilePath"
else
echo "File $externalFilePath not found"
fi
done
`, configDir, externalDir),
}, nil
case File:
return []string{}, nil
case Yaml, "yml":
return []string{}, nil
case Json:
return []string{}, nil
case Ini:
return []string{}, nil
case Xml:
return []string{}, nil
}

return []string{}, nil
}

type FileReplaceOperations struct {
Files []FileReplaceOperation `json:"files"`
}

type FileReplaceOperation struct {
TargetFile string `json:"target_file"`
SourceFile string `json:"source_file"`
TargetType string `json:"target_type"`
}
Loading

0 comments on commit 5618cbb

Please sign in to comment.