blob: 152d583271a215981814842db4ce09a6d8965e67 [file]
# 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
from unittest.mock import Mock
from openserverless.impl.builder.build_service import BuildService
class BuildTargetSecurityTest(unittest.TestCase):
def test_rejects_shell_syntax_before_kubernetes_calls(self):
service = BuildService.__new__(BuildService)
service.user = "alpha"
service.kube_client = Mock()
for target in ("alpha:ok;id", "alpha:ok$(id)", "alpha:ok\nRUN id", "alpha:ok,foo=bar"):
self.assertEqual((False, "Invalid target for the build"), service.build(target))
service.kube_client.assert_not_called()
self.assertEqual([], service.kube_client.mock_calls)
def test_valid_target_is_passed_as_data_to_buildctl(self):
service = BuildService.__new__(BuildService)
service.user = "alpha"
service.registry_host = "registry.local:5000"
service.custom_registry_auth = False
service.job_name = "build-alpha-test"
service.cm = "cm-alpha-test"
service.registry_auth = "registry-pull-secret"
job = service.create_build_job("alpha:release_1.2")
buildkit = job["spec"]["template"]["spec"]["containers"][0]
self.assertEqual("registry.local:5000/alpha:release_1.2", next(x["value"] for x in buildkit["env"] if x["name"] == "REGISTRY_IMAGE_NAME"))
self.assertIn('${REGISTRY_IMAGE_NAME}', buildkit["args"][0])
self.assertNotIn("alpha:release_1.2", buildkit["args"][0])
pod = job["spec"]["template"]["spec"]
self.assertFalse(pod["automountServiceAccountToken"])
self.assertFalse(pod["hostUsers"])
self.assertEqual("Unmasked", buildkit["securityContext"]["procMount"])
self.assertIn("@sha256:", buildkit["image"])
self.assertEqual({"/etc/subuid", "/etc/subgid"}, {
mount["mountPath"] for mount in buildkit["volumeMounts"] if mount.get("subPath")
})
self.assertFalse(buildkit["securityContext"]["privileged"])
self.assertEqual("Unconfined", buildkit["securityContext"]["appArmorProfile"]["type"])
self.assertEqual("Unconfined", buildkit["securityContext"]["seccompProfile"]["type"])
def test_source_cannot_add_dockerfile_instructions(self):
self.assertTrue(BuildService.valid_source_image("docker.io/apache/runtime:1.2"))
self.assertFalse(BuildService.valid_source_image("docker.io/apache/runtime:1.2\nRUN id"))
self.assertFalse(BuildService.valid_image_target("beta:release", "alpha"))
def test_dependency_build_keeps_existing_extension_contract(self):
service = BuildService.__new__(BuildService)
service.build_config = {"source": "runtime:python", "kind": "python", "file": "encoded"}
dockerfile = service.create_docker_file("requirements.txt")
self.assertIn("RUN /bin/extend\n", dockerfile)
self.assertTrue(dockerfile.endswith("USER nobody\n"))
def test_base_image_only_build_does_not_install_dependencies(self):
service = BuildService.__new__(BuildService)
service.build_config = {"source": "runtime:python", "kind": "python"}
self.assertEqual("FROM runtime:python\n\n", service.create_docker_file())
if __name__ == "__main__":
unittest.main()