package configobject import ( "bytes" "errors" "io/fs" "path/filepath" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "edge-infra.dev/pkg/sds/lib/os/file" "edge-infra.dev/pkg/sds/lib/os/passthrough" ) var ( fileMode = fs.FileMode(0644) errCouldNotCastToSecretType = errors.New("could not cast object to Secret type") ) type ConfigObject interface { metav1.Object runtime.Object ObjectType() string GetFiles() map[string][]byte GetLabelsSet() labels.Set GetFieldsSet() (fields.Set, error) Update(directory string, service string, fileHandler file.File, passthrough passthrough.Exec) error UpdateFiles(directory string, fileHandler file.File) (bool, error) } func getFieldsSetFromConfigObject(configObject ConfigObject) (fields.Set, error) { objectFields := fields.Set{"metadata.name": configObject.GetName(), "metadata.namespace": configObject.GetNamespace()} if configObject.ObjectType() == secretObjectType { secret, ok := configObject.(*Secret) if !ok { return nil, errCouldNotCastToSecretType } objectFields["type"] = secret.SecretType() } return objectFields, nil } func updateConfigObject(configObject ConfigObject, directory string, service string, fileHandler file.File, passthrough passthrough.Exec) error { updated, err := configObject.UpdateFiles(directory, fileHandler) if err != nil { return err } if updated && service != "" { // only restart services if files have changed _, err := passthrough.CombinedOutput("/usr/bin/systemctl", "restart", service) return err } return nil } func updateConfigObjectFiles(configObject ConfigObject, directory string, fileHandler file.File) (bool, error) { directory = filepath.Clean(directory) updated := false for filename, updatedData := range configObject.GetFiles() { path := filepath.Join(directory, filename) needsUpdating, err := fileNeedsUpdating(path, updatedData, fileHandler) if err != nil { return false, err } if needsUpdating { if err := fileHandler.Write(path, updatedData, fileMode); err != nil { return false, err } updated = true } } return updated, nil } func fileNeedsUpdating(path string, updatedData []byte, fileHandler file.File) (bool, error) { if !fileHandler.Exists(path) { return true, nil } currentData, err := fileHandler.Read(path) if err != nil { return false, err } return !bytes.Equal(currentData, updatedData), nil }