diff --git a/nova/templates/bin/_nova-compute-init.sh.tpl b/nova/templates/bin/_nova-compute-init.sh.tpl new file mode 100644 index 0000000000..b163e82fd5 --- /dev/null +++ b/nova/templates/bin/_nova-compute-init.sh.tpl @@ -0,0 +1,25 @@ +#!/bin/bash + +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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 -ex + +# Make the Nova Instances Dir as this is not autocreated. +mkdir -p /var/lib/nova/instances + +# Set Ownership of nova dirs to the nova user +chown ${NOVA_USER_UID} /var/lib/nova /var/lib/nova/instances diff --git a/nova/templates/bin/_nova-compute.sh.tpl b/nova/templates/bin/_nova-compute.sh.tpl index d890be95da..15f977bfd0 100644 --- a/nova/templates/bin/_nova-compute.sh.tpl +++ b/nova/templates/bin/_nova-compute.sh.tpl @@ -18,9 +18,6 @@ limitations under the License. set -ex -# Make the Nova Instances Dir as this is not autocreated. -mkdir -p /var/lib/nova/instances - console_kind="{{- .Values.console.console_kind -}}" if [ "${console_kind}" == "novnc" ] ; then exec nova-compute \ @@ -29,4 +26,4 @@ exec nova-compute \ else exec nova-compute \ --config-file /etc/nova/nova.conf -fi \ No newline at end of file +fi diff --git a/nova/templates/configmap-bin.yaml b/nova/templates/configmap-bin.yaml index 8196798d8b..5841861cfc 100644 --- a/nova/templates/configmap-bin.yaml +++ b/nova/templates/configmap-bin.yaml @@ -49,6 +49,8 @@ data: {{ tuple "bin/_nova-api-metadata.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} nova-compute.sh: | {{ tuple "bin/_nova-compute.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} + nova-compute-init.sh: | +{{ tuple "bin/_nova-compute-init.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} nova-conductor.sh: | {{ tuple "bin/_nova-conductor.sh.tpl" . | include "helm-toolkit.utils.template" | indent 4 }} nova-consoleauth.sh: | diff --git a/nova/templates/configmap-etc.yaml b/nova/templates/configmap-etc.yaml index 46492168e9..21623a7f78 100644 --- a/nova/templates/configmap-etc.yaml +++ b/nova/templates/configmap-etc.yaml @@ -110,4 +110,14 @@ data: {{- tuple .Values.conf.libvirtd "etc/_libvirtd.conf.tpl" . | include "helm-toolkit.utils.configmap_templater" }} qemu.conf: |+ {{- tuple .Values.conf.qemu "etc/_qemu.conf.tpl" . | include "helm-toolkit.utils.configmap_templater" }} + nova_sudoers: |+ +{{- tuple .Values.conf.neutron_sudoers "etc/_nova_sudoers.tpl" . | include "helm-toolkit.utils.configmap_templater" }} + rootwrap.conf: |+ +{{- tuple .Values.conf.rootwrap "etc/_rootwrap.conf.tpl" . | include "helm-toolkit.utils.configmap_templater" }} + api-metadata.filters: |+ +{{- tuple .Values.conf.rootwrap_filters.api_metadata "etc/rootwrap.d/_api-metadata.filters.tpl" . | include "helm-toolkit.utils.configmap_templater" }} + compute.filters: |+ +{{- tuple .Values.conf.rootwrap_filters.compute "etc/rootwrap.d/_compute.filters.tpl" . | include "helm-toolkit.utils.configmap_templater" }} + network.filters: |+ +{{- tuple .Values.conf.rootwrap_filters.network "etc/rootwrap.d/_network.filters.tpl" . | include "helm-toolkit.utils.configmap_templater" }} {{- end }} diff --git a/nova/templates/daemonset-compute.yaml b/nova/templates/daemonset-compute.yaml index ad39403fc2..a0f5443103 100644 --- a/nova/templates/daemonset-compute.yaml +++ b/nova/templates/daemonset-compute.yaml @@ -36,17 +36,34 @@ spec: spec: nodeSelector: {{ .Values.labels.agent.compute.node_selector_key }}: {{ .Values.labels.agent.compute.node_selector_value }} - securityContext: - runAsUser: 0 hostNetwork: true hostPID: true dnsPolicy: ClusterFirstWithHostNet initContainers: {{ tuple $envAll $dependencies $mounts_nova_compute_init | include "helm-toolkit.snippets.kubernetes_entrypoint_init_container" | indent 8 }} + - name: nova-compute-init + image: {{ .Values.images.compute }} + imagePullPolicy: {{ .Values.images.pull_policy }} + securityContext: + runAsUser: 0 + env: + - name: NOVA_USER_UID + value: "{{ .Values.pod.user.nova.uid }}" + command: + - /tmp/nova-compute-init.sh + volumeMounts: + - name: nova-bin + mountPath: /tmp/nova-compute-init.sh + subPath: nova-compute-init.sh + readOnly: true + - name: varlibnova + mountPath: /var/lib/nova {{- if .Values.ceph.enabled }} - name: ceph-keyring-placement image: {{ .Values.images.compute }} imagePullPolicy: {{ .Values.images.pull_policy }} + securityContext: + runAsUser: {{ .Values.pod.user.nova.uid }} env: - name: CEPH_CINDER_USER value: "{{ .Values.ceph.cinder_user }}" @@ -69,12 +86,12 @@ spec: subPath: key readOnly: true {{ end }} - - name: nova-compute-init + - name: nova-compute-vnc-init image: {{ .Values.images.compute }} imagePullPolicy: {{ .Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.compute | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} securityContext: - privileged: true + runAsUser: {{ .Values.pod.user.nova.uid }} command: - /tmp/nova-vnc-compute-init.sh volumeMounts: @@ -82,29 +99,6 @@ spec: mountPath: /tmp/nova-vnc-compute-init.sh subPath: nova-vnc-compute-init.sh readOnly: true - - name: nova-etc - mountPath: /etc/nova/nova.conf - subPath: nova.conf - readOnly: true - - name: nova-etc - mountPath: /etc/nova/api-paste.ini - subPath: api-paste.ini - readOnly: true - - name: nova-etc - mountPath: /etc/ceph/ceph.conf - subPath: ceph.conf - readOnly: true - - mountPath: /lib/modules - name: libmodules - readOnly: true - - name: varlibnova - mountPath: /var/lib/nova - - name: varliblibvirt - mountPath: /var/lib/libvirt - - name: run - mountPath: /run - - name: cgroup - mountPath: /sys/fs/cgroup - name: pod-shared mountPath: /tmp/pod-shared containers: @@ -113,6 +107,7 @@ spec: imagePullPolicy: {{ .Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.compute | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} securityContext: + runAsUser: {{ .Values.pod.user.nova.uid }} privileged: true {{- if .Values.ceph.enabled }} env: @@ -144,6 +139,29 @@ spec: mountPath: /etc/nova/policy.yaml subPath: policy.yaml readOnly: true + - name: nova-etc + # NOTE (Portdirect): We mount here to overide Kollas custom + # sudoers file when using Kolla images, this location will + # also work fine for other images. + mountPath: /etc/sudoers.d/kolla_nova_sudoers + subPath: nova_sudoers + readOnly: true + - name: nova-etc + mountPath: /etc/nova/rootwrap.conf + subPath: rootwrap.conf + readOnly: true + - name: nova-etc + mountPath: /etc/nova/rootwrap.d/api-metadata.filters + subPath: api-metadata.filters + readOnly: true + - name: nova-etc + mountPath: /etc/nova/rootwrap.d/compute.filters + subPath: compute.filters + readOnly: true + - name: nova-etc + mountPath: /etc/nova/rootwrap.d/network.filters + subPath: network.filters + readOnly: true {{- if .Values.ceph.enabled }} - name: etcceph mountPath: /etc/ceph diff --git a/nova/templates/daemonset-libvirt.yaml b/nova/templates/daemonset-libvirt.yaml index d6f1097fef..623caa3fe5 100644 --- a/nova/templates/daemonset-libvirt.yaml +++ b/nova/templates/daemonset-libvirt.yaml @@ -36,8 +36,6 @@ spec: spec: nodeSelector: {{ .Values.labels.agent.libvirt.node_selector_key }}: {{ .Values.labels.agent.libvirt.node_selector_value }} - securityContext: - runAsUser: 0 hostNetwork: true hostPID: true dnsPolicy: ClusterFirstWithHostNet @@ -47,6 +45,8 @@ spec: - name: ceph-keyring-placement image: {{ .Values.images.libvirt }} imagePullPolicy: {{ .Values.images.pull_policy }} + securityContext: + runAsUser: 0 env: - name: CEPH_CINDER_USER value: "{{ .Values.ceph.cinder_user }}" @@ -77,6 +77,7 @@ spec: {{ tuple $envAll $envAll.Values.pod.resources.libvirt | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} securityContext: privileged: true + runAsUser: 0 {{- if .Values.ceph.enabled }} env: - name: CEPH_CINDER_USER @@ -97,6 +98,13 @@ spec: {{- end }} command: - /tmp/libvirt.sh + {{- if .Values.ceph.enabled }} + lifecycle: + postStart: + exec: + command: + - /tmp/ceph-secret-define.sh + {{- end }} volumeMounts: - name: nova-bin mountPath: /tmp/libvirt.sh diff --git a/nova/templates/deployment-api-metadata.yaml b/nova/templates/deployment-api-metadata.yaml index e0ef3c7003..718865bb76 100644 --- a/nova/templates/deployment-api-metadata.yaml +++ b/nova/templates/deployment-api-metadata.yaml @@ -47,6 +47,8 @@ spec: image: {{ .Values.images.api }} imagePullPolicy: {{ .Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.api_metadata | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} + securityContext: + runAsUser: {{ .Values.pod.user.nova.uid }} command: - /tmp/nova-api-metadata.sh - start @@ -90,6 +92,29 @@ spec: mountPath: /etc/nova/policy.yaml subPath: policy.yaml readOnly: true + - name: nova-etc + # NOTE (Portdirect): We mount here to overide Kollas custom + # sudoers file when using Kolla images, this location will + # also work fine for other images. + mountPath: /etc/sudoers.d/kolla_nova_sudoers + subPath: nova_sudoers + readOnly: true + - name: nova-etc + mountPath: /etc/nova/rootwrap.conf + subPath: rootwrap.conf + readOnly: true + - name: nova-etc + mountPath: /etc/nova/rootwrap.d/api-metadata.filters + subPath: api-metadata.filters + readOnly: true + - name: nova-etc + mountPath: /etc/nova/rootwrap.d/compute.filters + subPath: compute.filters + readOnly: true + - name: nova-etc + mountPath: /etc/nova/rootwrap.d/network.filters + subPath: network.filters + readOnly: true {{ if $mounts_nova_api_metadata.volumeMounts }}{{ toYaml $mounts_nova_api_metadata.volumeMounts | indent 12 }}{{ end }} volumes: - name: nova-bin diff --git a/nova/templates/deployment-api-osapi.yaml b/nova/templates/deployment-api-osapi.yaml index 7f582f9431..d9b663ff84 100644 --- a/nova/templates/deployment-api-osapi.yaml +++ b/nova/templates/deployment-api-osapi.yaml @@ -47,6 +47,8 @@ spec: image: {{ .Values.images.api }} imagePullPolicy: {{ .Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.api | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} + securityContext: + runAsUser: {{ .Values.pod.user.nova.uid }} command: - /tmp/nova-api.sh - start diff --git a/nova/templates/deployment-conductor.yaml b/nova/templates/deployment-conductor.yaml index 6029bdf760..f026d39760 100644 --- a/nova/templates/deployment-conductor.yaml +++ b/nova/templates/deployment-conductor.yaml @@ -46,6 +46,8 @@ spec: image: {{ .Values.images.conductor }} imagePullPolicy: {{ .Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.conductor | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} + securityContext: + runAsUser: {{ .Values.pod.user.nova.uid }} command: - /tmp/nova-conductor.sh volumeMounts: diff --git a/nova/templates/deployment-consoleauth.yaml b/nova/templates/deployment-consoleauth.yaml index 810bc2aaae..ee5155357c 100644 --- a/nova/templates/deployment-consoleauth.yaml +++ b/nova/templates/deployment-consoleauth.yaml @@ -46,6 +46,8 @@ spec: image: {{ .Values.images.consoleauth }} imagePullPolicy: {{ .Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.consoleauth | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} + securityContext: + runAsUser: {{ .Values.pod.user.nova.uid }} command: - /tmp/nova-consoleauth.sh volumeMounts: diff --git a/nova/templates/deployment-novncproxy.yaml b/nova/templates/deployment-novncproxy.yaml index 095524eec5..1d16130790 100644 --- a/nova/templates/deployment-novncproxy.yaml +++ b/nova/templates/deployment-novncproxy.yaml @@ -48,6 +48,8 @@ spec: image: {{ .Values.images.novncproxy }} imagePullPolicy: {{ .Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.novncproxy | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} + securityContext: + runAsUser: {{ .Values.pod.user.nova.uid }} command: - /tmp/nova-vnc-proxy-init.sh volumeMounts: diff --git a/nova/templates/deployment-scheduler.yaml b/nova/templates/deployment-scheduler.yaml index 586eb5a159..82293aabc8 100644 --- a/nova/templates/deployment-scheduler.yaml +++ b/nova/templates/deployment-scheduler.yaml @@ -46,6 +46,8 @@ spec: image: {{ .Values.images.scheduler }} imagePullPolicy: {{ .Values.images.pull_policy }} {{ tuple $envAll $envAll.Values.pod.resources.scheduler | include "helm-toolkit.snippets.kubernetes_resources" | indent 10 }} + securityContext: + runAsUser: {{ .Values.pod.user.nova.uid }} command: - /tmp/nova-scheduler.sh volumeMounts: diff --git a/nova/templates/etc/_nova_sudoers.tpl b/nova/templates/etc/_nova_sudoers.tpl new file mode 100644 index 0000000000..e4a16efd93 --- /dev/null +++ b/nova/templates/etc/_nova_sudoers.tpl @@ -0,0 +1,20 @@ +{{/* +Copyright 2017 The Openstack-Helm Authors. + +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. +*/}} + +# This sudoers file supports rootwrap for both Kolla and LOCI Images. +Defaults !requiretty +Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin:/var/lib/openstack/bin:/var/lib/kolla/venv/bin" +nova ALL = (root) NOPASSWD: /var/lib/kolla/venv/bin/nova-rootwrap /etc/nova/rootwrap.conf *, /var/lib/openstack/bin/nova-rootwrap /etc/nova/rootwrap.conf * diff --git a/nova/templates/etc/_rootwrap.conf.tpl b/nova/templates/etc/_rootwrap.conf.tpl new file mode 100644 index 0000000000..74168c8198 --- /dev/null +++ b/nova/templates/etc/_rootwrap.conf.tpl @@ -0,0 +1,27 @@ +# Configuration for nova-rootwrap +# This file should be owned by (and only-writeable by) the root user + +[DEFAULT] +# List of directories to load filter definitions from (separated by ','). +# These directories MUST all be only writeable by root ! +filters_path=/etc/nova/rootwrap.d,/usr/share/nova/rootwrap + +# List of directories to search executables in, in case filters do not +# explicitely specify a full path (separated by ',') +# If not specified, defaults to system PATH environment variable. +# These directories MUST all be only writeable by root ! +exec_dirs=/sbin,/usr/sbin,/bin,/usr/bin,/usr/local/bin,/usr/local/sbin,/var/lib/openstack/bin,/var/lib/kolla/venv/bin + +# Enable logging to syslog +# Default value is False +use_syslog=False + +# Which syslog facility to use. +# Valid values include auth, authpriv, syslog, local0, local1... +# Default value is 'syslog' +syslog_log_facility=syslog + +# Which messages to log. +# INFO means log all usage +# ERROR means only log unsuccessful attempts +syslog_log_level=ERROR diff --git a/nova/templates/etc/rootwrap.d/_api-metadata.filters.tpl b/nova/templates/etc/rootwrap.d/_api-metadata.filters.tpl new file mode 100644 index 0000000000..1aa6f83e68 --- /dev/null +++ b/nova/templates/etc/rootwrap.d/_api-metadata.filters.tpl @@ -0,0 +1,13 @@ +# nova-rootwrap command filters for api-metadata nodes +# This is needed on nova-api hosts running with "metadata" in enabled_apis +# or when running nova-api-metadata +# This file should be owned by (and only-writeable by) the root user + +[Filters] +# nova/network/linux_net.py: 'ip[6]tables-save' % (cmd, '-t', ... +iptables-save: CommandFilter, iptables-save, root +ip6tables-save: CommandFilter, ip6tables-save, root + +# nova/network/linux_net.py: 'ip[6]tables-restore' % (cmd,) +iptables-restore: CommandFilter, iptables-restore, root +ip6tables-restore: CommandFilter, ip6tables-restore, root diff --git a/nova/templates/etc/rootwrap.d/_compute.filters.tpl b/nova/templates/etc/rootwrap.d/_compute.filters.tpl new file mode 100644 index 0000000000..07f18eab3b --- /dev/null +++ b/nova/templates/etc/rootwrap.d/_compute.filters.tpl @@ -0,0 +1,259 @@ +# nova-rootwrap command filters for compute nodes +# This file should be owned by (and only-writeable by) the root user + +[Filters] +# nova/virt/disk/mount/api.py: 'kpartx', '-a', device +# nova/virt/disk/mount/api.py: 'kpartx', '-d', device +kpartx: CommandFilter, kpartx, root + +# nova/virt/xenapi/vm_utils.py: tune2fs, -O ^has_journal, part_path +# nova/virt/xenapi/vm_utils.py: tune2fs, -j, partition_path +tune2fs: CommandFilter, tune2fs, root + +# nova/virt/disk/mount/api.py: 'mount', mapped_device +# nova/virt/disk/api.py: 'mount', '-o', 'bind', src, target +# nova/virt/xenapi/vm_utils.py: 'mount', '-t', 'ext2,ext3,ext4,reiserfs'.. +# nova/virt/configdrive.py: 'mount', device, mountdir +# nova/virt/libvirt/volume.py: 'mount', '-t', 'sofs' ... +mount: CommandFilter, mount, root + +# nova/virt/disk/mount/api.py: 'umount', mapped_device +# nova/virt/disk/api.py: 'umount' target +# nova/virt/xenapi/vm_utils.py: 'umount', dev_path +# nova/virt/configdrive.py: 'umount', mountdir +umount: CommandFilter, umount, root + +# nova/virt/disk/mount/nbd.py: 'qemu-nbd', '-c', device, image +# nova/virt/disk/mount/nbd.py: 'qemu-nbd', '-d', device +qemu-nbd: CommandFilter, qemu-nbd, root + +# nova/virt/disk/mount/loop.py: 'losetup', '--find', '--show', image +# nova/virt/disk/mount/loop.py: 'losetup', '--detach', device +losetup: CommandFilter, losetup, root + +# nova/virt/disk/vfs/localfs.py: 'blkid', '-o', 'value', '-s', 'TYPE', device +blkid: CommandFilter, blkid, root + +# nova/virt/libvirt/utils.py: 'blockdev', '--getsize64', path +# nova/virt/disk/mount/nbd.py: 'blockdev', '--flushbufs', device +blockdev: RegExpFilter, blockdev, root, blockdev, (--getsize64|--flushbufs), /dev/.* + +# nova/virt/disk/vfs/localfs.py: 'tee', canonpath +tee: CommandFilter, tee, root + +# nova/virt/disk/vfs/localfs.py: 'mkdir', canonpath +mkdir: CommandFilter, mkdir, root + +# nova/virt/disk/vfs/localfs.py: 'chown' +# nova/virt/libvirt/connection.py: 'chown', os.getuid( console_log +# nova/virt/libvirt/connection.py: 'chown', os.getuid( console_log +# nova/virt/libvirt/connection.py: 'chown', 'root', basepath('disk') +chown: CommandFilter, chown, root + +# nova/virt/disk/vfs/localfs.py: 'chmod' +chmod: CommandFilter, chmod, root + +# nova/virt/libvirt/vif.py: 'ip', 'tuntap', 'add', dev, 'mode', 'tap' +# nova/virt/libvirt/vif.py: 'ip', 'link', 'set', dev, 'up' +# nova/virt/libvirt/vif.py: 'ip', 'link', 'delete', dev +# nova/network/linux_net.py: 'ip', 'addr', 'add', str(floating_ip)+'/32'i.. +# nova/network/linux_net.py: 'ip', 'addr', 'del', str(floating_ip)+'/32'.. +# nova/network/linux_net.py: 'ip', 'addr', 'add', '169.254.169.254/32',.. +# nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', dev, 'scope',.. +# nova/network/linux_net.py: 'ip', 'addr', 'del/add', ip_params, dev) +# nova/network/linux_net.py: 'ip', 'addr', 'del', params, fields[-1] +# nova/network/linux_net.py: 'ip', 'addr', 'add', params, bridge +# nova/network/linux_net.py: 'ip', '-f', 'inet6', 'addr', 'change', .. +# nova/network/linux_net.py: 'ip', 'link', 'set', 'dev', dev, 'promisc',.. +# nova/network/linux_net.py: 'ip', 'link', 'add', 'link', bridge_if ... +# nova/network/linux_net.py: 'ip', 'link', 'set', interface, address,.. +# nova/network/linux_net.py: 'ip', 'link', 'set', interface, 'up' +# nova/network/linux_net.py: 'ip', 'link', 'set', bridge, 'up' +# nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', interface, .. +# nova/network/linux_net.py: 'ip', 'link', 'set', dev, address, .. +# nova/network/linux_net.py: 'ip', 'link', 'set', dev, 'up' +# nova/network/linux_net.py: 'ip', 'route', 'add', .. +# nova/network/linux_net.py: 'ip', 'route', 'del', . +# nova/network/linux_net.py: 'ip', 'route', 'show', 'dev', dev +ip: CommandFilter, ip, root + +# nova/virt/libvirt/vif.py: 'tunctl', '-b', '-t', dev +# nova/network/linux_net.py: 'tunctl', '-b', '-t', dev +tunctl: CommandFilter, tunctl, root + +# nova/virt/libvirt/vif.py: 'ovs-vsctl', ... +# nova/virt/libvirt/vif.py: 'ovs-vsctl', 'del-port', ... +# nova/network/linux_net.py: 'ovs-vsctl', .... +ovs-vsctl: CommandFilter, ovs-vsctl, root + +# nova/virt/libvirt/vif.py: 'vrouter-port-control', ... +vrouter-port-control: CommandFilter, vrouter-port-control, root + +# nova/virt/libvirt/vif.py: 'ebrctl', ... +ebrctl: CommandFilter, ebrctl, root + +# nova/virt/libvirt/vif.py: 'mm-ctl', ... +mm-ctl: CommandFilter, mm-ctl, root + +# nova/network/linux_net.py: 'ovs-ofctl', .... +ovs-ofctl: CommandFilter, ovs-ofctl, root + +# nova/virt/libvirt/connection.py: 'dd', if=%s % virsh_output, ... +dd: CommandFilter, dd, root + +# nova/virt/xenapi/volume_utils.py: 'iscsiadm', '-m', ... +iscsiadm: CommandFilter, iscsiadm, root + +# nova/virt/libvirt/volume/aoe.py: 'aoe-revalidate', aoedev +# nova/virt/libvirt/volume/aoe.py: 'aoe-discover' +aoe-revalidate: CommandFilter, aoe-revalidate, root +aoe-discover: CommandFilter, aoe-discover, root + +# nova/virt/xenapi/vm_utils.py: parted, --script, ... +# nova/virt/xenapi/vm_utils.py: 'parted', '--script', dev_path, ..*. +parted: CommandFilter, parted, root + +# nova/virt/xenapi/vm_utils.py: 'pygrub', '-qn', dev_path +pygrub: CommandFilter, pygrub, root + +# nova/virt/xenapi/vm_utils.py: fdisk %(dev_path)s +fdisk: CommandFilter, fdisk, root + +# nova/virt/xenapi/vm_utils.py: e2fsck, -f, -p, partition_path +# nova/virt/disk/api.py: e2fsck, -f, -p, image +e2fsck: CommandFilter, e2fsck, root + +# nova/virt/xenapi/vm_utils.py: resize2fs, partition_path +# nova/virt/disk/api.py: resize2fs, image +resize2fs: CommandFilter, resize2fs, root + +# nova/network/linux_net.py: 'ip[6]tables-save' % (cmd, '-t', ... +iptables-save: CommandFilter, iptables-save, root +ip6tables-save: CommandFilter, ip6tables-save, root + +# nova/network/linux_net.py: 'ip[6]tables-restore' % (cmd,) +iptables-restore: CommandFilter, iptables-restore, root +ip6tables-restore: CommandFilter, ip6tables-restore, root + +# nova/network/linux_net.py: 'arping', '-U', floating_ip, '-A', '-I', ... +# nova/network/linux_net.py: 'arping', '-U', network_ref['dhcp_server'],.. +arping: CommandFilter, arping, root + +# nova/network/linux_net.py: 'dhcp_release', dev, address, mac_address +dhcp_release: CommandFilter, dhcp_release, root + +# nova/network/linux_net.py: 'kill', '-9', pid +# nova/network/linux_net.py: 'kill', '-HUP', pid +kill_dnsmasq: KillFilter, root, /usr/sbin/dnsmasq, -9, -HUP + +# nova/network/linux_net.py: 'kill', pid +kill_radvd: KillFilter, root, /usr/sbin/radvd + +# nova/network/linux_net.py: dnsmasq call +dnsmasq: EnvFilter, env, root, CONFIG_FILE=, NETWORK_ID=, dnsmasq + +# nova/network/linux_net.py: 'radvd', '-C', '%s' % _ra_file(dev, 'conf'.. +radvd: CommandFilter, radvd, root + +# nova/network/linux_net.py: 'brctl', 'addbr', bridge +# nova/network/linux_net.py: 'brctl', 'setfd', bridge, 0 +# nova/network/linux_net.py: 'brctl', 'stp', bridge, 'off' +# nova/network/linux_net.py: 'brctl', 'addif', bridge, interface +brctl: CommandFilter, brctl, root + +# nova/virt/libvirt/utils.py: 'mkswap' +# nova/virt/xenapi/vm_utils.py: 'mkswap' +mkswap: CommandFilter, mkswap, root + +# nova/virt/libvirt/utils.py: 'nova-idmapshift' +nova-idmapshift: CommandFilter, nova-idmapshift, root + +# nova/virt/xenapi/vm_utils.py: 'mkfs' +# nova/utils.py: 'mkfs', fs, path, label +mkfs: CommandFilter, mkfs, root + +# nova/virt/libvirt/utils.py: 'qemu-img' +qemu-img: CommandFilter, qemu-img, root + +# nova/virt/disk/vfs/localfs.py: 'readlink', '-e' +readlink: CommandFilter, readlink, root + +# nova/virt/disk/api.py: +mkfs.ext3: CommandFilter, mkfs.ext3, root +mkfs.ext4: CommandFilter, mkfs.ext4, root +mkfs.ntfs: CommandFilter, mkfs.ntfs, root + +# nova/virt/libvirt/connection.py: +lvremove: CommandFilter, lvremove, root + +# nova/virt/libvirt/utils.py: +lvcreate: CommandFilter, lvcreate, root + +# nova/virt/libvirt/utils.py: +lvs: CommandFilter, lvs, root + +# nova/virt/libvirt/utils.py: +vgs: CommandFilter, vgs, root + +# nova/utils.py:read_file_as_root: 'cat', file_path +# (called from nova/virt/disk/vfs/localfs.py:VFSLocalFS.read_file) +read_passwd: RegExpFilter, cat, root, cat, (/var|/usr)?/tmp/openstack-vfs-localfs[^/]+/etc/passwd +read_shadow: RegExpFilter, cat, root, cat, (/var|/usr)?/tmp/openstack-vfs-localfs[^/]+/etc/shadow + +# os-brick needed commands +read_initiator: ReadFileFilter, /etc/iscsi/initiatorname.iscsi +multipath: CommandFilter, multipath, root +# multipathd show status +multipathd: CommandFilter, multipathd, root +systool: CommandFilter, systool, root +vgc-cluster: CommandFilter, vgc-cluster, root +# os_brick/initiator/connector.py +drv_cfg: CommandFilter, /opt/emc/scaleio/sdc/bin/drv_cfg, root, /opt/emc/scaleio/sdc/bin/drv_cfg, --query_guid + +# TODO(smcginnis) Temporary fix. +# Need to pull in os-brick os-brick.filters file instead and clean +# out stale brick values from this file. +scsi_id: CommandFilter, /lib/udev/scsi_id, root +# os_brick.privileged.default oslo.privsep context +# This line ties the superuser privs with the config files, context name, +# and (implicitly) the actual python code invoked. +privsep-rootwrap: RegExpFilter, privsep-helper, root, privsep-helper, --config-file, /etc/(?!\.\.).*, --privsep_context, os_brick.privileged.default, --privsep_sock_path, /tmp/.* + +# nova/storage/linuxscsi.py: sg_scan device +sg_scan: CommandFilter, sg_scan, root + +# nova/volume/encryptors/cryptsetup.py: +# nova/volume/encryptors/luks.py: +ln: RegExpFilter, ln, root, ln, --symbolic, --force, /dev/mapper/crypt-.+, .+ + +# nova/volume/encryptors.py: +# nova/virt/libvirt/dmcrypt.py: +cryptsetup: CommandFilter, cryptsetup, root + +# nova/virt/xenapi/vm_utils.py: +xenstore-read: CommandFilter, xenstore-read, root + +# nova/virt/libvirt/utils.py: +rbd: CommandFilter, rbd, root + +# nova/virt/libvirt/utils.py: 'shred', '-n3', '-s%d' % volume_size, path +shred: CommandFilter, shred, root + +# nova/virt/libvirt/volume.py: 'cp', '/dev/stdin', delete_control.. +cp: CommandFilter, cp, root + +# nova/virt/xenapi/vm_utils.py: +sync: CommandFilter, sync, root + +# nova/virt/libvirt/imagebackend.py: +ploop: RegExpFilter, ploop, root, ploop, restore-descriptor, .* +prl_disk_tool: RegExpFilter, prl_disk_tool, root, prl_disk_tool, resize, --size, .*M$, --resize_partition, --hdd, .* + +# nova/virt/libvirt/utils.py: 'xend', 'status' +xend: CommandFilter, xend, root + +# nova/virt/libvirt/utils.py: +touch: CommandFilter, touch, root + +# nova/virt/libvirt/volume/vzstorage.py +pstorage-mount: CommandFilter, pstorage-mount, root diff --git a/nova/templates/etc/rootwrap.d/_network.filters.tpl b/nova/templates/etc/rootwrap.d/_network.filters.tpl new file mode 100644 index 0000000000..52b7130ea8 --- /dev/null +++ b/nova/templates/etc/rootwrap.d/_network.filters.tpl @@ -0,0 +1,91 @@ +# nova-rootwrap command filters for network nodes +# This file should be owned by (and only-writeable by) the root user + +[Filters] +# nova/virt/libvirt/vif.py: 'ip', 'tuntap', 'add', dev, 'mode', 'tap' +# nova/virt/libvirt/vif.py: 'ip', 'link', 'set', dev, 'up' +# nova/virt/libvirt/vif.py: 'ip', 'link', 'delete', dev +# nova/network/linux_net.py: 'ip', 'addr', 'add', str(floating_ip)+'/32'i.. +# nova/network/linux_net.py: 'ip', 'addr', 'del', str(floating_ip)+'/32'.. +# nova/network/linux_net.py: 'ip', 'addr', 'add', '169.254.169.254/32',.. +# nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', dev, 'scope',.. +# nova/network/linux_net.py: 'ip', 'addr', 'del/add', ip_params, dev) +# nova/network/linux_net.py: 'ip', 'addr', 'del', params, fields[-1] +# nova/network/linux_net.py: 'ip', 'addr', 'add', params, bridge +# nova/network/linux_net.py: 'ip', '-f', 'inet6', 'addr', 'change', .. +# nova/network/linux_net.py: 'ip', 'link', 'set', 'dev', dev, 'promisc',.. +# nova/network/linux_net.py: 'ip', 'link', 'add', 'link', bridge_if ... +# nova/network/linux_net.py: 'ip', 'link', 'set', interface, address,.. +# nova/network/linux_net.py: 'ip', 'link', 'set', interface, 'up' +# nova/network/linux_net.py: 'ip', 'link', 'set', bridge, 'up' +# nova/network/linux_net.py: 'ip', 'addr', 'show', 'dev', interface, .. +# nova/network/linux_net.py: 'ip', 'link', 'set', dev, address, .. +# nova/network/linux_net.py: 'ip', 'link', 'set', dev, 'up' +# nova/network/linux_net.py: 'ip', 'route', 'add', .. +# nova/network/linux_net.py: 'ip', 'route', 'del', . +# nova/network/linux_net.py: 'ip', 'route', 'show', 'dev', dev +ip: CommandFilter, ip, root + +# nova/virt/libvirt/vif.py: 'ovs-vsctl', ... +# nova/virt/libvirt/vif.py: 'ovs-vsctl', 'del-port', ... +# nova/network/linux_net.py: 'ovs-vsctl', .... +ovs-vsctl: CommandFilter, ovs-vsctl, root + +# nova/network/linux_net.py: 'ovs-ofctl', .... +ovs-ofctl: CommandFilter, ovs-ofctl, root + +# nova/virt/libvirt/vif.py: 'ivs-ctl', ... +# nova/virt/libvirt/vif.py: 'ivs-ctl', 'del-port', ... +# nova/network/linux_net.py: 'ivs-ctl', .... +ivs-ctl: CommandFilter, ivs-ctl, root + +# nova/virt/libvirt/vif.py: 'ifc_ctl', ... +ifc_ctl: CommandFilter, /opt/pg/bin/ifc_ctl, root + +# nova/network/linux_net.py: 'ebtables', '-D' ... +# nova/network/linux_net.py: 'ebtables', '-I' ... +ebtables: CommandFilter, ebtables, root +ebtables_usr: CommandFilter, ebtables, root + +# nova/network/linux_net.py: 'ip[6]tables-save' % (cmd, '-t', ... +iptables-save: CommandFilter, iptables-save, root +ip6tables-save: CommandFilter, ip6tables-save, root + +# nova/network/linux_net.py: 'ip[6]tables-restore' % (cmd,) +iptables-restore: CommandFilter, iptables-restore, root +ip6tables-restore: CommandFilter, ip6tables-restore, root + +# nova/network/linux_net.py: 'arping', '-U', floating_ip, '-A', '-I', ... +# nova/network/linux_net.py: 'arping', '-U', network_ref['dhcp_server'],.. +arping: CommandFilter, arping, root + +# nova/network/linux_net.py: 'dhcp_release', dev, address, mac_address +dhcp_release: CommandFilter, dhcp_release, root + +# nova/network/linux_net.py: 'kill', '-9', pid +# nova/network/linux_net.py: 'kill', '-HUP', pid +kill_dnsmasq: KillFilter, root, /usr/sbin/dnsmasq, -9, -HUP + +# nova/network/linux_net.py: 'kill', pid +kill_radvd: KillFilter, root, /usr/sbin/radvd + +# nova/network/linux_net.py: dnsmasq call +dnsmasq: EnvFilter, env, root, CONFIG_FILE=, NETWORK_ID=, dnsmasq + +# nova/network/linux_net.py: 'radvd', '-C', '%s' % _ra_file(dev, 'conf'.. +radvd: CommandFilter, radvd, root + +# nova/network/linux_net.py: 'brctl', 'addbr', bridge +# nova/network/linux_net.py: 'brctl', 'setfd', bridge, 0 +# nova/network/linux_net.py: 'brctl', 'stp', bridge, 'off' +# nova/network/linux_net.py: 'brctl', 'addif', bridge, interface +brctl: CommandFilter, brctl, root + +# nova/network/linux_net.py: 'sysctl', .... +sysctl: CommandFilter, sysctl, root + +# nova/network/linux_net.py: 'conntrack' +conntrack: CommandFilter, conntrack, root + +# nova/network/linux_net.py: 'fp-vdev' +fp-vdev: CommandFilter, fp-vdev, root diff --git a/nova/values.yaml b/nova/values.yaml index 465a8e94b7..22339d44a9 100644 --- a/nova/values.yaml +++ b/nova/values.yaml @@ -275,6 +275,22 @@ conf: policy: override: append: + nova_sudoers: + override: + append: + rootwrap: + override: + append: + rootwrap_filters: + api_metadata: + override: + append: + compute: + override: + append: + network: + override: + append: libvirtd: override: append: @@ -549,6 +565,9 @@ endpoints: public: 80 pod: + user: + nova: + uid: 1000 affinity: anti: type: