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 <Sreejith.Punnapuzha@outlook.com>
Change-Id: I018d96c50e2557da72874a553cfef43b331aa079
This commit is contained in:
Sreejith Punnapuzha 2021-05-24 23:13:27 -05:00
parent 5013bfc23b
commit c1685f11a1
5 changed files with 153 additions and 0 deletions

View File

@ -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

View File

@ -0,0 +1,6 @@
---
- name: apparmor reload
service:
name: apparmor
state: reloaded
become: yes

View File

@ -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

View File

@ -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 <tunables/global>
#
/bin/example.sh {
#include <abstractions/base>
#
/bin/example.sh r,
deny /tmp/sample.txt w,
}
state: present

View File

@ -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"