From 58814d76ede74465a3d28fa206e0040eb723ed2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Huss?= Date: Wed, 13 Nov 2024 13:10:31 +0100 Subject: [PATCH] Update package --- agent/scripts/lib/gen_package.rhai | 2 +- agent/scripts/lib/install_from_dir.rhai | 259 ++++++++++++++---------- box/vynil/package.yaml | 2 +- box/vynil/systems/cm.yaml | 4 - box/vynil/systems/rbac.yaml.hbs | 58 +++--- common/src/k8sgeneric.rs | 1 - common/src/k8sworkload.rs | 1 - operator/templates/package.yaml.hbs | 8 +- 8 files changed, 191 insertions(+), 144 deletions(-) delete mode 100644 box/vynil/systems/cm.yaml diff --git a/agent/scripts/lib/gen_package.rhai b/agent/scripts/lib/gen_package.rhai index 8e3ff5b..8ad219d 100644 --- a/agent/scripts/lib/gen_package.rhai +++ b/agent/scripts/lib/gen_package.rhai @@ -7,7 +7,7 @@ fn gen_system(path, docs) { let yaml = yaml_decode(file_read(path+"/package.yaml")); let name = if type_of(yaml["metadata"]) == "map" {yaml["metadata"]["name"]} else {()}; if name != () { - for doc in docs { + for doc in docs.filter(|obj| type_of(obj) == "map" && obj.keys().contains("kind") && obj.keys().contains("metadata") && type_of(obj.metadata) == "map") { if doc.kind == "CustomResourceDefinition" { create_dir(`${path}/get_crds`); if "conversion" in doc.spec && doc.spec.conversion != () { diff --git a/agent/scripts/lib/install_from_dir.rhai b/agent/scripts/lib/install_from_dir.rhai index b59cc80..37bb390 100644 --- a/agent/scripts/lib/install_from_dir.rhai +++ b/agent/scripts/lib/install_from_dir.rhai @@ -1,120 +1,173 @@ -fn install(instance, context, dir, allow_cluster, force_ns) { - let hbs = new_hbs(); - hbs.register_partial_dir(`${context.package_dir}/handlebars/partials`); - hbs.register_helper_dir(`${context.package_dir}/handlebars/helpers`); - let applied_objs = []; - for file in read_dir(dir) { - log_info(`Applying ${file}`); - let objects = if file.ends_with(".yaml") || file.ends_with(".yml") { - yaml_decode_multi(file_read(file)) - } else if file.ends_with(".yaml.hbs") || file.ends_with(".yml.hbs") { - yaml_decode_multi(hbs.render_from(file_read(file), context)) - } else {[]}; - for obj in objects { - if obj.kind != () && obj.metadata != () { - let ns = if (force_ns) { - instance.metadata.namespace - } else { - if obj.metadata.namespace != () {obj.metadata.namespace} else {instance.metadata.namespace} - }; - let api = k8s_resource(obj.kind, ns); - if api.exist() { - if force_ns && api.scope != "cluster" { - obj.metadata.namespace = ns; - } - if api.scope == "cluster" { - if allow_cluster { - api.apply(obj.metadata.name, obj); - applied_objs.push(#{ - kind: obj.kind, - name: obj.metadata.name - }); - } else { - log_warn(`Ignoring ${obj.kind} ${obj.metadata.name} as it is a clusterwide resource type.`); - } - } else { - api.apply(obj.metadata.name, obj); - applied_objs.push(#{ - kind: obj.kind, - name: obj.metadata.name, - namespace: ns - }); - } - } else { - log_debug(yaml_encode(obj)); - throw `kind: ${obj.kind} is unknown from the apiServer.`; - } - } else { + const FIRST = [ + "Namespace", + "ServiceAccount", + "ClusterRole", + "ClusterRoleBinding", + "Role", + "RoleBinding", + "Secret", + "ConfigMap", + "PersistentVolume", + "PersistentVolumeClaim", + ]; + const LAST = [ + "Pod", + "Job", + "CronJob", + "DaemonSet", + "Deployment", + "ReplicaSet", + "StatefulSet", + "Service", + "Ingress", + "APIService", + "MutatingWebhookConfiguration", + "ValidatingAdmissionPolicy", + "ValidatingAdmissionPolicyBinding", + "ValidatingWebhookConfiguration", + ]; + + fn get_objects(context, dir) { + let hbs = new_hbs(); + hbs.register_partial_dir(`${context.package_dir}/handlebars/partials`); + hbs.register_helper_dir(`${context.package_dir}/handlebars/helpers`); + let ret = []; + for file in read_dir(dir) { + let objects = if file.ends_with(".yaml") || file.ends_with(".yml") { + yaml_decode_multi(file_read(file)) + } else if file.ends_with(".yaml.hbs") || file.ends_with(".yml.hbs") { + yaml_decode_multi(hbs.render_from(file_read(file), context)) + } else {[]}; + for obj in objects.filter(|obj| type_of(obj) != "map" || ! obj.keys().contains("kind") || ! obj.keys().contains("metadata") || type_of(obj.metadata) != "map") { log_warn(`No kind for an object in file ${file}`); log_debug(yaml_encode(obj)); } + ret += objects.filter(|obj| type_of(obj) == "map" && obj.keys().contains("kind") && obj.keys().contains("metadata") && type_of(obj.metadata) == "map"); } + ret } - applied_objs -} -fn install_allowed(instance, context, dir, allowed) { - let hbs = new_hbs(); - hbs.register_partial_dir(`${context.package_dir}/handlebars/partials`); - hbs.register_helper_dir(`${context.package_dir}/handlebars/helpers`); - let applied_objs = []; - for file in read_dir(dir) { - log_info(`Applying ${file}`); - let objects = if file.ends_with(".yaml") || file.ends_with(".yml") { - yaml_decode_multi(file_read(file)) - } else if file.ends_with(".yaml.hbs") || file.ends_with(".yml.hbs") { - yaml_decode_multi(hbs.render_from(file_read(file), context)) - } else {[]}; - for obj in objects { - if obj.kind != () && obj.metadata != () { - let ns = if (obj.metadata.namespace != () && obj.metadata.namespace in allowed) { - obj.metadata.namespace - } else { - instance.metadata.namespace - }; - let api = k8s_resource(obj.kind, ns); - if api.exist() { - if api.scope != "cluster" { - obj.metadata.namespace = ns; - api.apply(obj.metadata.name, obj); - applied_objs.push(#{ - kind: obj.kind, - name: obj.metadata.name, - namespace: ns - }); - } else { - log_warn(`Ignoring ${obj.kind} ${obj.metadata.name} as it is a clusterwide resource type.`); - } + fn install_obj(obj, allow_cluster, namespace, force_ns) { + let applied = []; + let ns = if (force_ns) { + namespace + } else { + if obj.metadata.namespace != () {obj.metadata.namespace} else {namespace} + }; + let api = k8s_resource(obj.kind, ns); + if api.exist() { + if force_ns && api.scope != "cluster" { + obj.metadata.namespace = ns; + } + if api.scope == "cluster" { + if allow_cluster { + log_info(`Applying ${obj.kind} ${obj.metadata.name}`); + api.apply(obj.metadata.name, obj); + applied.push(#{ + kind: obj.kind, + name: obj.metadata.name + }); } else { - log_debug(yaml_encode(obj)); - throw `kind: ${obj.kind} is unknown from the apiServer.`; + log_warn(`Ignoring ${obj.kind} ${obj.metadata.name} as it is a clusterwide resource type.`); } } else { - log_warn(`No kind for an object in file ${file}`); - log_debug(yaml_encode(obj)); + log_info(`Applying ${obj.kind} ${ns}/${obj.metadata.name}`); + api.apply(obj.metadata.name, obj); + applied.push(#{ + kind: obj.kind, + name: obj.metadata.name, + namespace: ns + }); + } + } else { + log_debug(yaml_encode(obj)); + throw `kind: ${obj.kind} is unknown from the apiServer.`; + } + applied + } + fn install(instance, context, dir, allow_cluster, force_ns) { + let all = get_objects(context, dir); + let applied_objs = []; + for k in global::FIRST { + for obj in all.filter(|o| o.kind==k) { + applied_objs += install_obj(obj, allow_cluster, instance.metadata.namespace, force_ns); + } + } + for obj in all.filter(|o| !global::FIRST.contains(o.kind) && !global::LAST.contains(o.kind)) { + applied_objs += install_obj(obj, allow_cluster, instance.metadata.namespace, force_ns); + } + for k in global::LAST { + for obj in all.filter(|o| o.kind==k) { + applied_objs += install_obj(obj, allow_cluster, instance.metadata.namespace, force_ns); } } + applied_objs } - applied_objs -} -fn remove(applied, previous, default_ns) { - let deleted = []; - for old in previous { - if ! applied.some(|n| n.kind == old.kind && n.namespace == old.namespace && n.name == old.name) { - let ns = if old.namespace != () {old.namespace} else {default_ns}; - let api = k8s_resource(old.kind, ns); - if api.exist() { - try { - let o = api.get_obj(old.name); - o.delete(); - deleted.push(o); - } catch(e) {} + fn install_allowed_obj(obj, allowed, namespace) { + let applied = []; + let ns = if (obj.metadata.namespace != () && obj.metadata.namespace in allowed) { + obj.metadata.namespace + } else { + namespace + }; + let api = k8s_resource(obj.kind, ns); + if api.exist() { + if api.scope != "cluster" { + obj.metadata.namespace = ns; + log_info(`Applying ${obj.kind} ${ns}/${obj.metadata.name}`); + api.apply(obj.metadata.name, obj); + applied.push(#{ + kind: obj.kind, + name: obj.metadata.name, + namespace: ns + }); + } else { + log_warn(`Ignoring ${obj.kind} ${obj.metadata.name} as it is a clusterwide resource type.`); } + } else { + log_debug(yaml_encode(obj)); + throw `kind: ${obj.kind} is unknown from the apiServer.`; } + applied } - for d in deleted { - log_info(`Waiting for ${d.metadata.name} to be deleted`); - d.wait_deleted(60*5); + + fn install_allowed(instance, context, dir, allowed) { + let all = get_objects(context, dir); + let applied_objs = []; + for k in global::FIRST { + for obj in all.filter(|o| o.kind==k) { + applied_objs += install_allowed_obj(obj, allowed, instance.metadata.namespace); + } + } + for obj in all.filter(|o| !global::FIRST.contains(o.kind) && !global::LAST.contains(o.kind)) { + applied_objs += install_allowed_obj(obj, allowed, instance.metadata.namespace); + } + for k in global::LAST { + for obj in all.filter(|o| o.kind==k) { + applied_objs += install_allowed_obj(obj, allowed, instance.metadata.namespace); + } + } + applied_objs } -} \ No newline at end of file + + fn remove(applied, previous, default_ns) { + let deleted = []; + for old in previous { + if ! applied.some(|n| n.kind == old.kind && n.namespace == old.namespace && n.name == old.name) { + let ns = if old.namespace != () {old.namespace} else {default_ns}; + let api = k8s_resource(old.kind, ns); + if api.exist() { + try { + let o = api.get_obj(old.name); + o.delete(); + deleted.push(o); + } catch(e) {} + } + } + } + for d in deleted { + log_info(`Waiting for ${d.metadata.name} to be deleted`); + d.wait_deleted(60*5); + } + } \ No newline at end of file diff --git a/box/vynil/package.yaml b/box/vynil/package.yaml index 446dcc4..fd7efa2 100644 --- a/box/vynil/package.yaml +++ b/box/vynil/package.yaml @@ -2,10 +2,10 @@ apiVersion: vinyl.solidite.fr/v1beta1 kind: Package metadata: + type: system name: vynil category: core description: Vynil controller to manage vynil packages installations - type: system features: - upgrade - auto_config diff --git a/box/vynil/systems/cm.yaml b/box/vynil/systems/cm.yaml deleted file mode 100644 index a1eeaed..0000000 --- a/box/vynil/systems/cm.yaml +++ /dev/null @@ -1,4 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: vynil diff --git a/box/vynil/systems/rbac.yaml.hbs b/box/vynil/systems/rbac.yaml.hbs index 3c137ef..150dcf8 100644 --- a/box/vynil/systems/rbac.yaml.hbs +++ b/box/vynil/systems/rbac.yaml.hbs @@ -2,13 +2,13 @@ apiVersion: v1 kind: ServiceAccount metadata: - name: {{instance.appslug}}-controller + name: vynil-agent automountServiceAccountToken: true --- apiVersion: v1 kind: ServiceAccount metadata: - name: vynil-agent + name: {{instance.appslug}}-controller automountServiceAccountToken: true --- kind: ClusterRole @@ -26,18 +26,6 @@ rules: resources: ["*"] verbs: ["get", "list"] --- -kind: Role -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: {{instance.appslug}}-resources -rules: -- apiGroups: ["batch"] - resources: ["cronjobs", "jobs"] - verbs: ["*"] -- apiGroups: [""] - resources: ["secrets"] - verbs: ["get", "list"] ---- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: @@ -50,30 +38,30 @@ rules: kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: {{instance.namespace}}-{{instance.appslug}}-controller-resources + name: {{instance.namespace}}-vynil-agent-cluster-admin subjects: -- kind: ServiceAccount - namespace: {{instance.namespace}} - name: {{instance.appslug}}-controller - kind: ServiceAccount namespace: {{instance.namespace}} name: vynil-agent roleRef: kind: ClusterRole - name: {{instance.namespace}}-{{instance.appslug}}-resources + name: cluster-admin apiGroup: rbac.authorization.k8s.io --- -kind: RoleBinding +kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: {{instance.appslug}}-controller-resources + name: {{instance.namespace}}-{{instance.appslug}}-controller-resources subjects: - kind: ServiceAccount namespace: {{instance.namespace}} name: {{instance.appslug}}-controller +- kind: ServiceAccount + namespace: {{instance.namespace}} + name: vynil-agent roleRef: - kind: Role - name: {{instance.appslug}}-resources + kind: ClusterRole + name: {{instance.namespace}}-{{instance.appslug}}-resources apiGroup: rbac.authorization.k8s.io --- kind: ClusterRoleBinding @@ -89,15 +77,27 @@ roleRef: name: {{instance.namespace}}-{{instance.appslug}}-admin apiGroup: rbac.authorization.k8s.io --- -kind: ClusterRoleBinding +kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: {{instance.namespace}}-vynil-agent-cluster-admin + name: {{instance.appslug}}-resources +rules: +- apiGroups: ["batch"] + resources: ["cronjobs", "jobs"] + verbs: ["*"] +- apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list"] +--- +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{instance.appslug}}-controller-resources subjects: - kind: ServiceAccount namespace: {{instance.namespace}} - name: vynil-agent + name: {{instance.appslug}}-controller roleRef: - kind: ClusterRole - name: cluster-admin - apiGroup: rbac.authorization.k8s.io \ No newline at end of file + kind: Role + name: {{instance.appslug}}-resources + apiGroup: rbac.authorization.k8s.io diff --git a/common/src/k8sgeneric.rs b/common/src/k8sgeneric.rs index 149bd6d..c291df9 100644 --- a/common/src/k8sgeneric.rs +++ b/common/src/k8sgeneric.rs @@ -110,7 +110,6 @@ impl K8sObject { .contains(&&"conditions".to_string()) { let conditions = status.as_object().unwrap()["conditions"].clone(); - tracing::warn!("Testing conditions: {cond} with {:?}", conditions); if conditions.is_array() && conditions.as_array().unwrap().into_iter().any(|c| { c.is_object() diff --git a/common/src/k8sworkload.rs b/common/src/k8sworkload.rs index 2427561..0ea316b 100644 --- a/common/src/k8sworkload.rs +++ b/common/src/k8sworkload.rs @@ -157,7 +157,6 @@ impl K8sDeploy { if let Some(s) = &job.status { if let Some(conds) = &s.conditions { if let Some(pcond) = conds.iter().find(|c| c.type_ == "Available") { - tracing::warn!(pcond.status); return pcond.status == "True"; } } diff --git a/operator/templates/package.yaml.hbs b/operator/templates/package.yaml.hbs index 3b2fd07..88e1109 100644 --- a/operator/templates/package.yaml.hbs +++ b/operator/templates/package.yaml.hbs @@ -43,8 +43,10 @@ spec: image: {{ agent_image }} imagePullPolicy: IfNotPresent volumeMounts: - - mountPath: /package - name: package + - name: config + mountPath: /etc/vynil + - name: package + mountPath: /package initContainers: - name: unpack args: @@ -80,8 +82,6 @@ spec: volumeMounts: - name: package mountPath: /package - - name: config - mountPath: /etc/vynil {{#if use_secret }} - name: pullsecret mountPath: /secret