blob: 16d851b1976e09304242e3ef687e9ec282269416 [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you 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.
import unittest
import jmespath
from parameterized import parameterized
from tests.charts.helm_template_generator import render_chart
DEPLOYMENT_NO_RBAC_NO_SA_KIND_NAME_TUPLES = [
('Secret', 'test-rbac-postgresql'),
('Secret', 'test-rbac-airflow-metadata'),
('Secret', 'test-rbac-pgbouncer-config'),
('Secret', 'test-rbac-pgbouncer-stats'),
('ConfigMap', 'test-rbac-airflow-config'),
('Service', 'test-rbac-postgresql-headless'),
('Service', 'test-rbac-postgresql'),
('Service', 'test-rbac-statsd'),
('Service', 'test-rbac-webserver'),
('Service', 'test-rbac-flower'),
('Service', 'test-rbac-pgbouncer'),
('Service', 'test-rbac-redis'),
('Service', 'test-rbac-worker'),
('Deployment', 'test-rbac-scheduler'),
('Deployment', 'test-rbac-statsd'),
('Deployment', 'test-rbac-webserver'),
('Deployment', 'test-rbac-flower'),
('Deployment', 'test-rbac-pgbouncer'),
('Deployment', 'test-rbac-triggerer'),
('StatefulSet', 'test-rbac-postgresql'),
('StatefulSet', 'test-rbac-redis'),
('StatefulSet', 'test-rbac-worker'),
('Secret', 'test-rbac-broker-url'),
('Secret', 'test-rbac-fernet-key'),
('Secret', 'test-rbac-redis-password'),
('Secret', 'test-rbac-webserver-secret-key'),
('Job', 'test-rbac-create-user'),
('Job', 'test-rbac-run-airflow-migrations'),
('CronJob', 'test-rbac-cleanup'),
]
RBAC_ENABLED_KIND_NAME_TUPLES = [
('Role', 'test-rbac-pod-launcher-role'),
('Role', 'test-rbac-cleanup-role'),
('Role', 'test-rbac-pod-log-reader-role'),
('RoleBinding', 'test-rbac-pod-launcher-rolebinding'),
('RoleBinding', 'test-rbac-pod-log-reader-rolebinding'),
('RoleBinding', 'test-rbac-cleanup-rolebinding'),
]
SERVICE_ACCOUNT_NAME_TUPLES = [
('ServiceAccount', 'test-rbac-cleanup'),
('ServiceAccount', 'test-rbac-scheduler'),
('ServiceAccount', 'test-rbac-webserver'),
('ServiceAccount', 'test-rbac-worker'),
('ServiceAccount', 'test-rbac-triggerer'),
('ServiceAccount', 'test-rbac-pgbouncer'),
('ServiceAccount', 'test-rbac-flower'),
('ServiceAccount', 'test-rbac-statsd'),
('ServiceAccount', 'test-rbac-create-user-job'),
('ServiceAccount', 'test-rbac-migrate-database-job'),
('ServiceAccount', 'test-rbac-redis'),
]
CUSTOM_SERVICE_ACCOUNT_NAMES = (
CUSTOM_SCHEDULER_NAME,
CUSTOM_WEBSERVER_NAME,
CUSTOM_WORKER_NAME,
CUSTOM_TRIGGERER_NAME,
CUSTOM_CLEANUP_NAME,
CUSTOM_FLOWER_NAME,
CUSTOM_PGBOUNCER_NAME,
CUSTOM_STATSD_NAME,
CUSTOM_CREATE_USER_JOBS_NAME,
CUSTOM_MIGRATE_DATABASE_JOBS_NAME,
CUSTOM_REDIS_NAME,
) = (
"TestScheduler",
"TestWebserver",
"TestWorker",
"TestTriggerer",
"TestCleanup",
"TestFlower",
"TestPGBouncer",
"TestStatsd",
"TestCreateUserJob",
"TestMigrateDatabaseJob",
"TestRedis",
)
class RBACTest(unittest.TestCase):
def _get_values_with_version(self, values, version):
if version != "default":
values["airflowVersion"] = version
return values
def _get_object_count(self, version):
# TODO remove default from condition after airflow update
if version == "2.3.2" or version == "default":
return [
('Secret', 'test-rbac-airflow-result-backend')
] + DEPLOYMENT_NO_RBAC_NO_SA_KIND_NAME_TUPLES
return DEPLOYMENT_NO_RBAC_NO_SA_KIND_NAME_TUPLES
@parameterized.expand(["2.3.2", "2.4.0", "default"])
def test_deployments_no_rbac_no_sa(self, version):
k8s_objects = render_chart(
"test-rbac",
values=self._get_values_with_version(
values={
"fullnameOverride": "test-rbac",
"rbac": {"create": False},
"cleanup": {
"enabled": True,
"serviceAccount": {
"create": False,
},
},
"pgbouncer": {
"enabled": True,
"serviceAccount": {
"create": False,
},
},
"redis": {"serviceAccount": {"create": False}},
"scheduler": {"serviceAccount": {"create": False}},
"webserver": {"serviceAccount": {"create": False}},
"workers": {"serviceAccount": {"create": False}},
"triggerer": {"serviceAccount": {"create": False}},
"statsd": {"serviceAccount": {"create": False}},
"createUserJob": {"serviceAccount": {"create": False}},
"migrateDatabaseJob": {"serviceAccount": {"create": False}},
"flower": {"enabled": True, "serviceAccount": {"create": False}},
},
version=version,
),
)
list_of_kind_names_tuples = [
(k8s_object['kind'], k8s_object['metadata']['name']) for k8s_object in k8s_objects
]
self.assertCountEqual(
list_of_kind_names_tuples,
self._get_object_count(version),
)
@parameterized.expand(["2.3.2", "2.4.0", "default"])
def test_deployments_no_rbac_with_sa(self, version):
k8s_objects = render_chart(
"test-rbac",
values=self._get_values_with_version(
values={
"fullnameOverride": "test-rbac",
"rbac": {"create": False},
"cleanup": {"enabled": True},
"flower": {"enabled": True},
"pgbouncer": {"enabled": True},
},
version=version,
),
)
list_of_kind_names_tuples = [
(k8s_object['kind'], k8s_object['metadata']['name']) for k8s_object in k8s_objects
]
real_list_of_kind_names = self._get_object_count(version) + SERVICE_ACCOUNT_NAME_TUPLES
self.assertCountEqual(
list_of_kind_names_tuples,
real_list_of_kind_names,
)
@parameterized.expand(["2.3.2", "2.4.0", "default"])
def test_deployments_with_rbac_no_sa(self, version):
k8s_objects = render_chart(
"test-rbac",
values=self._get_values_with_version(
values={
"fullnameOverride": "test-rbac",
"cleanup": {
"enabled": True,
"serviceAccount": {
"create": False,
},
},
"scheduler": {"serviceAccount": {"create": False}},
"webserver": {"serviceAccount": {"create": False}},
"workers": {"serviceAccount": {"create": False}},
"triggerer": {"serviceAccount": {"create": False}},
"flower": {"enabled": True, "serviceAccount": {"create": False}},
"statsd": {"serviceAccount": {"create": False}},
"redis": {"serviceAccount": {"create": False}},
"pgbouncer": {
"enabled": True,
"serviceAccount": {
"create": False,
},
},
"createUserJob": {"serviceAccount": {"create": False}},
"migrateDatabaseJob": {"serviceAccount": {"create": False}},
},
version=version,
),
)
list_of_kind_names_tuples = [
(k8s_object['kind'], k8s_object['metadata']['name']) for k8s_object in k8s_objects
]
real_list_of_kind_names = self._get_object_count(version) + RBAC_ENABLED_KIND_NAME_TUPLES
self.assertCountEqual(
list_of_kind_names_tuples,
real_list_of_kind_names,
)
@parameterized.expand(["2.3.2", "2.4.0", "default"])
def test_deployments_with_rbac_with_sa(self, version):
k8s_objects = render_chart(
"test-rbac",
values=self._get_values_with_version(
values={
"fullnameOverride": "test-rbac",
"cleanup": {"enabled": True},
"flower": {"enabled": True},
"pgbouncer": {"enabled": True},
},
version=version,
),
)
list_of_kind_names_tuples = [
(k8s_object['kind'], k8s_object['metadata']['name']) for k8s_object in k8s_objects
]
real_list_of_kind_names = (
self._get_object_count(version) + SERVICE_ACCOUNT_NAME_TUPLES + RBAC_ENABLED_KIND_NAME_TUPLES
)
self.assertCountEqual(
list_of_kind_names_tuples,
real_list_of_kind_names,
)
def test_service_account_custom_names(self):
k8s_objects = render_chart(
"test-rbac",
values={
"fullnameOverride": "test-rbac",
"cleanup": {
"enabled": True,
"serviceAccount": {
"name": CUSTOM_CLEANUP_NAME,
},
},
"scheduler": {"serviceAccount": {"name": CUSTOM_SCHEDULER_NAME}},
"webserver": {"serviceAccount": {"name": CUSTOM_WEBSERVER_NAME}},
"workers": {"serviceAccount": {"name": CUSTOM_WORKER_NAME}},
"triggerer": {"serviceAccount": {"name": CUSTOM_TRIGGERER_NAME}},
"flower": {"enabled": True, "serviceAccount": {"name": CUSTOM_FLOWER_NAME}},
"statsd": {"serviceAccount": {"name": CUSTOM_STATSD_NAME}},
"redis": {"serviceAccount": {"name": CUSTOM_REDIS_NAME}},
"pgbouncer": {
"enabled": True,
"serviceAccount": {
"name": CUSTOM_PGBOUNCER_NAME,
},
},
"createUserJob": {"serviceAccount": {"name": CUSTOM_CREATE_USER_JOBS_NAME}},
"migrateDatabaseJob": {"serviceAccount": {"name": CUSTOM_MIGRATE_DATABASE_JOBS_NAME}},
},
)
list_of_sa_names = [
k8s_object['metadata']['name']
for k8s_object in k8s_objects
if k8s_object['kind'] == "ServiceAccount"
]
self.assertCountEqual(
list_of_sa_names,
CUSTOM_SERVICE_ACCOUNT_NAMES,
)
def test_service_account_custom_names_in_objects(self):
k8s_objects = render_chart(
"test-rbac",
values={
"fullnameOverride": "test-rbac",
"cleanup": {
"enabled": True,
"serviceAccount": {
"name": CUSTOM_CLEANUP_NAME,
},
},
"scheduler": {"serviceAccount": {"name": CUSTOM_SCHEDULER_NAME}},
"webserver": {"serviceAccount": {"name": CUSTOM_WEBSERVER_NAME}},
"workers": {"serviceAccount": {"name": CUSTOM_WORKER_NAME}},
"triggerer": {"serviceAccount": {"name": CUSTOM_TRIGGERER_NAME}},
"flower": {"enabled": True, "serviceAccount": {"name": CUSTOM_FLOWER_NAME}},
"statsd": {"serviceAccount": {"name": CUSTOM_STATSD_NAME}},
"redis": {"serviceAccount": {"name": CUSTOM_REDIS_NAME}},
"pgbouncer": {
"enabled": True,
"serviceAccount": {
"name": CUSTOM_PGBOUNCER_NAME,
},
},
"createUserJob": {"serviceAccount": {"name": CUSTOM_CREATE_USER_JOBS_NAME}},
"migrateDatabaseJob": {"serviceAccount": {"name": CUSTOM_MIGRATE_DATABASE_JOBS_NAME}},
},
)
list_of_sa_names_in_objects = []
for k8s_object in k8s_objects:
name = (
jmespath.search("spec.template.spec.serviceAccountName", k8s_object)
or jmespath.search(
"spec.jobTemplate.spec.template.spec.serviceAccountName",
k8s_object,
)
or None
)
if name and name not in list_of_sa_names_in_objects:
list_of_sa_names_in_objects.append(name)
self.assertCountEqual(
list_of_sa_names_in_objects,
CUSTOM_SERVICE_ACCOUNT_NAMES,
)
def test_service_account_without_resource(self):
k8s_objects = render_chart(
"test-rbac",
values={
"fullnameOverride": "test-rbac",
"executor": "LocalExecutor",
"cleanup": {"enabled": False},
"pgbouncer": {"enabled": False},
"redis": {"enabled": False},
"flower": {"enabled": False},
"statsd": {"enabled": False},
"webserver": {"defaultUser": {"enabled": False}},
},
)
list_of_sa_names = [
k8s_object['metadata']['name']
for k8s_object in k8s_objects
if k8s_object['kind'] == "ServiceAccount"
]
service_account_names = [
'test-rbac-scheduler',
'test-rbac-webserver',
'test-rbac-triggerer',
'test-rbac-migrate-database-job',
]
self.assertCountEqual(list_of_sa_names, service_account_names)