From c1685f11a18412b0848617dcb36019af270ac3a9 Mon Sep 17 00:00:00 2001 From: Sreejith Punnapuzha Date: Mon, 24 May 2021 23:13:27 -0500 Subject: [PATCH] Add apparmor support to Hostconfig-operator This commit adds apparmor support to hostconfig-operator. with this apparmor support we can add/remove custom apparmor profiles to every nodes managed via hostconfig-operator. Signed-off-by: Sreejith Punnapuzha Change-Id: I018d96c50e2557da72874a553cfef43b331aa079 --- ...tconfig.airshipit.org_hostconfigs_crd.yaml | 15 ++++ .../roles/apparmor/handlers/main.yml | 6 ++ .../roles/apparmor/tasks/main.yml | 39 +++++++++++ demo_examples/example_apparmor.yaml | 25 +++++++ tools/deployment/54_test_apparmor.sh | 68 +++++++++++++++++++ 5 files changed, 153 insertions(+) create mode 100644 airship-host-config/roles/apparmor/handlers/main.yml create mode 100644 airship-host-config/roles/apparmor/tasks/main.yml create mode 100644 demo_examples/example_apparmor.yaml create mode 100755 tools/deployment/54_test_apparmor.sh diff --git a/airship-host-config/deploy/crds/hostconfig.airshipit.org_hostconfigs_crd.yaml b/airship-host-config/deploy/crds/hostconfig.airshipit.org_hostconfigs_crd.yaml index 3e35f24..4f06a89 100644 --- a/airship-host-config/deploy/crds/hostconfig.airshipit.org_hostconfigs_crd.yaml +++ b/airship-host-config/deploy/crds/hostconfig.airshipit.org_hostconfigs_crd.yaml @@ -74,6 +74,21 @@ spec: type: object description: "The configuration details that needs to be performed on the targeted kubernetes nodes." properties: + apparmor: + description: "An array of apparmor configuration to be performed on the target nodes." + type: array + items: + type: object + properties: + filename: + type: string + profile: + type: string + state: + type: string + required: + - filename + - state exec: description: "An array of script configuration that would be executed on the target nodes" type: array diff --git a/airship-host-config/roles/apparmor/handlers/main.yml b/airship-host-config/roles/apparmor/handlers/main.yml new file mode 100644 index 0000000..1a787b0 --- /dev/null +++ b/airship-host-config/roles/apparmor/handlers/main.yml @@ -0,0 +1,6 @@ +--- +- name: apparmor reload + service: + name: apparmor + state: reloaded + become: yes diff --git a/airship-host-config/roles/apparmor/tasks/main.yml b/airship-host-config/roles/apparmor/tasks/main.yml new file mode 100644 index 0000000..ffc602d --- /dev/null +++ b/airship-host-config/roles/apparmor/tasks/main.yml @@ -0,0 +1,39 @@ +--- +- name: install > Packages + package: + name: apparmor + state: present + become: yes + +- name: configs > Ensures destination directories exists + file: + path: /etc/apparmor.d + state: directory + recurse: true + owner: root + group: root + mode: "0755" + become: yes + +- name: configs > Create files + copy: + content: "{{ item.profile }}" + dest: "/etc/apparmor.d/{{ item.filename }}" + owner: root + group: root + mode: "0644" + when: item.state|default('present') != 'absent' + with_items: "{{ config.apparmor }}" + become: yes + notify: + - apparmor reload + +- name: configs > Remove files + file: + path: "/etc/apparmor.d/{{ item.filename }}" + state: absent + when: item.state|default('present') == 'absent' + with_items: "{{ config.apparmor }}" + become: yes + notify: + - apparmor reload diff --git a/demo_examples/example_apparmor.yaml b/demo_examples/example_apparmor.yaml new file mode 100644 index 0000000..ddba3f1 --- /dev/null +++ b/demo_examples/example_apparmor.yaml @@ -0,0 +1,25 @@ +# This CR when executed configures the passed sysctl and ulimit +# configuration on the kubernetes master nodes. + +apiVersion: hostconfig.airshipit.org/v1alpha1 +kind: HostConfig +metadata: + name: example-apparmor +spec: + host_groups: + - name: "kubernetes.io/hostname" + values: + - "hostconfig-control-plane" + config: + apparmor: + - filename: bin.example.sh + profile: | + #include + # + /bin/example.sh { + #include + # + /bin/example.sh r, + deny /tmp/sample.txt w, + } + state: present diff --git a/tools/deployment/54_test_apparmor.sh b/tools/deployment/54_test_apparmor.sh new file mode 100755 index 0000000..cd44a58 --- /dev/null +++ b/tools/deployment/54_test_apparmor.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash + +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +set -xe + +export TIMEOUT=${TIMEOUT:-3600} +export AIRSHIP_HOSTCONFIG=${AIRSHIP_HOSTCONFIG:-$PWD} + +check_status(){ + hostconfig=$1 + end=$(($(date +%s) + $TIMEOUT)) + while true; do + # Getting the failed and unreachable nodes status + failures=$(kubectl get hostconfig $hostconfig -o jsonpath='{.status.ansibleSummary.failures}') + unreachable=$(kubectl get hostconfig $hostconfig -o jsonpath='{.status.ansibleSummary.unreachable}') + if [[ $failures == "map[]" && $unreachable == "map[]" ]]; then + kubectl get hostconfig $hostconfig -o json + hosts=$2 + ok=$(kubectl get hostconfig $hostconfig -o json | jq '.status.ansibleSummary.ok | keys') + hostNames=$(kubectl get hostconfig $hostconfig -o json | jq '.status.hostConfigStatus | keys') + ok_array=${ok[@]} + hostNames_array=${hostNames[@]} + # Checking if all hosts has executed + if [ "$hosts" == "$ok_array" ] && [ "$hosts" == "$hostNames_array" ]; then + if [[ `sudo docker exec $3 bash -c "echo 'touch /tmp/sample.txt' >> /bin/example.sh; chmod +x /bin/example.sh; /bin/example.sh; ls /tmp/sample.txt"` ]]; then + echo "$hostconfig hostconfig executed successfully" + return 0 + else + echo "$hostconfig hostconfig execution failed!" + return 1 + fi + else + # Failing the execution is the hosts hasn't matched. + echo "$hostconfig hostconfig execution failed!" + exit 1 + fi + elif [ -z "$failures" ] && [ -z "$unreachable" ]; then + # Waiting for the HostConfig CR status till timeout is reached. + now=$(date +%s) + if [ $now -gt $end ]; then + kubectl get hostconfig $hostconfig -o json + echo -e "HostConfig CR execution not completed even after timeout" + exit 1 + fi + else + # Failing the execution if the HostConfig CR object execution has failed. + kubectl get hostconfig $hostconfig -o json + echo "HostConfig CR execution failed" + exit 1 + fi + sleep 30 + done +} + +# Checking HostConfig CR packages installation +kubectl apply -f $AIRSHIP_HOSTCONFIG/demo_examples/example_apparmor.yaml +check_status example-apparmor '[ "hostconfig-control-plane" ]' "hostconfig-control-plane"