├── .circleci ├── config.yml └── scripts │ ├── clean_up_gke.sh │ ├── clean_up_kops.sh │ └── prepare_host.sh ├── .gitignore ├── LICENSE ├── README.md ├── docs ├── architecture.md ├── architecture.png ├── building.md ├── deployment.md ├── exampleinstallation.md ├── kubespray_gcp.md ├── platform_admin_guide.md ├── platform_user_guide.md ├── prerequisites.md ├── privateregistry.md ├── security_recommendations.md ├── serving_templates.md └── troubleshooting.md ├── examples ├── crd │ └── example-inference-endpoint.yaml └── grpc_client │ ├── Makefile │ ├── README.md │ ├── __init__.py │ ├── classes.py │ ├── grpc_client.py │ ├── grpc_client_utils.py │ ├── images_2_numpy.py │ ├── load_testing │ ├── README.md │ ├── image_locust.py │ ├── requirements-locust.txt │ ├── start_locust.sh │ └── stop_locust.sh │ └── requirements.txt ├── helm-deployment ├── .helmignore ├── README.md ├── crd-subchart │ ├── Chart.yaml │ ├── README.md │ ├── serving-templates │ │ ├── ovms │ │ │ ├── configMap.tmpl │ │ │ ├── deployment.tmpl │ │ │ ├── ingress.tmpl │ │ │ └── service.tmpl │ │ └── tf-serving │ │ │ ├── configMap.tmpl │ │ │ ├── deployment.tmpl │ │ │ ├── ingress.tmpl │ │ │ └── service.tmpl │ ├── templates │ │ ├── crd.yaml │ │ ├── deployment.yaml │ │ ├── namespace.yaml │ │ └── template-config.yaml │ └── values.yaml ├── dex-subchart │ ├── Chart.yaml │ ├── README.md │ ├── certs │ │ ├── generate-dex-certs.sh │ │ ├── generate-ing-ca.sh │ │ └── generate-ing-dex-certs.sh │ ├── templates │ │ ├── _helpers.tpl │ │ ├── deployment.yaml │ │ ├── dex-ca.yaml │ │ ├── dex-ingress.yaml │ │ ├── namespace.yaml │ │ ├── rolebinding.yaml │ │ ├── root-ca.yaml │ │ ├── secret.yaml │ │ ├── service.yaml │ │ ├── serviceaccount.yaml │ │ ├── tls-dex-secret.yaml │ │ └── tls-ing-dex-secret.yaml │ └── values.yaml ├── ing-subchart │ ├── Chart.yaml │ ├── README.md │ ├── nginx.tmpl │ ├── templates │ │ ├── _helpers.tpl │ │ ├── default-http-backend-service.yaml │ │ ├── default-http-backend.yaml │ │ ├── ingress-nginx-baremetal.yaml │ │ ├── ingress-nginx-cloud-generic.yaml │ │ ├── namespace.yaml │ │ ├── nginx-configuration-configmap.yaml │ │ ├── nginx-ingress-clusterrole-nisa-binding.yaml │ │ ├── nginx-ingress-clusterrole.yaml │ │ ├── nginx-ingress-controller.yaml │ │ ├── nginx-ingress-role-nisa-binding.yaml │ │ ├── nginx-ingress-role.yaml │ │ ├── nginx-ingress-serviceaccount.yaml │ │ ├── nginx-template-configmap.yaml │ │ ├── tcp-services-configmap.yaml │ │ └── udp-services-configmap.yaml │ └── values.yaml ├── ldap-subchart │ ├── Chart.yaml │ ├── README.md │ ├── certs │ │ └── genereate_ldap_certs.sh │ ├── customLdifFiles.yaml │ ├── deployment.sh │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── certs_secret.yaml │ │ ├── configmap-env.yaml │ │ ├── deployment.yaml │ │ ├── pvc.yaml │ │ ├── secret-customldif.yaml │ │ ├── secret.yaml │ │ ├── service.yaml │ │ └── tests │ │ │ ├── openldap-test-runner.yaml │ │ │ └── openldap-tests.yaml │ └── values.yaml ├── management-api-subchart │ ├── Chart.yaml │ ├── README.md │ ├── certs │ │ ├── ca.conf │ │ ├── generate-ing-management-api-certs.sh │ │ ├── generate-management-api-certs.sh │ │ ├── script-wrong-certs.sh │ │ └── scriptcert.sh │ ├── templates │ │ ├── _helpers.tpl │ │ ├── cluster-role-binding.yaml │ │ ├── dex-ca.yaml │ │ ├── dex-secret.yaml │ │ ├── man-api-ca.yaml │ │ ├── man-api-ingress.yaml │ │ ├── management.yaml │ │ ├── minio-secret.yaml │ │ ├── namespace.yaml │ │ ├── secrets-serverside.yaml │ │ ├── service-account-rb.yaml │ │ ├── tls-ing-management-secret.yaml │ │ └── tls-management-secret.yaml │ └── values.yaml └── minio-subchart │ ├── Chart.yaml │ ├── README.md │ ├── requirements.yaml │ └── values.yaml ├── installer ├── README.md ├── certs │ └── dex-ing-ca.yaml ├── configs │ ├── test_LdifFiles.yaml │ └── test_dex_config.yaml ├── crd │ └── install.sh ├── default_tenant.sh ├── dex │ └── install.sh ├── dns │ └── setup.sh ├── hooks │ └── example_dns_entry_hook.sh ├── ingress │ └── install.sh ├── install.sh ├── k8s │ ├── create_kops_cluster_gke.sh │ ├── get_ing_ca_crt.sh │ ├── install_tiller.sh │ └── restart_k8sapi.sh ├── kops │ ├── README.md │ ├── SETUP.md │ ├── desiredcni.yaml │ ├── desiredcni_ci.yaml │ └── oidc_tmpl.yaml ├── ldap │ └── install.sh ├── main.sh ├── management-api │ └── install.sh ├── minio │ ├── install.sh │ └── minio_ing_tmpl.yaml ├── prerequisites_ubuntu.sh ├── uninstaller.sh ├── utils │ ├── check_required_tools.sh │ ├── fill_template.sh │ ├── messages.sh │ ├── progress_bar.sh │ ├── route53 │ │ ├── apply.sh │ │ └── route_record_tmpl.json │ ├── show_help.sh │ ├── validate_envs.sh │ ├── wait_for_kubectl.sh │ └── wait_for_pod.sh └── validate.sh ├── management ├── .dockerignore ├── Dockerfile ├── Makefile ├── README.md ├── gcloud-push.sh ├── install_CA.sh ├── management_api │ ├── __init__.py │ ├── authenticate │ │ ├── __init__.py │ │ ├── auth_controller.py │ │ └── authenticate.py │ ├── config.py │ ├── endpoints │ │ ├── __init__.py │ │ ├── endpoint_utils.py │ │ └── endpoints.py │ ├── main.py │ ├── models │ │ ├── __init__.py │ │ ├── model_utils.py │ │ └── models.py │ ├── runner.py │ ├── schemas │ │ ├── __init__.py │ │ ├── authenticate.py │ │ ├── elements │ │ │ ├── __init__.py │ │ │ ├── models.py │ │ │ ├── names.py │ │ │ ├── resources.py │ │ │ └── verifications.py │ │ ├── endpoints.py │ │ ├── models.py │ │ ├── tenants.py │ │ └── uploads.py │ ├── servings │ │ ├── __init__.py │ │ ├── servings.py │ │ └── servings_utils.py │ ├── tenants │ │ ├── __init__.py │ │ ├── tenants.py │ │ └── tenants_utils.py │ ├── upload │ │ ├── __init__.py │ │ ├── multipart.py │ │ └── multipart_utils.py │ └── utils │ │ ├── __init__.py │ │ ├── cert.py │ │ ├── errors_handling.py │ │ ├── kubernetes_resources.py │ │ ├── logger.py │ │ └── routes.py ├── requirements.txt ├── run.sh ├── setup.cfg ├── setup.py └── test │ ├── conftest.py │ ├── test_auth │ ├── test_auth_controller.py │ ├── test_authenticate.py │ └── test_endpoints_auth.py │ ├── test_endpoints │ ├── __init__.py │ ├── test_endpoint_utils.py │ └── test_endpoints.py │ ├── test_models │ └── test_models.py │ ├── test_upload │ ├── __init__.py │ ├── test_multipart.py │ └── test_multipart_utils.py │ └── test_utils │ ├── auth_middleware_mock.py │ └── token_stuff.py ├── scripts ├── README.md ├── ca.conf ├── common_token.py ├── create_tenant_certs.sh ├── delete_tenant_certs.sh ├── generate_certs.sh ├── get_cert.sh ├── get_cert_kubectl.sh ├── images │ ├── airliner.jpeg │ ├── arctic-fox.jpeg │ ├── bee.jpeg │ ├── golden_retriever.jpeg │ ├── gorilla.jpeg │ ├── magnetic_compass.jpeg │ ├── peacock.jpeg │ ├── pelican.jpeg │ ├── snail.jpeg │ └── zebra.jpeg ├── imm ├── imm_tests.bats ├── imm_utils.sh ├── model_upload.py ├── model_upload_cli.py ├── prepare_env_single_tenant_mode.sh ├── prepare_test_env.sh ├── refresh_token.py ├── requirements.txt └── webbrowser_authenticate.py ├── server-controller ├── .dockerignore ├── Dockerfile.prod ├── Gopkg.lock ├── Gopkg.toml ├── Makefile ├── README.md ├── apis │ └── cr │ │ └── v1 │ │ ├── deepcopy_generated.go │ │ ├── doc.go │ │ ├── roundtrip_test.go │ │ └── types.go ├── check_coverage.sh ├── hooks.go ├── hooks_test.go ├── kubernetes │ └── deployment.yml ├── lint.json ├── main.go └── mock_client_test.go └── tests ├── Makefile ├── README.md ├── config.py ├── conftest.py ├── context.py ├── e2e_tests ├── __init__.py ├── config.py ├── inference_endpoints │ ├── __init__.py │ └── test_inference_endpoints.py ├── management_api_requests.py └── tf_serving_utils │ ├── __init__.py │ ├── fox.jpg │ ├── images.npy │ └── load_numpy.py ├── integration ├── __init__.py └── test_ovms.py ├── management_api_tests ├── __init__.py ├── authenticate.py ├── authenticate │ └── test_authenticate.py ├── config.py ├── endpoints │ ├── __init__.py │ ├── endpoint_utils.py │ └── test_endpoints.py ├── models │ ├── __init__.py │ └── test_models.py ├── reused.py ├── servings │ ├── __init__.py │ └── test_servings.py ├── tenants │ ├── __init__.py │ ├── tenant_utils.py │ └── test_tenants.py └── upload │ └── test_multipart_upload.py ├── requirements.txt └── run_test.sh /.circleci/scripts/clean_up_gke.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | export MGT_API_AUTHORIZATION="true" 18 | . ~/inference-model-manager/.venv/bin/activate 19 | cd ~/inference-model-manager/scripts 20 | . ./prepare_test_env.sh ${DOMAIN_NAME} 21 | . ./imm_utils.sh 22 | get_token admin 23 | export ING_IP=`kubectl get services -n ingress-nginx|grep ingress-nginx|awk '{ print $(NF-2) }'` 24 | cd ~/inference-model-manager/installer 25 | ./uninstaller.sh -q 26 | sleep 3m 27 | echo y | gcloud container clusters delete gke-imm-${SHORT_SHA1}-${CIRCLE_BRANCH} --zone us-west1-a 28 | cd ~/inference-model-manager/installer/utils/route53 29 | unset REQUESTS_CA_BUNDLE 30 | unset MANAGEMENT_CA_CERT_PATH 31 | unset CURL_CA_BUNDLE 32 | ./apply.sh DELETE ${ING_IP} ${DOMAIN_NAME} 33 | -------------------------------------------------------------------------------- /.circleci/scripts/clean_up_kops.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | . ~/inference-model-manager/.venv/bin/activate 18 | cd ~/inference-model-manager/scripts 19 | . ./prepare_test_env.sh ${DOMAIN_NAME} 20 | . ./imm_utils.sh 21 | get_token admin 22 | export ING_IP=`kubectl get services -n ingress-nginx|grep ingress-nginx|awk '{ print $(NF-2) }'` 23 | cd ~/inference-model-manager/installer 24 | ./uninstaller.sh -q 25 | sleep 3m 26 | kops delete cluster ${CLUSTER_NAME} --yes 27 | cd ~/inference-model-manager/installer/utils/route53 28 | unset REQUESTS_CA_BUNDLE 29 | unset MANAGEMENT_CA_CERT_PATH 30 | unset CURL_CA_BUNDLE 31 | ./apply.sh DELETE ${ING_IP} ${DOMAIN_NAME} 32 | deactivate 33 | -------------------------------------------------------------------------------- /.circleci/scripts/prepare_host.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | echo "deb http://packages.cloud.google.com/apt $CLOUD_SDK_REPO main" | sudo tee -a /etc/apt/sources.list.d/google-cloud-sdk.list 19 | curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - 20 | sudo -E apt-get update && sudo -E apt-get install -y google-cloud-sdk 21 | sudo -E apt-get install kubectl 22 | sudo -E apt-get update && sudo -E apt-get --only-upgrade install kubectl google-cloud-sdk google-cloud-sdk-app-engine-grpc google-cloud-sdk-pubsub-emulator \ 23 | google-cloud-sdk-app-engine-go google-cloud-sdk-cloud-build-local google-cloud-sdk-datastore-emulator google-cloud-sdk-app-engine-python google-cloud-sdk-cbt \ 24 | google-cloud-sdk-bigtable-emulator google-cloud-sdk-app-engine-python-extras google-cloud-sdk-datalab google-cloud-sdk-app-engine-java 25 | gcloud auth activate-service-account --key-file /tmp/gcp-key.json 26 | gcloud config set project "${GOOGLE_PROJECT_ID}" 27 | export PROJECT=`gcloud config get-value project` 28 | cd ~/inference-model-manager/ 29 | cd ~/inference-model-manager/installer/ 30 | ./prerequisites_ubuntu.sh 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Python template 3 | # Byte-compiled / optimized / DLL files 4 | __pycache__/ 5 | *.py[cod] 6 | *$py.class 7 | 8 | # C extensions 9 | *.so 10 | 11 | # Distribution / packaging 12 | .Python 13 | env/ 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | wheels/ 26 | *.egg-info/ 27 | .installed.cfg 28 | *.egg 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *,cover 49 | .hypothesis/ 50 | 51 | # Translations 52 | *.mo 53 | *.pot 54 | 55 | # Django stuff: 56 | *.log 57 | local_settings.py 58 | 59 | # Flask stuff: 60 | instance/ 61 | .webassets-cache 62 | 63 | # Scrapy stuff: 64 | .scrapy 65 | 66 | # Sphinx documentation 67 | docs/_build/ 68 | 69 | # PyBuilder 70 | target/ 71 | 72 | # Jupyter Notebook 73 | .ipynb_checkpoints 74 | 75 | # pyenv 76 | .python-version 77 | 78 | # celery beat schedule file 79 | celerybeat-schedule 80 | 81 | # SageMath parsed files 82 | *.sage.py 83 | 84 | # dotenv 85 | .env 86 | 87 | # virtualenv 88 | .venv 89 | venv/ 90 | ENV/ 91 | .venv36 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | 96 | # Rope project settings 97 | .ropeproject 98 | 99 | .idea/ 100 | 101 | config 102 | .pytest_cache/ 103 | 104 | # Installer additional files 105 | installer/dex/dex_config.yaml 106 | installer/k8s/cluster.yaml 107 | installer/k8s/config.yaml 108 | installer/k8s/config_oidc.yaml 109 | installer/k8s/oidc.yaml 110 | installer/minio/minio_ing.yaml 111 | installer/validate/__pycache__/ 112 | installer/utils/dns_utils/.venvaws 113 | installer/utils/route53/route_record.json 114 | installer/helm-temp-dir 115 | installer/hooks/dns_entry_hook.sh 116 | helm-deployment/*/charts 117 | helm-deployment/*/*.lock 118 | 119 | **/*.pem 120 | **/*.crt 121 | **/*.csr 122 | **/*.key 123 | **/*.pb 124 | scripts/*.npy 125 | -------------------------------------------------------------------------------- /docs/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/docs/architecture.png -------------------------------------------------------------------------------- /docs/building.md: -------------------------------------------------------------------------------- 1 | # Building docker images for Inference Model Manager 2 | 3 | ## TensorFlow Serving 4 | The choice is to use prebuilt Docker images published by Google on [Docker Hub](https://hub.docker.com/r/tensorflow/serving/) 5 | or to build them from sources with compilation options optimized for target HW and CPU architecture on the Kubernetes nodes. 6 | Description how to build Tensorflow Serving from sources are 7 | [https://www.tensorflow.org/serving/setup](https://www.tensorflow.org/serving/setup) 8 | Tensorflow Serving can be built with Eigen backend libraries (default option) or with MKL libraries. 9 | MKL backed in TF Serving brings better performance but needs threading parameters tuning via setting environment variables. 10 | 11 | ## OpenVINO Model Server 12 | The choice is to use prebuilt Docker image published by Intel on [Docker Hub](https://hub.docker.com/r/intelaipg/openvino-model-server/) 13 | or to [build the image](https://github.com/IntelAI/OpenVINO-model-server/blob/master/docs/docker_container.md) yourself 14 | 15 | ## CRD controller 16 | Prebuilt images are avaliable in https://hub.docker.com/r/intelaipg/inference-model-manager-crd 17 | 18 | If you want to build them on your own, please refer to the documentation on [server-controller](../server-controller) documentation. 19 | 20 | ## Management API server 21 | Prebuilt images are avaliable in https://hub.docker.com/r/intelaipg/inference-model-manager-api 22 | 23 | If you want to build them on your own, please refer to the documentation on [management api](../management) documentation. 24 | 25 | -------------------------------------------------------------------------------- /docs/kubespray_gcp.md: -------------------------------------------------------------------------------- 1 | ## Deploy Kubernetes with Kubespray 2 | ### Example on Google Cloud Platform 3 | 4 | Create VMs with gcloud: 5 | 6 | ``` 7 | gcloud compute instances create instance-1 instance-2 instance-3 --zone --can-ip-forward --tags= 8 | ``` 9 | 10 | Clone kubespray repository. 11 | 12 | Check IP adresses of above instances. 13 | 14 | ``` 15 | gcloud compute instances list --filter="name ~ instance-1" --format='value(EXTERNAL_IP)' 16 | gcloud compute instances list --filter="name ~ instance-1" --format='value(INTERNAL_IP)' 17 | ``` 18 | Add following variables to inventory file (host.ini) 19 | ``` 20 | ansible_ssh_host=EXTERNAL_IP ansible_host=INTERNAL_IP access_ip=INTERNAL_IP ip=INTERNAL_IP 21 | ``` 22 | Note that your ssh key must be copied to all machines mentioned in inventory configuration. 23 | 24 | 25 | Run ansible playbook inside clone of kubespray repository 26 | ``` 27 | ansible-playbook -u -e ansible_ssh_user=admin -e cloud_provider=gce -b --become-user=root -i inventory/ cluster.yml --private-key=~/.ssh/private_key 28 | ``` 29 | 30 | Clone inference-model-manager repository and go through installation procedure. 31 | 32 | ### Enabling oidc authentication in Kubernetes installed via Kubespray 33 | 34 | Changes required to enable oidc authentication in Kubernetes installed via Kubespray 35 | 36 | ``` 37 | cd /etc/kubernetes/manifests/ 38 | vi kube-apiserver.yaml 39 | ``` 40 | Add following flags with desired values 41 | 42 | [More information about oidc flags here](../docs/deployment.md) 43 | 44 | ``` 45 | --oidc-issuer-url 46 | --oidc-client-id 47 | --oidc-groups-claim 48 | --oidc-username-claim 49 | --oidc-ca-file 50 | ``` 51 | After saving changes in kube-apiserver.yaml file, kubeapi server pod will be restarted automatically, what means that until pod is up & running again, kubectl commands will return connection refused errors. 52 | ``` 53 | kubectl get pods -n kube-system 54 | The connection to the server :6443 was refused - did you specify the right host or port? 55 | ``` 56 | If error occurs after few minutes, review updates in kube apiserver configuration and double check path to certificate file. Remember, to not to add `oidc-ca-file` flag before placing certificate file in right directory as kube apiserver pod will not start. 57 | 58 | -------------------------------------------------------------------------------- /docs/privateregistry.md: -------------------------------------------------------------------------------- 1 | ## Private Docker Registry 2 | Private Docker Registry used to store Management Api and Server Controller images requires creation of special kubernetes secret. 3 | 4 | Example secret creation, Google Cloud Registry assumed: 5 | ``` 6 | kubectl create secret docker-registry gcr-json-key \ 7 | --docker-server=https://gcr.io \ 8 | --docker-username=_json_key \ 9 | --docker-password="$(cat ~/.json)" \ 10 | --docker-email=email@example.com 11 | ``` 12 | Patch service account used for imagePullSecret option for Management Api and Server Controller. 13 | 14 | ``` 15 | kubectl patch serviceaccount mgt-api \ 16 | -p "{\"imagePullSecrets\": [{\"name\": \"gcr-json-key\"}]}" \ 17 | -n mgt-api 18 | ``` 19 | ``` 20 | kubectl patch serviceaccount server-controller \ 21 | -p "{\"imagePullSecrets\": [{\"name\": \"gcr-json-key\"}]}" \ 22 | -n crd 23 | ``` 24 | -------------------------------------------------------------------------------- /docs/security_recommendations.md: -------------------------------------------------------------------------------- 1 | # Security recommendations 2 | 3 | Beside the mandatory [requirements and prerequisites](prerequisites.md) there are a few recommendations 4 | for Kubernetes setup to ensure secure and reliable experience in the production usage. 5 | 6 | - consider using an overlay network that implements network policy 7 | - keeping the kubernetes master nodes separate from worker nodes 8 | - enabling encryption on etcd to protect secrets 9 | - ensuring the unauthenticated api server ports are blocked 10 | - consider host-level inbound firewall policy 11 | - audit your K8S cluster using [CIS Security benchmark](https://www.cisecurity.org/benchmark/kubernetes/) -------------------------------------------------------------------------------- /examples/crd/example-inference-endpoint.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: "intel.com/v1" 2 | kind: InferenceEndpoint 3 | metadata: 4 | name: example-endpoint 5 | spec: 6 | modelName: "resnet_v1_50" 7 | modelVersionPolicy: "{latest{}}" 8 | subjectName: "client-name" 9 | endpointName: "resnet" 10 | servingName: "tf-serving" 11 | -------------------------------------------------------------------------------- /examples/grpc_client/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | style: 18 | flake8 --max-line-length 100 images_2_numpy.py grpc_client_utils.py grpc_client.py load_testing/image_locust.py 19 | -------------------------------------------------------------------------------- /examples/grpc_client/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/examples/grpc_client/__init__.py -------------------------------------------------------------------------------- /examples/grpc_client/load_testing/README.md: -------------------------------------------------------------------------------- 1 | # Load Test 2 | 3 | ## Prerequisites 4 | * Python 3.6 5 | * Install [requirements](../requirements.txt) needed to launch [grpc client](../README.md) 6 | * Install Locust requirements ```pip install -r requirements-locust.txt``` 7 | 8 | 9 | ## Description 10 | Script available under this directory allows users to execute their own load tests. Prepared [Locust class](image_locust.py) 11 | loads configuration from environment variables and images also creates grpc stub in `on start` method. In hatching phase this client only performs requests to GRPC service using earlier loaded images. 12 | The number of comma-delimited photo paths determines the size of the batch. Now this tests only support resnet model. 13 | 14 | ## Configurable parameters 15 | ```` 16 | GRPC_ADDRESS # address to grpc endpoint 17 | MODEL_NAME = # model name; default value=resnet 18 | TENSOR_NAME # input tensor name; default value=in 19 | IMAGES # path to images, separated by comma; example=/test/image.jpeg,/test/image2.jpeg 20 | SERVER_CERT # path to server certificate 21 | CLIENT_CERT # path to client certificate 22 | CLIENT_KEY # path to client key 23 | TRANSPOSE # set to True if you want to transpose input or completly unset env to not transpose 24 | TIMEOUT # timeout used in grpc request; default value=10.0 25 | ```` 26 | 27 | ## Start Locust 28 | 29 | A script was prepared to launch specific amount of locust instances, by passing integer to bash script. 30 | Without passing any parameter script will launch Locust in distributed mode with 2 slaves. 31 | If you want to perform as many RPS as possible we recommend to spawn 1 slave for 1 CPU core. 32 | Also this script creates temporary file `pid_locust` which keeps PID of processes launched by this script. 33 | 34 | ```./start_locust.sh``` 35 | 36 | Examples: 37 | ``` 38 | ./start_locust.sh 1 # Launch Locust in distributed mode with 1 slave 39 | ./start_locust.sh 0 # Launch Locust in single instance mode 40 | ./start_locust.sh 4 # Launch Locust in distributed mode with 4 slaves 41 | ``` 42 | 43 | After using this command Locust will be available under [http://localhost:8089](http://localhost:8089) 44 | 45 | ## Stop Locust 46 | 47 | We run all instances as background process, so to stop load tests you can use our script ```./stop_locust``` 48 | , which also removes temporary file created earlier or read PIDs in `pid_locust` file and simply kill processes listed in that file. 49 | -------------------------------------------------------------------------------- /examples/grpc_client/load_testing/requirements-locust.txt: -------------------------------------------------------------------------------- 1 | locustio==0.9.0 2 | -------------------------------------------------------------------------------- /examples/grpc_client/load_testing/start_locust.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | SLAVES=${1:-2} 3 | 4 | if [ "$SLAVES" == "0" ] 5 | then 6 | LOCUST_OPTS="" 7 | echo "Launch locust single instance" 8 | else 9 | LOCUST_OPTS="--master" 10 | echo "Launch locust master" 11 | fi 12 | 13 | locust -f image_locust.py ${LOCUST_OPTS} & 14 | echo $! >> pid_locust 15 | for (( c=1; c<=$SLAVES; c++ )) 16 | do 17 | echo "Launch locust slave $i" 18 | locust -f image_locust.py --master-host=localhost --slave & 19 | echo $! >> pid_locust 20 | done 21 | -------------------------------------------------------------------------------- /examples/grpc_client/load_testing/stop_locust.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | while read p; do 3 | kill -9 $p 4 | done # platform dns 8 | private_registry: false # If you use private registry and your cluster do not have access to that registry set this value to "true". Below you can see what else you need to do 9 | ``` 10 | #### Private docker registry 11 | 12 | If you set in previous step `docker_secret` variable to ``true`` you have to create a secret in the cluster which holds your authorization token. Whole process is described [here](https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/#create-a-secret-in-the-cluster-that-holds-your-authorization-token). 13 | 14 | #### Serving templates 15 | 16 | Under ``serving-templates`` directory could be found serving templates, which be used by CRD. 17 | By default, 2 templates are available after creating the CRD ``tf-serving`` and ``ovms``. 18 | 19 | You can add your own [templates](../../docs/serving_templates.md). Under ``serving-templates`` create new directory, which be name for serving-template(Name of that directory must be longer than 3 chars and can`t contain '_'). 20 | In created directory must be 4 yaml files with exactly the same names, as mentioned below: 21 | ``` 22 | deployment.tmpl 23 | ingress.tmpl 24 | service.tmpl 25 | configMap.tmpl 26 | ``` 27 | 28 | Other hints and requirements can be read [serving-templates readme file](../../docs/serving_templates.md). 29 | 30 | 31 | ### Installation 32 | 33 | To install this chart after preparation phase use: 34 | ```helm install .``` 35 | -------------------------------------------------------------------------------- /helm-deployment/crd-subchart/serving-templates/ovms/configMap.tmpl: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: "{{.Spec.EndpointName}}" 5 | namespace: "{{.ObjectMeta.Namespace}}" 6 | labels: 7 | id: "{{.Spec.EndpointName}}" 8 | endpoint: "{{.Spec.EndpointName}}" 9 | ownerReferences: 10 | - apiVersion: {{.APIVersion}} 11 | kind: {{.Kind}} 12 | name: {{.Name}} 13 | uid: {{.UID}} 14 | controller: {{.Controller}} 15 | blockOwnerDeletion: {{.BlockOwnerDeletion}} 16 | data: 17 | ovms.json: | 18 | { 19 | "model_config_list": [{ 20 | "config":{ 21 | "name":"{{.Spec.ModelName}}", 22 | "base_path":"s3://{{.ObjectMeta.Namespace}}/{{.Spec.ModelName}}" 23 | } 24 | }] 25 | } 26 | -------------------------------------------------------------------------------- /helm-deployment/crd-subchart/serving-templates/ovms/ingress.tmpl: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: "{{.Spec.EndpointName}}" 5 | namespace: "{{.ObjectMeta.Namespace}}" 6 | annotations: 7 | kubernetes.io/ingress.class: nginx 8 | nginx.ingress.kubernetes.io/grpc-backend: "true" 9 | nginx.ingress.kubernetes.io/auth-tls-verify-client: "on" 10 | nginx.ingress.kubernetes.io/auth-tls-secret: "{{.ObjectMeta.Namespace}}/ca-cert-secret" 11 | nginx.ingress.kubernetes.io/auth-tls-verify-depth: "1" 12 | nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: "false" 13 | nginx.ingress.kubernetes.io/proxy-body-size: 64m 14 | allowed-values: "CN={{.Spec.SubjectName}}" 15 | labels: 16 | id: "{{.Spec.EndpointName}}" 17 | endpoint: "{{.Spec.EndpointName}}" 18 | ownerReferences: 19 | - apiVersion: {{.APIVersion}} 20 | kind: {{.Kind}} 21 | name: {{.Name}} 22 | uid: {{.UID}} 23 | controller: {{.Controller}} 24 | blockOwnerDeletion: {{.BlockOwnerDeletion}} 25 | spec: 26 | rules: 27 | - host: {{.Spec.EndpointName}}-{{.ObjectMeta.Namespace}}.{{ GlobalTemplateValue "platformDomain" }} 28 | http: 29 | paths: 30 | - backend: 31 | serviceName: "{{.Spec.EndpointName}}" 32 | servicePort: 9000 33 | tls: 34 | - hosts: 35 | - {{.Spec.EndpointName}}-{{.ObjectMeta.Namespace}}.{{ GlobalTemplateValue "platformDomain" }} 36 | secretName: tls-secret 37 | -------------------------------------------------------------------------------- /helm-deployment/crd-subchart/serving-templates/ovms/service.tmpl: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: "{{.Spec.EndpointName}}" 5 | namespace: "{{.ObjectMeta.Namespace}}" 6 | labels: 7 | id: "{{.Spec.EndpointName}}" 8 | endpoint: "{{.Spec.EndpointName}}" 9 | ownerReferences: 10 | - apiVersion: {{.APIVersion}} 11 | kind: {{.Kind}} 12 | name: {{.Name}} 13 | uid: {{.UID}} 14 | controller: {{.Controller}} 15 | blockOwnerDeletion: {{.BlockOwnerDeletion}} 16 | spec: 17 | selector: 18 | endpoint: "{{.Spec.EndpointName}}" 19 | ports: 20 | - port: 9000 21 | targetPort: 9000 22 | -------------------------------------------------------------------------------- /helm-deployment/crd-subchart/serving-templates/tf-serving/configMap.tmpl: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: "{{.Spec.EndpointName}}" 5 | namespace: "{{.ObjectMeta.Namespace}}" 6 | labels: 7 | id: "{{.Spec.EndpointName}}" 8 | endpoint: "{{.Spec.EndpointName}}" 9 | ownerReferences: 10 | - apiVersion: {{.APIVersion}} 11 | kind: {{.Kind}} 12 | name: {{.Name}} 13 | uid: {{.UID}} 14 | controller: {{.Controller}} 15 | blockOwnerDeletion: {{.BlockOwnerDeletion}} 16 | data: 17 | tf.conf: | 18 | model_config_list: { 19 | config:{ 20 | name:"{{.Spec.ModelName}}", 21 | base_path:"s3://{{.ObjectMeta.Namespace}}/{{.Spec.ModelName}}", 22 | model_platform:"tensorflow", 23 | model_version_policy: {{ .Spec.ModelVersionPolicy }} 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /helm-deployment/crd-subchart/serving-templates/tf-serving/ingress.tmpl: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: "{{.Spec.EndpointName}}" 5 | namespace: "{{.ObjectMeta.Namespace}}" 6 | annotations: 7 | kubernetes.io/ingress.class: nginx 8 | nginx.ingress.kubernetes.io/grpc-backend: "true" 9 | nginx.ingress.kubernetes.io/auth-tls-verify-client: "on" 10 | nginx.ingress.kubernetes.io/auth-tls-secret: "{{.ObjectMeta.Namespace}}/ca-cert-secret" 11 | nginx.ingress.kubernetes.io/auth-tls-verify-depth: "1" 12 | nginx.ingress.kubernetes.io/auth-tls-pass-certificate-to-upstream: "false" 13 | nginx.ingress.kubernetes.io/proxy-body-size: 64m 14 | allowed-values: "CN={{.Spec.SubjectName}}" 15 | labels: 16 | id: "{{.Spec.EndpointName}}" 17 | endpoint: "{{.Spec.EndpointName}}" 18 | ownerReferences: 19 | - apiVersion: {{.APIVersion}} 20 | kind: {{.Kind}} 21 | name: {{.Name}} 22 | uid: {{.UID}} 23 | controller: {{.Controller}} 24 | blockOwnerDeletion: {{.BlockOwnerDeletion}} 25 | spec: 26 | rules: 27 | - host: {{.Spec.EndpointName}}-{{.ObjectMeta.Namespace}}.{{ GlobalTemplateValue "platformDomain" }} 28 | http: 29 | paths: 30 | - backend: 31 | serviceName: "{{.Spec.EndpointName}}" 32 | servicePort: 9000 33 | tls: 34 | - hosts: 35 | - {{.Spec.EndpointName}}-{{.ObjectMeta.Namespace}}.{{ GlobalTemplateValue "platformDomain" }} 36 | secretName: tls-secret 37 | -------------------------------------------------------------------------------- /helm-deployment/crd-subchart/serving-templates/tf-serving/service.tmpl: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: "{{.Spec.EndpointName}}" 5 | namespace: "{{.ObjectMeta.Namespace}}" 6 | labels: 7 | id: "{{.Spec.EndpointName}}" 8 | endpoint: "{{.Spec.EndpointName}}" 9 | ownerReferences: 10 | - apiVersion: {{.APIVersion}} 11 | kind: {{.Kind}} 12 | name: {{.Name}} 13 | uid: {{.UID}} 14 | controller: {{.Controller}} 15 | blockOwnerDeletion: {{.BlockOwnerDeletion}} 16 | spec: 17 | selector: 18 | endpoint: "{{.Spec.EndpointName}}" 19 | ports: 20 | - port: 9000 21 | targetPort: 9000 22 | -------------------------------------------------------------------------------- /helm-deployment/crd-subchart/templates/crd.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1beta1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | name: inference-endpoints.ai.intel.com 5 | namespace: {{ .Values.namespace }} 6 | spec: 7 | group: ai.intel.com 8 | version: v1 9 | scope: Namespaced 10 | names: 11 | plural: inference-endpoints 12 | singular: inference-endpoint 13 | kind: InferenceEndpoint 14 | shortNames: 15 | - ie 16 | validation: 17 | openAPIV3Schema: 18 | properties: 19 | spec: 20 | required: 21 | - modelName 22 | - endpointName 23 | - subjectName 24 | - servingName 25 | properties: 26 | modelName: 27 | type: string 28 | minLength: 3 29 | endpointName: 30 | type: string 31 | minLength: 3 32 | subjectName: 33 | type: string 34 | pattern: '^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$' 35 | modelVersionPolicy: 36 | type: string 37 | pattern: '^\s*{\s*(specific\s*{\s*(versions:\s*\d+\s+)*versions:\s*\d+\s*}|all\s*{\s*}|latest\s*{\s*})\s*}\s*$' 38 | resources: 39 | type: object 40 | properties: 41 | additionalProperties: 42 | type: string 43 | replicas: 44 | type: integer 45 | format: int32 46 | minimum: 0 47 | servingName: 48 | type: string 49 | minLength: 1 50 | -------------------------------------------------------------------------------- /helm-deployment/crd-subchart/templates/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: {{ .Values.namespace }} 5 | -------------------------------------------------------------------------------- /helm-deployment/crd-subchart/templates/template-config.yaml: -------------------------------------------------------------------------------- 1 | {{- $namespace := .Values.namespace -}} 2 | {{- range $path, $bytes := .Files.Glob "serving-templates/*/deployment.tmpl" }} 3 | {{- $folder := base (dir $path) }} 4 | apiVersion: v1 5 | kind: ConfigMap 6 | metadata: 7 | name: {{ $folder }} 8 | namespace: {{ $namespace }} 9 | data: 10 | {{ ($.Files.Glob (printf "serving-templates/%s/*" $folder)).AsConfig | indent 2 }} 11 | --- 12 | {{- end }} 13 | -------------------------------------------------------------------------------- /helm-deployment/crd-subchart/values.yaml: -------------------------------------------------------------------------------- 1 | image: 2 | tag: 3 | namespace: "crd" 4 | docker_secret: false 5 | platformDomain: 6 | s3_use_https: 7 | s3_verify_ssl: 0 8 | -------------------------------------------------------------------------------- /helm-deployment/dex-subchart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | appVersion: "1.0" 3 | description: A Helm chart for Kubernetes 4 | name: imm-dex-subchart 5 | version: 0.3.0 6 | -------------------------------------------------------------------------------- /helm-deployment/dex-subchart/certs/generate-dex-certs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Copyright (c) 2018 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | # This script shows how to generate certificates for dex internal interface 19 | 20 | # Generate CA 21 | openssl genrsa -out ca-dex.key 4096 22 | openssl req -new -x509 -days 365 -key ca-dex.key -out ca-dex.crt -subj "/CN=ca-dex" 23 | 24 | # Generate server key/cert 25 | openssl genrsa -out dex.key 4096 26 | openssl req -new -key dex.key -out dex.csr -subj "/CN=dex.${DEX_NAMESPACE}" 27 | openssl x509 -req -days 365 -in dex.csr -CA ca-dex.crt -CAkey ca-dex.key -set_serial 01 -out dex.crt 28 | -------------------------------------------------------------------------------- /helm-deployment/dex-subchart/certs/generate-ing-ca.sh: -------------------------------------------------------------------------------- 1 | # Generate valid CA for ingress 2 | openssl genrsa -out ca-ing.key 4096 3 | openssl req -new -x509 -days 365 -key ca-ing.key -out ca-ing.crt -subj "/CN=ca-ing" 4 | 5 | -------------------------------------------------------------------------------- /helm-deployment/dex-subchart/certs/generate-ing-dex-certs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Copyright (c) 2018 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | # Example script generating TLS certificates for dex external interface to be configured in K8S ingress records. 19 | 20 | 21 | # Generate valid ing-dex server key/cert 22 | openssl genrsa -out ing-dex.key 4096 23 | openssl req -new -key ing-dex.key -out ing-dex.csr -subj "/CN=${DEX_DOMAIN_NAME}" 24 | openssl x509 -req -days 365 -in ing-dex.csr -CA ca-ing.crt -CAkey ca-ing.key -set_serial 01 -out ing-dex.crt 25 | cat ca-ing.crt >> ing-dex.crt 26 | -------------------------------------------------------------------------------- /helm-deployment/dex-subchart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | */}} 13 | {{- define "fullname" -}} 14 | {{- $name := default .Chart.Name .Values.nameOverride -}} 15 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 16 | {{- end -}} 17 | -------------------------------------------------------------------------------- /helm-deployment/dex-subchart/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | labels: 5 | app: dex 6 | name: dex 7 | namespace: {{ .Values.namespace }} 8 | spec: 9 | replicas: 1 10 | template: 11 | metadata: 12 | labels: 13 | app: dex 14 | spec: 15 | serviceAccountName: dex 16 | containers: 17 | - image: quay.io/dexidp/dex:v2.10.0 18 | name: dex 19 | command: ["/usr/local/bin/dex", "serve", "/etc/dex/cfg/config.yaml"] 20 | ports: 21 | - name: https 22 | containerPort: 443 23 | volumeMounts: 24 | - name: config 25 | mountPath: /etc/dex/cfg 26 | - name: https-tls 27 | mountPath: /etc/dex/tls/https/server 28 | {{- if .Values.rootCAsecret }} 29 | - name: rootca 30 | mountPath: /etc/dex/ca 31 | {{- end}} 32 | resources: 33 | {{ toYaml .Values.resources | indent 10 }} 34 | env: 35 | {{ toYaml .Values.env | indent 10 }} 36 | volumes: 37 | - name: config 38 | secret: 39 | defaultMode: 420 40 | secretName: dex 41 | items: 42 | - key: config.yaml 43 | path: config.yaml 44 | - name: https-tls 45 | secret: 46 | defaultMode: 420 47 | secretName: dex-key-cert 48 | {{- if .Values.rootCAsecret }} 49 | - name: rootca 50 | secret: 51 | secretName: {{ .Values.rootCAsecret }} 52 | {{- end}} 53 | -------------------------------------------------------------------------------- /helm-deployment/dex-subchart/templates/dex-ca.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: ca-secret-dex 5 | namespace: {{ .Values.namespace }} 6 | labels: 7 | app: {{ template "fullname" . }} 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | type: Opaque 12 | data: 13 | "ca.crt": |- 14 | {{ .Files.Get "certs/ca-dex.crt" | b64enc | indent 4 }} 15 | -------------------------------------------------------------------------------- /helm-deployment/dex-subchart/templates/dex-ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $serviceName := .Values.service.name -}} 3 | {{- $servicePort := .Values.service.externalPort -}} 4 | {{- $host := .Values.ingress.hosts -}} 5 | apiVersion: extensions/v1beta1 6 | kind: Ingress 7 | metadata: 8 | name: {{ .Values.service.name }} 9 | namespace: {{ .Values.namespace }} 10 | labels: 11 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 12 | release: {{ .Release.Name }} 13 | heritage: {{ .Release.Service }} 14 | annotations: 15 | {{- range $key, $value := .Values.ingress.annotations }} 16 | {{ $key }}: {{ $value | quote }} 17 | {{- end }} 18 | generation: 2 19 | spec: 20 | rules: 21 | - host: {{ $host }} 22 | http: 23 | paths: 24 | - backend: 25 | serviceName: {{ $serviceName }} 26 | servicePort: {{ $servicePort }} 27 | tls: 28 | - secretName: tls-ing-dex-secret 29 | hosts: 30 | - {{ $host }} 31 | {{- end -}} 32 | -------------------------------------------------------------------------------- /helm-deployment/dex-subchart/templates/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: {{ .Values.namespace }} 5 | -------------------------------------------------------------------------------- /helm-deployment/dex-subchart/templates/rolebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1beta1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | labels: 5 | app: dex 6 | name: dex 7 | namespace: {{ .Values.namespace }} 8 | roleRef: 9 | apiGroup: rbac.authorization.k8s.io 10 | kind: ClusterRole 11 | name: cluster-admin 12 | subjects: 13 | - kind: ServiceAccount 14 | name: dex 15 | namespace: {{ .Values.namespace }} 16 | -------------------------------------------------------------------------------- /helm-deployment/dex-subchart/templates/root-ca.yaml: -------------------------------------------------------------------------------- 1 | {{ if .Values.rootCAfile }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: {{ .Values.rootCAsecret }} 6 | namespace: {{ .Values.namespace }} 7 | labels: 8 | app: {{ template "fullname" . }} 9 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 10 | release: "{{ .Release.Name }}" 11 | heritage: "{{ .Release.Service }}" 12 | type: Opaque 13 | data: 14 | "ldap.ca": |- 15 | {{ $.Files.Get .Values.rootCAfile | b64enc | indent 4 }} 16 | {{ end }} 17 | -------------------------------------------------------------------------------- /helm-deployment/dex-subchart/templates/secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: dex 5 | namespace: {{ .Values.namespace }} 6 | data: 7 | config.yaml: {{ toYaml .Values.config | b64enc }} 8 | -------------------------------------------------------------------------------- /helm-deployment/dex-subchart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: dex 5 | namespace: {{ .Values.namespace }} 6 | labels: 7 | app: dex 8 | spec: 9 | type: ClusterIP 10 | ports: 11 | - name: https 12 | port: 443 13 | targetPort: 443 14 | selector: 15 | app: dex 16 | -------------------------------------------------------------------------------- /helm-deployment/dex-subchart/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | labels: 5 | app: dex 6 | name: dex 7 | namespace: {{ .Values.namespace }} 8 | -------------------------------------------------------------------------------- /helm-deployment/dex-subchart/templates/tls-dex-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: dex-key-cert 5 | namespace: {{ .Values.namespace }} 6 | labels: 7 | app: {{ template "fullname" . }} 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | type: kubernetes.io/tls 12 | data: 13 | "tls.key": |- 14 | {{ .Files.Get "certs/dex.key" | b64enc | indent 4 }} 15 | "tls.crt": |- 16 | {{ .Files.Get "certs/dex.crt" | b64enc | indent 4 }} 17 | -------------------------------------------------------------------------------- /helm-deployment/dex-subchart/templates/tls-ing-dex-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: tls-ing-dex-secret 5 | namespace: {{ .Values.namespace }} 6 | labels: 7 | app: {{ template "fullname" . }} 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | type: kubernetes.io/tls 12 | data: 13 | "tls.key": |- 14 | {{ .Files.Get "certs/ing-dex.key" | b64enc | indent 4 }} 15 | "tls.crt": |- 16 | {{ .Files.Get "certs/ing-dex.crt" | b64enc | indent 4 }} 17 | -------------------------------------------------------------------------------- /helm-deployment/dex-subchart/values.yaml: -------------------------------------------------------------------------------- 1 | issuer: toreplacedbyissuer 2 | namespace: "dex" 3 | config: 4 | 5 | service: 6 | name: dex 7 | type: LoadBalancer 8 | externalPort: 443 9 | ingress: 10 | enabled: true 11 | # Used to create Ingress record (should used with service.type: ClusterIP). 12 | hosts: toreplacedbyingresshosts 13 | serviceName: dex 14 | servicePort: 443 15 | annotations: 16 | kubernetes.io/ingress.class: nginx 17 | nginx.ingress.kubernetes.io/proxy-body-size: 8m 18 | nginx.ingress.kubernetes.io/secure-backends: "true" 19 | nginx.ingress.kubernetes.io/secure-verify-ca-secret: ca-secret-dex 20 | nginx.ingress.kubernetes.io/ssl-redirect: "false" 21 | tls: 22 | secretName: dex-key-cert 23 | hosts: toreplacedbyingresstlshosts 24 | resources: {} 25 | -------------------------------------------------------------------------------- /helm-deployment/ing-subchart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: A Helm chart for Kubernetes 3 | name: imm-ingress 4 | version: 0.3.0 5 | -------------------------------------------------------------------------------- /helm-deployment/ing-subchart/README.md: -------------------------------------------------------------------------------- 1 | # Helm deployment of Ingress Nginx Controller 2 | 3 | ## Preparation to installation 4 | 5 | Before installation is required to specify type of k8s cluster. 6 | If you use Google Cloud as your k8s provider you have to specify ```ingType``` value as ``cloud-generic``. 7 | If you have k8s installed on bare metal you have to specify ```ingType``` value as ``baremetal``. 8 | 9 | In case you use another providers please check process of deployment in this [guide](https://github.com/kubernetes/ingress-nginx/blob/master/docs/deploy/index.md) 10 | 11 | ## Installation 12 | 13 | To install this chart after preparation phase use: 14 | 15 | ```helm install .``` -------------------------------------------------------------------------------- /helm-deployment/ing-subchart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | */}} 13 | {{- define "fullname" -}} 14 | {{- $name := default .Chart.Name .Values.nameOverride -}} 15 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 16 | {{- end -}} 17 | -------------------------------------------------------------------------------- /helm-deployment/ing-subchart/templates/default-http-backend-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: default-http-backend 5 | namespace: ingress-nginx 6 | labels: 7 | app: default-http-backend 8 | spec: 9 | ports: 10 | - port: 80 11 | targetPort: 8080 12 | selector: 13 | app: default-http-backend -------------------------------------------------------------------------------- /helm-deployment/ing-subchart/templates/default-http-backend.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: default-http-backend 5 | labels: 6 | app: default-http-backend 7 | namespace: ingress-nginx 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: default-http-backend 13 | template: 14 | metadata: 15 | labels: 16 | app: default-http-backend 17 | spec: 18 | terminationGracePeriodSeconds: 60 19 | containers: 20 | - name: default-http-backend 21 | # Any image is permissible as long as: 22 | # 1. It serves a 404 page at / 23 | # 2. It serves 200 on a /healthz endpoint 24 | image: gcr.io/google_containers/defaultbackend:1.4 25 | livenessProbe: 26 | httpGet: 27 | path: /healthz 28 | port: 8080 29 | scheme: HTTP 30 | initialDelaySeconds: 30 31 | timeoutSeconds: 5 32 | ports: 33 | - containerPort: 8080 34 | resources: 35 | limits: 36 | cpu: 10m 37 | memory: 20Mi 38 | requests: 39 | cpu: 10m 40 | memory: 20Mi -------------------------------------------------------------------------------- /helm-deployment/ing-subchart/templates/ingress-nginx-baremetal.yaml: -------------------------------------------------------------------------------- 1 | {{- if eq .Values.ingType "baremetal" -}} 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: ingress-nginx 6 | namespace: ingress-nginx 7 | spec: 8 | type: NodePort 9 | ports: 10 | - name: http 11 | port: 80 12 | targetPort: 80 13 | protocol: TCP 14 | - name: https 15 | port: 443 16 | targetPort: 443 17 | protocol: TCP 18 | selector: 19 | app: ingress-nginx 20 | {{- end -}} 21 | -------------------------------------------------------------------------------- /helm-deployment/ing-subchart/templates/ingress-nginx-cloud-generic.yaml: -------------------------------------------------------------------------------- 1 | {{- if eq .Values.ingType "cloud-generic" -}} 2 | kind: Service 3 | apiVersion: v1 4 | metadata: 5 | name: ingress-nginx 6 | namespace: ingress-nginx 7 | labels: 8 | app: ingress-nginx 9 | spec: 10 | externalTrafficPolicy: Cluster 11 | type: LoadBalancer 12 | selector: 13 | app: ingress-nginx 14 | ports: 15 | - name: http 16 | port: 80 17 | targetPort: http 18 | - name: https 19 | port: 443 20 | targetPort: https 21 | {{- end -}} 22 | -------------------------------------------------------------------------------- /helm-deployment/ing-subchart/templates/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: ingress-nginx -------------------------------------------------------------------------------- /helm-deployment/ing-subchart/templates/nginx-configuration-configmap.yaml: -------------------------------------------------------------------------------- 1 | kind: ConfigMap 2 | apiVersion: v1 3 | metadata: 4 | name: nginx-configuration 5 | namespace: ingress-nginx 6 | labels: 7 | app: ingress-nginx 8 | -------------------------------------------------------------------------------- /helm-deployment/ing-subchart/templates/nginx-ingress-clusterrole-nisa-binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1beta1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: nginx-ingress-clusterrole-nisa-binding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: nginx-ingress-clusterrole 9 | subjects: 10 | - kind: ServiceAccount 11 | name: nginx-ingress-serviceaccount 12 | namespace: ingress-nginx -------------------------------------------------------------------------------- /helm-deployment/ing-subchart/templates/nginx-ingress-clusterrole.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1beta1 2 | kind: ClusterRole 3 | metadata: 4 | name: nginx-ingress-clusterrole 5 | rules: 6 | - apiGroups: 7 | - "" 8 | resources: 9 | - configmaps 10 | - endpoints 11 | - nodes 12 | - pods 13 | - secrets 14 | verbs: 15 | - list 16 | - watch 17 | - apiGroups: 18 | - "" 19 | resources: 20 | - nodes 21 | verbs: 22 | - get 23 | - apiGroups: 24 | - "" 25 | resources: 26 | - services 27 | verbs: 28 | - get 29 | - list 30 | - watch 31 | - apiGroups: 32 | - "extensions" 33 | resources: 34 | - ingresses 35 | verbs: 36 | - get 37 | - list 38 | - watch 39 | - apiGroups: 40 | - "" 41 | resources: 42 | - events 43 | verbs: 44 | - create 45 | - patch 46 | - apiGroups: 47 | - "extensions" 48 | resources: 49 | - ingresses/status 50 | verbs: 51 | - update 52 | -------------------------------------------------------------------------------- /helm-deployment/ing-subchart/templates/nginx-ingress-role-nisa-binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1beta1 2 | kind: RoleBinding 3 | metadata: 4 | name: nginx-ingress-role-nisa-binding 5 | namespace: ingress-nginx 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: Role 9 | name: nginx-ingress-role 10 | subjects: 11 | - kind: ServiceAccount 12 | name: nginx-ingress-serviceaccount 13 | namespace: ingress-nginx -------------------------------------------------------------------------------- /helm-deployment/ing-subchart/templates/nginx-ingress-role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1beta1 2 | kind: Role 3 | metadata: 4 | name: nginx-ingress-role 5 | namespace: ingress-nginx 6 | rules: 7 | - apiGroups: 8 | - "" 9 | resources: 10 | - configmaps 11 | - pods 12 | - secrets 13 | - namespaces 14 | verbs: 15 | - get 16 | - apiGroups: 17 | - "" 18 | resources: 19 | - configmaps 20 | resourceNames: 21 | # Defaults to "-" 22 | # Here: "-" 23 | # This has to be adapted if you change either parameter 24 | # when launching the nginx-ingress-controller. 25 | - "ingress-controller-leader-nginx" 26 | verbs: 27 | - get 28 | - update 29 | - apiGroups: 30 | - "" 31 | resources: 32 | - configmaps 33 | verbs: 34 | - create 35 | - apiGroups: 36 | - "" 37 | resources: 38 | - endpoints 39 | verbs: 40 | - get -------------------------------------------------------------------------------- /helm-deployment/ing-subchart/templates/nginx-ingress-serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | name: nginx-ingress-serviceaccount 5 | namespace: ingress-nginx -------------------------------------------------------------------------------- /helm-deployment/ing-subchart/templates/nginx-template-configmap.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: nginx-template 5 | namespace: ingress-nginx 6 | data: 7 | "nginx.tmpl": |- 8 | {{ .Files.Get "nginx.tmpl" | indent 4 }} 9 | -------------------------------------------------------------------------------- /helm-deployment/ing-subchart/templates/tcp-services-configmap.yaml: -------------------------------------------------------------------------------- 1 | kind: ConfigMap 2 | apiVersion: v1 3 | metadata: 4 | name: tcp-services 5 | namespace: ingress-nginx -------------------------------------------------------------------------------- /helm-deployment/ing-subchart/templates/udp-services-configmap.yaml: -------------------------------------------------------------------------------- 1 | kind: ConfigMap 2 | apiVersion: v1 3 | metadata: 4 | name: udp-services 5 | namespace: ingress-nginx -------------------------------------------------------------------------------- /helm-deployment/ing-subchart/values.yaml: -------------------------------------------------------------------------------- 1 | ingType: "cloud-generic" 2 | -------------------------------------------------------------------------------- /helm-deployment/ldap-subchart/Chart.yaml: -------------------------------------------------------------------------------- 1 | name: imm-openldap 2 | home: https://www.openldap.org 3 | version: 0.3.0 4 | appVersion: 2.4.44 5 | description: Community developed LDAP software 6 | icon: http://www.openldap.org/images/headers/LDAPworm.gif 7 | keywords: 8 | - ldap 9 | - openldap 10 | sources: 11 | - https://github.com/kubernetes/charts 12 | maintainers: 13 | - name: enis 14 | email: enis@apache.org 15 | engine: gotpl 16 | -------------------------------------------------------------------------------- /helm-deployment/ldap-subchart/certs/genereate_ldap_certs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | # Example how to create self-signed CA for OpenLDAP component 19 | LDAP_DOMAIN_NAME="${LDAP_DOMAIN_NAME:=imm-openldap.default}" 20 | 21 | # Generate CA for OpenLDAP 22 | openssl genrsa -out ca-ldap.key 4096 23 | openssl req -new -x509 -days 365 -key ca-ldap.key -out ca.crt -subj "/CN=ca-ldap" 24 | 25 | # Generate server key/cert 26 | openssl genrsa -out ldap.key 4096 27 | openssl req -new -key ldap.key -out ldap.csr -subj "/CN=${LDAP_DOMAIN_NAME}" 28 | openssl x509 -req -days 365 -in ldap.csr -CA ca.crt -CAkey ca-ldap.key -set_serial 01 -out ldap.crt 29 | -------------------------------------------------------------------------------- /helm-deployment/ldap-subchart/customLdifFiles.yaml: -------------------------------------------------------------------------------- 1 | customLdifFiles: 2 | ldif: |- 3 | dn: ou=People,dc=example,dc=org 4 | objectClass: organizationalUnit 5 | ou: People 6 | 7 | dn: cn=user,ou=People,dc=example,dc=org 8 | objectClass: person 9 | objectClass: inetOrgPerson 10 | sn: user 11 | cn: user 12 | mail: user@example.com 13 | userpassword: *password* 14 | 15 | # Group definitions. 16 | dn: ou=Groups,dc=example,dc=org 17 | objectClass: organizationalUnit 18 | ou: Groups 19 | 20 | dn: cn=admin,ou=Groups,dc=example,dc=org 21 | objectClass: groupOfNames 22 | cn: admin 23 | member: cn=user,ou=People,dc=example,dc=org 24 | 25 | -------------------------------------------------------------------------------- /helm-deployment/ldap-subchart/deployment.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Copyright (c) 2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | cd certs 18 | ./genereate_ldap_certs.sh 19 | cd .. 20 | helm install --name imm-openldap -f ../../installer/ldap/customLdifFiles.yaml . 21 | -------------------------------------------------------------------------------- /helm-deployment/ldap-subchart/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | OpenLDAP has been installed. You can access the server from within the k8s cluster using: 2 | 3 | {{ template "openldap.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.service.ldapPort }} 4 | 5 | 6 | You can access the LDAP adminPassword and configPassword using: 7 | 8 | kubectl get secret --namespace {{ .Release.Namespace }} {{ template "openldap.secretName" . }} -o jsonpath="{.data.LDAP_ADMIN_PASSWORD}" | base64 --decode; echo 9 | kubectl get secret --namespace {{ .Release.Namespace }} {{ template "openldap.secretName" . }} -o jsonpath="{.data.LDAP_CONFIG_PASSWORD}" | base64 --decode; echo 10 | 11 | 12 | You can access the content of ldif bootstrap configuration using: 13 | 14 | kubectl get secret imm-openldap-customldif -o json | jq -r '.data."immconfig.ldif"' | base64 -decode 15 | 16 | You can access the LDAP service, from within the cluster (or with kubectl port-forward) with a command like (replace password and domain): 17 | ldapsearch -x -H ldap://{{ template "openldap.fullname" . }}-service.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.service.ldapPort }} -b dc=example,dc=org -D "cn=admin,dc=example,dc=org" -w $LDAP_ADMIN_PASSWORD 18 | 19 | 20 | Test server health using Helm test: 21 | helm test {{ .Release.Name }} 22 | 23 | 24 | You can also consider installing the helm chart for phpldapadmin to manage this instance of OpenLDAP, or install Apache Directory Studio, and connect using kubectl port-forward. 25 | -------------------------------------------------------------------------------- /helm-deployment/ldap-subchart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "openldap.name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | If release name contains chart name it will be used as a full name. 13 | */}} 14 | {{- define "openldap.fullname" -}} 15 | {{- if .Values.fullnameOverride -}} 16 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} 17 | {{- else -}} 18 | {{- $name := default .Chart.Name .Values.nameOverride -}} 19 | {{- if contains $name .Release.Name -}} 20 | {{- .Release.Name | trunc 63 | trimSuffix "-" -}} 21 | {{- else -}} 22 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 23 | {{- end -}} 24 | {{- end -}} 25 | {{- end -}} 26 | 27 | {{/* 28 | Create chart name and version as used by the chart label. 29 | */}} 30 | {{- define "openldap.chart" -}} 31 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} 32 | {{- end -}} 33 | 34 | 35 | {{/* 36 | Generate chart secret name 37 | */}} 38 | {{- define "openldap.secretName" -}} 39 | {{ default (include "openldap.fullname" .) .Values.existingSecret }} 40 | {{- end -}} 41 | -------------------------------------------------------------------------------- /helm-deployment/ldap-subchart/templates/certs_secret.yaml: -------------------------------------------------------------------------------- 1 | {{ if .Values.cert_files }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: {{ .Values.certs_secret }} 6 | labels: 7 | app: {{ template "openldap.name" . }} 8 | chart: {{ template "openldap.chart" . }} 9 | release: {{ .Release.Name }} 10 | heritage: {{ .Release.Service }} 11 | {{- if .Values.extraLabels }} 12 | {{ toYaml .Values.extraLabels | indent 4 }} 13 | {{- end }} 14 | type: Opaque 15 | data: 16 | {{- range $key, $val := .Values.cert_files }} 17 | {{ $key }}: |- 18 | {{ $.Files.Get $val | b64enc | indent 4 }} 19 | {{- end }} 20 | {{ end }} 21 | 22 | 23 | -------------------------------------------------------------------------------- /helm-deployment/ldap-subchart/templates/configmap-env.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # A ConfigMap spec for openldap slapd that map directly to env variables in the Pod. 3 | # List of environment variables supported is from the docker image: 4 | # https://github.com/osixia/docker-openldap#beginner-guide 5 | # Note that passwords are defined as secrets 6 | # 7 | apiVersion: v1 8 | kind: ConfigMap 9 | metadata: 10 | name: {{ template "openldap.fullname" . }}-env 11 | labels: 12 | app: {{ template "openldap.name" . }} 13 | chart: {{ template "openldap.chart" . }} 14 | release: {{ .Release.Name }} 15 | heritage: {{ .Release.Service }} 16 | {{- if .Values.extraLabels }} 17 | {{ toYaml .Values.extraLabels | indent 4 }} 18 | {{- end }} 19 | data: 20 | {{ toYaml .Values.env | indent 2 }} 21 | -------------------------------------------------------------------------------- /helm-deployment/ldap-subchart/templates/pvc.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }} 2 | kind: PersistentVolumeClaim 3 | apiVersion: v1 4 | metadata: 5 | name: {{ template "openldap.fullname" . }} 6 | labels: 7 | app: {{ template "openldap.name" . }} 8 | chart: {{ template "openldap.chart" . }} 9 | release: {{ .Release.Name }} 10 | heritage: {{ .Release.Service }} 11 | {{- if .Values.extraLabels }} 12 | {{ toYaml .Values.extraLabels | indent 4 }} 13 | {{- end }} 14 | spec: 15 | accessModes: 16 | - {{ .Values.persistence.accessMode | quote }} 17 | resources: 18 | requests: 19 | storage: {{ .Values.persistence.size | quote }} 20 | {{- if .Values.persistence.storageClass }} 21 | {{- if (eq "-" .Values.persistence.storageClass) }} 22 | storageClassName: "" 23 | {{- else }} 24 | storageClassName: "{{ .Values.persistence.storageClass }}" 25 | {{- end }} 26 | {{- end }} 27 | {{- end }} 28 | -------------------------------------------------------------------------------- /helm-deployment/ldap-subchart/templates/secret-customldif.yaml: -------------------------------------------------------------------------------- 1 | # 2 | # A Secret spec for openldap slapd that map directly to files under 3 | # /container/service/slapd/assets/config/bootstrap/ldif/custom 4 | # 5 | {{- if .Values.customLdifFiles }} 6 | apiVersion: v1 7 | kind: Secret 8 | metadata: 9 | name: {{ template "openldap.fullname" . }}-customldif 10 | labels: 11 | app: {{ template "openldap.name" . }} 12 | chart: {{ template "openldap.chart" . }} 13 | release: {{ .Release.Name }} 14 | heritage: {{ .Release.Service }} 15 | {{- if .Values.extraLabels }} 16 | {{ toYaml .Values.extraLabels | indent 4 }} 17 | {{- end }} 18 | 19 | type: Opaque 20 | 21 | data: 22 | immconfig.ldif: {{ .Values.customLdifFiles.ldif | replace "*password*" (randAlphaNum 8) | b64enc | quote }} 23 | 24 | {{ end }} 25 | -------------------------------------------------------------------------------- /helm-deployment/ldap-subchart/templates/secret.yaml: -------------------------------------------------------------------------------- 1 | {{ if not .Values.existingSecret }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: {{ template "openldap.fullname" . }} 6 | labels: 7 | app: {{ template "openldap.name" . }} 8 | chart: {{ template "openldap.chart" . }} 9 | release: {{ .Release.Name }} 10 | heritage: {{ .Release.Service }} 11 | {{- if .Values.extraLabels }} 12 | {{ toYaml .Values.extraLabels | indent 4 }} 13 | {{- end }} 14 | type: Opaque 15 | data: 16 | LDAP_ADMIN_PASSWORD: {{ .Values.adminPassword | default (randAlphaNum 32) | b64enc | quote }} 17 | LDAP_CONFIG_PASSWORD: {{ .Values.configPassword | default (randAlphaNum 32) | b64enc | quote }} 18 | {{ end }} 19 | -------------------------------------------------------------------------------- /helm-deployment/ldap-subchart/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | {{- if .Values.service.annotations }} 5 | annotations: 6 | {{ toYaml .Values.service.annotations | indent 4 }} 7 | {{- end }} 8 | name: {{ template "openldap.fullname" . }} 9 | labels: 10 | app: {{ template "openldap.name" . }} 11 | chart: {{ template "openldap.chart" . }} 12 | release: {{ .Release.Name }} 13 | heritage: {{ .Release.Service }} 14 | {{- if .Values.extraLabels }} 15 | {{ toYaml .Values.extraLabels | indent 4 }} 16 | {{- end }} 17 | spec: 18 | clusterIP: {{ .Values.service.clusterIP | quote }} 19 | {{- if .Values.service.externalIPs }} 20 | externalIPs: 21 | {{ toYaml .Values.service.externalIPs | indent 4 }} 22 | {{- end }} 23 | {{- if .Values.service.loadBalancerIP }} 24 | loadBalancerIP: {{ .Values.service.loadBalancerIP | quote }} 25 | {{- end }} 26 | {{- if .Values.service.loadBalancerSourceRanges }} 27 | loadBalancerSourceRanges: 28 | {{ toYaml .Values.service.loadBalancerSourceRanges | indent 4 }} 29 | {{- end }} 30 | ports: 31 | - name: ldap-port 32 | protocol: TCP 33 | port: {{ .Values.service.ldapPort }} 34 | targetPort: ldap-port 35 | - name: ssl-ldap-port 36 | protocol: TCP 37 | port: {{ .Values.service.sslLdapPort }} 38 | targetPort: ssl-ldap-port 39 | selector: 40 | app: {{ template "openldap.name" . }} 41 | release: {{ .Release.Name }} 42 | type: {{ .Values.service.type }} 43 | -------------------------------------------------------------------------------- /helm-deployment/ldap-subchart/templates/tests/openldap-test-runner.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.test.enabled -}} 2 | apiVersion: v1 3 | kind: Pod 4 | metadata: 5 | name: "{{ template "openldap.fullname" . }}-test-{{ randAlphaNum 5 | lower }}" 6 | labels: 7 | app: {{ template "openldap.name" . }} 8 | chart: {{ template "openldap.chart" . }} 9 | release: {{ .Release.Name }} 10 | heritage: {{ .Release.Service }} 11 | {{- if .Values.extraLabels }} 12 | {{ toYaml .Values.extraLabels | indent 4 }} 13 | {{- end }} 14 | annotations: 15 | "helm.sh/hook": test-success 16 | spec: 17 | initContainers: 18 | - name: test-framework 19 | image: {{ .Values.test.image.repository }}:{{ .Values.test.image.tag }} 20 | command: 21 | - "bash" 22 | - "-c" 23 | - | 24 | set -ex 25 | # copy bats to tools dir 26 | cp -R /usr/local/libexec/ /tools/bats/ 27 | volumeMounts: 28 | - mountPath: /tools 29 | name: tools 30 | containers: 31 | - name: {{ .Release.Name }}-test 32 | image: {{ .Values.test.image.repository }}:{{ .Values.test.image.tag }} 33 | envFrom: 34 | - secretRef: 35 | name: {{ template "openldap.secretName" . }} 36 | command: ["/tools/bats/bats", "-t", "/tests/run.sh"] 37 | volumeMounts: 38 | - mountPath: /tests 39 | name: tests 40 | readOnly: true 41 | - mountPath: /tools 42 | name: tools 43 | volumes: 44 | - name: tests 45 | configMap: 46 | name: {{ template "openldap.fullname" . }}-tests 47 | - name: tools 48 | emptyDir: {} 49 | restartPolicy: Never 50 | {{- end -}} 51 | -------------------------------------------------------------------------------- /helm-deployment/ldap-subchart/templates/tests/openldap-tests.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.test.enabled -}} 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: {{ template "openldap.fullname" . }}-tests 6 | labels: 7 | app: {{ template "openldap.name" . }} 8 | chart: {{ template "openldap.chart" . }} 9 | release: {{ .Release.Name }} 10 | heritage: {{ .Release.Service }} 11 | {{- if .Values.extraLabels }} 12 | {{ toYaml .Values.extraLabels | indent 4 }} 13 | {{- end }} 14 | data: 15 | run.sh: |- 16 | @test "Testing connecting to slapd server" { 17 | # Ideally, this should be in the docker image, but there is not a generic image we can use 18 | # with bats and ldap-utils installed. It is not worth for now to push an image for this. 19 | apt-get update && apt-get install -y ldap-utils 20 | ldapsearch -x -H ldap://{{ template "openldap.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.service.ldapPort }} -b "dc=example,dc=org" -D "cn=admin,dc=example,dc=org" -w $LDAP_ADMIN_PASSWORD 21 | } 22 | {{- end -}} 23 | -------------------------------------------------------------------------------- /helm-deployment/management-api-subchart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | appVersion: "1.0" 3 | description: A Helm chart for Kubernetes 4 | name: imm-management-api-chart 5 | version: 0.3.0 6 | -------------------------------------------------------------------------------- /helm-deployment/management-api-subchart/certs/ca.conf: -------------------------------------------------------------------------------- 1 | # Mainly copied from: 2 | # http://swearingscience.com/2009/01/18/openssl-self-signed-ca/ 3 | 4 | [ ca ] 5 | default_ca = myca 6 | 7 | [ crl_ext ] 8 | # issuerAltName=issuer:copy #this would copy the issuer name to altname 9 | authorityKeyIdentifier=keyid:always 10 | 11 | [ myca ] 12 | dir = ./ 13 | new_certs_dir = $dir 14 | unique_subject = no 15 | certificate = $dir/ca.crt 16 | database = $dir/certindex 17 | private_key = $dir/ca.key 18 | serial = $dir/certserial 19 | default_days = 730 20 | default_md = sha1 21 | policy = myca_policy 22 | x509_extensions = myca_extensions 23 | crlnumber = $dir/crlnumber 24 | default_crl_days = 730 25 | 26 | [ myca_policy ] 27 | commonName = supplied 28 | stateOrProvinceName = supplied 29 | countryName = optional 30 | emailAddress = optional 31 | organizationName = supplied 32 | organizationalUnitName = optional 33 | 34 | [ myca_extensions ] 35 | basicConstraints = CA:false 36 | subjectKeyIdentifier = hash 37 | authorityKeyIdentifier = keyid:always 38 | keyUsage = digitalSignature,keyEncipherment 39 | extendedKeyUsage = serverAuth 40 | crlDistributionPoints = URI:http://example.com/root.crl 41 | subjectAltName = @alt_names 42 | 43 | [alt_names] 44 | DNS.1 = example.com 45 | DNS.2 = *.example.com 46 | -------------------------------------------------------------------------------- /helm-deployment/management-api-subchart/certs/generate-ing-management-api-certs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | # Generate server key/cert 19 | openssl genrsa -out ing-mgt-api.key 4096 20 | openssl req -new -key ing-mgt-api.key -out ing-mgt-api.csr -subj "/CN=${MGMT_DOMAIN_NAME}" 21 | openssl x509 -req -days 365 -in ing-mgt-api.csr -CA ca-ing.crt -CAkey ca-ing.key -set_serial 01 -out ing-mgt-api.crt 22 | cat ca-ing.crt >> ing-mgt-api.crt 23 | -------------------------------------------------------------------------------- /helm-deployment/management-api-subchart/certs/generate-management-api-certs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Copyright (c) 2018 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | # How to generate certificates for Management API internal interface 19 | 20 | # Generate CA for Management Api 21 | openssl genrsa -out ca-mgt-api.key 4096 22 | openssl req -new -x509 -days 365 -key ca-mgt-api.key -out ca-mgt-api.crt -subj "/CN=ca-mgt-api" 23 | 24 | # Generate server key/cert 25 | openssl genrsa -out mgt-api.key 4096 26 | openssl req -new -key mgt-api.key -out mgt-api.csr -subj "/CN=management-api.${MGT_NAMESPACE}" 27 | openssl x509 -req -days 365 -in mgt-api.csr -CA ca-mgt-api.crt -CAkey ca-mgt-api.key -set_serial 01 -out mgt-api.crt 28 | -------------------------------------------------------------------------------- /helm-deployment/management-api-subchart/certs/script-wrong-certs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | # Generate invalid client certificate with improper subject name, but signed by proper CA (test purposes) 19 | openssl genrsa -out bad-client.key 4096 20 | openssl req -new -key bad-client.key -out bad-client.csr -subj "/CN=bad-client" 21 | openssl x509 -req -days 365 -in bad-client.csr -CA ca-cert-tf.crt -CAkey ca-cert-tf.key -set_serial 01 -out bad-client.crt 22 | -------------------------------------------------------------------------------- /helm-deployment/management-api-subchart/certs/scriptcert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | # This script shows how to generate test keys and certs 19 | # If you provide different value in annotations.allowed values than "CN=client", remember to change subject name also in client key 20 | 21 | # Generate a CA to be used for creating client certificates 22 | openssl genrsa -out ca-cert-tf.key 4096 23 | openssl req -new -x509 -days 365 -key ca-cert-tf.key -out ca-cert-tf.crt -subj "/CN=ca" 24 | 25 | # Generate client key and certificate authorizing access to inference endpoints. Change the CN as needed. 26 | openssl genrsa -out client-tf.key 4096 27 | openssl req -new -key client-tf.key -out client-tf.csr -subj "/CN=client" 28 | openssl x509 -req -days 365 -in client-tf.csr -CA ca-cert-tf.crt -CAkey ca-cert-tf.key -set_serial 01 -out client-tf.crt 29 | 30 | # Example creating self-signed server key/cert for external inference endpoints 31 | openssl genrsa -out server-tf.key 4096 32 | openssl req -new -x509 -days 365 -key server-tf.key -out server-tf.crt -subj "/CN=*.${DOMAIN_NAME}" 33 | 34 | # Generate empty CRL file 35 | echo 01 > certserial 36 | echo 01 > crlnumber 37 | echo 01 > crlnumber 38 | touch certindex 39 | openssl ca -config ca.conf -gencrl -keyfile ca-cert-tf.key -cert ca-cert-tf.crt -out root.crl.pem 40 | cat root.crl.pem >> ca-cert-tf.crt 41 | -------------------------------------------------------------------------------- /helm-deployment/management-api-subchart/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | */}} 13 | {{- define "fullname" -}} 14 | {{- $name := default .Chart.Name .Values.nameOverride -}} 15 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 16 | {{- end -}} 17 | -------------------------------------------------------------------------------- /helm-deployment/management-api-subchart/templates/cluster-role-binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: imm-cluster-admin-binding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: cluster-admin 9 | subjects: 10 | - apiGroup: rbac.authorization.k8s.io 11 | kind: Group 12 | name: {{ .Values.adminScope }} 13 | -------------------------------------------------------------------------------- /helm-deployment/management-api-subchart/templates/dex-ca.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: custom-ca-secret 5 | namespace: {{ .Values.namespace }} 6 | labels: 7 | app: {{ template "fullname" . }} 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | type: Opaque 12 | data: 13 | "dex_ca.crt": |- 14 | {{ .Files.Get "certs/ca-dex.crt" | b64enc | indent 4 }} 15 | -------------------------------------------------------------------------------- /helm-deployment/management-api-subchart/templates/dex-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: dex 5 | namespace: {{ .Values.namespace }} 6 | data: 7 | staticClient.id: {{ .Values.dex.id | b64enc }} 8 | staticClient.redirectURIs: {{ .Values.dex.redirectURIs | b64enc }} 9 | staticClient.secret: {{ .Values.dex.secret | b64enc }} 10 | -------------------------------------------------------------------------------- /helm-deployment/management-api-subchart/templates/man-api-ca.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: ca-secret-man-api 5 | namespace: {{ .Values.namespace }} 6 | labels: 7 | app: {{ template "fullname" . }} 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | type: Opaque 12 | data: 13 | "ca.crt": |- 14 | {{ .Files.Get "certs/ca-mgt-api.crt" | b64enc | indent 4 }} 15 | -------------------------------------------------------------------------------- /helm-deployment/management-api-subchart/templates/man-api-ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $serviceName := .Values.service.name -}} 3 | {{- $servicePort := .Values.service.externalPort -}} 4 | {{- $host := .Values.ingress.hosts -}} 5 | apiVersion: extensions/v1beta1 6 | kind: Ingress 7 | metadata: 8 | name: {{ .Values.service.name }} 9 | namespace: {{ .Values.namespace }} 10 | labels: 11 | chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} 12 | release: {{ .Release.Name }} 13 | heritage: {{ .Release.Service }} 14 | annotations: 15 | {{- range $key, $value := .Values.ingress.annotations }} 16 | {{ $key }}: {{ $value | quote }} 17 | {{- end }} 18 | generation: 2 19 | spec: 20 | rules: 21 | - host: {{ $host }} 22 | http: 23 | paths: 24 | - backend: 25 | serviceName: {{ $serviceName }} 26 | servicePort: {{ $servicePort }} 27 | tls: 28 | - secretName: tls-ing-management-secret 29 | hosts: 30 | - {{ $host }} 31 | {{- end -}} 32 | 33 | -------------------------------------------------------------------------------- /helm-deployment/management-api-subchart/templates/minio-secret.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.minio.secretCreate -}} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: minio-access-info 6 | namespace: {{ .Values.namespace }} 7 | type: Opaque 8 | data: 9 | "minio.access_key_id": {{ .Values.minio.accessKey | b64enc }} 10 | "minio.access_secret_key": {{ .Values.minio.secretKey | b64enc }} 11 | "minio.endpoint": {{ .Values.minio.endpoint | b64enc }} 12 | "minio.endpoint_url": {{ .Values.minio.endpointUrl | b64enc }} 13 | "minio.minio_region": {{ .Values.minio.minioRegion | b64enc }} 14 | "minio.signature_version": {{ .Values.minio.minioSignatureVersion | b64enc }} 15 | {{- end -}} 16 | -------------------------------------------------------------------------------- /helm-deployment/management-api-subchart/templates/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: {{ .Values.namespace }} 5 | -------------------------------------------------------------------------------- /helm-deployment/management-api-subchart/templates/secrets-serverside.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: tls-secret 5 | namespace: {{ .Values.namespace }} 6 | labels: 7 | app: {{ template "fullname" . }} 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | type: kubernetes.io/tls 12 | data: 13 | "tls.crt": |- 14 | {{ .Files.Get "certs/server-tf.crt" | b64enc | indent 4 }} 15 | "tls.key": |- 16 | {{ .Files.Get "certs/server-tf.key" | b64enc | indent 4 }} 17 | -------------------------------------------------------------------------------- /helm-deployment/management-api-subchart/templates/service-account-rb.yaml: -------------------------------------------------------------------------------- 1 | {{ if .Values.useMgtApiAuthorization }} 2 | apiVersion: rbac.authorization.k8s.io/v1beta1 3 | kind: ClusterRoleBinding 4 | metadata: 5 | name: mgt-api-cluster-admin-binding 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: ClusterRole 9 | name: cluster-admin 10 | subjects: 11 | - kind: ServiceAccount 12 | name: mgt-api 13 | namespace: {{ .Values.namespace }} 14 | {{ end }} 15 | -------------------------------------------------------------------------------- /helm-deployment/management-api-subchart/templates/tls-ing-management-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: tls-ing-management-secret 5 | namespace: {{ .Values.namespace }} 6 | labels: 7 | app: {{ template "fullname" . }} 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | type: kubernetes.io/tls 12 | data: 13 | "tls.crt": |- 14 | {{ .Files.Get "certs/ing-mgt-api.crt" | b64enc | indent 4 }} 15 | "tls.key": |- 16 | {{ .Files.Get "certs/ing-mgt-api.key" | b64enc | indent 4 }} 17 | -------------------------------------------------------------------------------- /helm-deployment/management-api-subchart/templates/tls-management-secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: tls-management-secret 5 | namespace: {{ .Values.namespace }} 6 | labels: 7 | app: {{ template "fullname" . }} 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | type: kubernetes.io/tls 12 | data: 13 | "tls.crt": |- 14 | {{ .Files.Get "certs/mgt-api.crt" | b64enc | indent 4 }} 15 | "tls.key": |- 16 | {{ .Files.Get "certs/mgt-api.key" | b64enc | indent 4 }} 17 | -------------------------------------------------------------------------------- /helm-deployment/management-api-subchart/values.yaml: -------------------------------------------------------------------------------- 1 | image: 2 | tag: 3 | namespace: "mgt-api" 4 | service: 5 | name: management-api 6 | externalPort: 9443 7 | ingress: 8 | enabled: true 9 | # Used to create Ingress record (should used with service.type: ClusterIP). 10 | hosts: 11 | serviceName: management-api 12 | servicePort: 443 13 | annotations: 14 | kubernetes.io/ingress.class: nginx 15 | nginx.ingress.kubernetes.io/proxy-body-size: 32m 16 | nginx.ingress.kubernetes.io/secure-backends: "true" 17 | nginx.ingress.kubernetes.io/secure-verify-ca-secret: ca-secret-man-api 18 | nginx.ingress.kubernetes.io/ssl-redirect: "false" 19 | tls: 20 | secretName: tls-management-secret 21 | hosts: 22 | resources: {} 23 | platformDomain: 24 | dexUrl: "https://dex.dex:443" 25 | dexTokenPath: "/dex/token" 26 | dexAuthPath: "/dex/auth" 27 | dexKeysPath: "/dex/keys" 28 | platformAdminLabel: "platform_admin" 29 | adminScope: "admin" 30 | useMgtApiAuthorization: 31 | ingNamespace: 'ingress-nginx' 32 | minio: 33 | secretCreate: true 34 | accessKey: 35 | secretKey: 36 | endpoint: 37 | endpointUrl: 38 | minioRegion: 39 | minioSignatureVersion: 40 | dex: 41 | id: example-app 42 | redirectURIs: 'http://127.0.0.1:5555/callback' 43 | name: 'Example App' 44 | secret: ZXhhbXBsZS1hcHAtc2VjcmV0 45 | -------------------------------------------------------------------------------- /helm-deployment/minio-subchart/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: A Helm chart for Kubernetes 3 | name: imm-minio 4 | version: 0.3.0 5 | -------------------------------------------------------------------------------- /helm-deployment/minio-subchart/README.md: -------------------------------------------------------------------------------- 1 | ## Helm deployment of Dex 2 | 3 | ### Preparation to installation 4 | 5 | You have to set all values specify in this chapter to properly run this chart 6 | ``` accessKey: 7 | secretKey: 8 | ``` 9 | 10 | ### Installation 11 | 12 | To install this chart after preparation phase use: 13 | ```helm install .``` 14 | 15 | ### MANUAL STEPS REQUIRED TO SECURE MINIO WITH TLS (SELF-SIGNED CERTIFICATES) 16 | 17 | Assumed that self-signed certificate and key is placed in current directory. Cert and key file name is important. 18 | Create kubernetes secret. 19 | 20 | ``` 21 | kubectl create secret generic tls-ssl-minio --from-file=./private.key --from-file=./public.crt 22 | 23 | kubectl edit deployment minioplatform 24 | ``` 25 | 26 | Follow instructions from https://github.com/minio/minio/tree/master/docs/tls/kubernetes#3-update-deployment-yaml-file 27 | -------------------------------------------------------------------------------- /helm-deployment/minio-subchart/requirements.yaml: -------------------------------------------------------------------------------- 1 | # run 'helm dep up .' 2 | dependencies: 3 | - name: minio 4 | version: 1.6.0 5 | repository: https://kubernetes-charts.storage.googleapis.com 6 | condition: minio.enabled 7 | -------------------------------------------------------------------------------- /helm-deployment/minio-subchart/values.yaml: -------------------------------------------------------------------------------- 1 | minio: 2 | enabled: true 3 | accessKey: 4 | secretKey: 5 | -------------------------------------------------------------------------------- /installer/certs/dex-ing-ca.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: ca-ing 5 | namespace: dex 6 | labels: 7 | app: {{ template "fullname" . }} 8 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 9 | release: "{{ .Release.Name }}" 10 | heritage: "{{ .Release.Service }}" 11 | type: Opaque 12 | data: 13 | "ca.crt": |- 14 | {{ .Files.Get "certs/ca-ing.crt" | b64enc | indent 4 }} 15 | -------------------------------------------------------------------------------- /installer/configs/test_LdifFiles.yaml: -------------------------------------------------------------------------------- 1 | customLdifFiles: 2 | ldif: |- 3 | dn: ou=People,dc=example,dc=org 4 | objectClass: organizationalUnit 5 | ou: People 6 | 7 | dn: cn=sun,ou=People,dc=example,dc=org 8 | objectClass: person 9 | objectClass: inetOrgPerson 10 | sn: sun 11 | cn: sun 12 | mail: sun@example.com 13 | userpassword: sun_pass 14 | 15 | dn: cn=mars,ou=People,dc=example,dc=org 16 | objectClass: person 17 | objectClass: inetOrgPerson 18 | sn: mars 19 | cn: mars 20 | mail: mars@example.com 21 | userpassword: mars_pass 22 | 23 | dn: cn=saturn,ou=People,dc=example,dc=org 24 | objectClass: person 25 | objectClass: inetOrgPerson 26 | sn: saturn 27 | cn: saturn 28 | mail: saturn@example.com 29 | userpassword: saturn_pass 30 | 31 | dn: cn=venus,ou=People,dc=example,dc=org 32 | objectClass: person 33 | objectClass: inetOrgPerson 34 | sn: venus 35 | cn: venus 36 | mail: venus@example.com 37 | userpassword: venus_pass 38 | 39 | dn: cn=mercury,ou=People,dc=example,dc=org 40 | objectClass: person 41 | objectClass: inetOrgPerson 42 | sn: mercury 43 | cn: mercury 44 | mail: mercury@example.com 45 | userpassword: mercury_pass 46 | 47 | dn: cn=user,ou=People,dc=example,dc=org 48 | objectClass: person 49 | objectClass: inetOrgPerson 50 | sn: user 51 | cn: user 52 | mail: user@example.com 53 | userpassword: *password* 54 | 55 | # Group definitions. 56 | 57 | dn: ou=Groups,dc=example,dc=org 58 | objectClass: organizationalUnit 59 | ou: Groups 60 | 61 | dn: cn=admin,ou=Groups,dc=example,dc=org 62 | objectClass: groupOfNames 63 | cn: admin 64 | member: cn=sun,ou=People,dc=example,dc=org 65 | 66 | dn: cn=test,ou=Groups,dc=example,dc=org 67 | objectClass: groupOfNames 68 | cn: test 69 | member: cn=venus,ou=People,dc=example,dc=org 70 | 71 | dn: cn=apus,ou=Groups,dc=example,dc=org 72 | objectClass: groupOfNames 73 | cn: apus 74 | member: cn=mars,ou=People,dc=example,dc=org 75 | 76 | dn: cn=cetus,ou=Groups,dc=example,dc=org 77 | objectClass: groupOfNames 78 | cn: cetus 79 | member: cn=saturn,ou=People,dc=example,dc=org 80 | -------------------------------------------------------------------------------- /installer/configs/test_dex_config.yaml: -------------------------------------------------------------------------------- 1 | config: 2 | issuer: toreplacedbyissuer 3 | storage: 4 | type: kubernetes 5 | config: 6 | inCluster: true 7 | logger: 8 | level: debug 9 | expiry: 10 | signingKeys: "6h" 11 | idTokens: "1h" 12 | web: 13 | https: "0.0.0.0:443" 14 | tlsCert: /etc/dex/tls/https/server/tls.crt 15 | tlsKey: /etc/dex/tls/https/server/tls.key 16 | connectors: 17 | - type: ldap 18 | name: OpenLDAP 19 | id: ldap 20 | config: 21 | issuer: toreplacedbyissuer 22 | # No TLS for this setup. 23 | insecureNoSSL: false 24 | rootCA: /etc/dex/ca/ldap.ca 25 | # This would normally be a read-only user. 26 | bindDN: "cn=readonly,dc=example,dc=org" 27 | bindPW: readonly 28 | groupSearch: 29 | baseDN: "ou=Groups,dc=example,dc=org" 30 | filter: (objectClass=groupOfNames) 31 | groupAttr: member 32 | nameAttr: cn 33 | userAttr: DN 34 | host: "toreplacebyldapaddress" 35 | userSearch: 36 | baseDN: "ou=People,dc=example,dc=org" 37 | emailAttr: mail 38 | filter: (objectClass=person) 39 | idAttr: DN 40 | nameAttr: cn 41 | username: mail 42 | usernamePrompt: "Email Address" 43 | oauth2: 44 | skipApprovalScreen: true 45 | staticClients: 46 | - id: example-app 47 | redirectURIs: 48 | - 'http://127.0.0.1:5555/callback' 49 | - 'urn:ietf:wg:oauth:2.0:oob' 50 | name: 'Example App' 51 | secret: ZXhhbXBsZS1hcHAtc2VjcmV0 52 | rootCAsecret: root-ca 53 | rootCAfile: certs/ldap.ca 54 | -------------------------------------------------------------------------------- /installer/crd/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | . ../utils/fill_template.sh 19 | . ../utils/messages.sh 20 | 21 | header "Installation of CRD Controller" 22 | DOMAIN_NAME=$1 23 | USE_HTTPS=$2 24 | RELEASE_NAME="$IMM_RELEASE_PREFIX-crd" 25 | cd $HELM_TEMP_DIR/crd-subchart 26 | fill_template "" $CRD_IMAGE values.yaml 27 | fill_template "" $CRD_TAG values.yaml 28 | fill_template "" $DOMAIN_NAME values.yaml 29 | fill_template "" $USE_HTTPS values.yaml 30 | helm install --name $RELEASE_NAME . 31 | show_result $? "CRD installation completed" "Failed to install CRD" 32 | cd - 33 | -------------------------------------------------------------------------------- /installer/default_tenant.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | DOMAIN_NAME=$1 19 | PROXY=$2 20 | DEFAULT_TENANT_NAME=$DEFAULT_TENANT_NAME 21 | 22 | . ./utils/messages.sh 23 | 24 | . ../.venv/bin/activate 25 | 26 | SCOPE='admin' 27 | export USER_SCOPE=$SCOPE 28 | export ADMIN_SCOPE=$SCOPE 29 | export TENANT_RESOURCES={} 30 | 31 | cd ../scripts 32 | . ./imm_utils.sh 33 | 34 | EXPECTED='{"status": "OK", "data": {"tenants": []}}' 35 | 36 | while [[ "$TENANTS" != $EXPECTED ]]; do 37 | echo $TENANTS 38 | get_token admin 39 | TENANTS=`./imm ls t`; 40 | if [[ "$TENANTS" != $EXPECTED ]]; then 41 | echo "IMM not ready"; 42 | sleep 5; 43 | fi 44 | done 45 | 46 | response=`yes | ./imm create t $DEFAULT_TENANT_NAME $SCOPE` 47 | echo $response 48 | [[ $response =~ '{"status": "CREATED", "data": {"name": "'""$DEFAULT_TENANT_NAME'"}}' ]] && success "Successfully created default tenant $DEFAULT_TENANT_NAME" || failure "Failed to create default tenant $DEFAULT_TENANT_NAME" 49 | cd - 50 | -------------------------------------------------------------------------------- /installer/dex/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | ## 17 | . ../utils/fill_template.sh 18 | . ../utils/messages.sh 19 | 20 | export ISSUER=$1 21 | export DEX_NAMESPACE=$2 22 | export DEX_DOMAIN_NAME=$3 23 | RELEASE_NAME="$IMM_RELEASE_PREFIX-dex" 24 | header "Generating certificates for DEX" 25 | cp ../certs/dex-ing-ca.yaml $HELM_TEMP_DIR/dex-subchart/templates/ 26 | cd $HELM_TEMP_DIR/dex-subchart/certs 27 | ./generate-ing-ca.sh 28 | ./generate-dex-certs.sh 29 | ./generate-ing-dex-certs.sh 30 | cp ../../ldap-subchart/certs/ca.crt ./ldap.ca 31 | cd - 32 | 33 | header "Installing DEX" 34 | cp ../configs/test_dex_config.yaml dex_config.yaml 35 | export OPENLDAP_SVC=`kubectl get svc|grep "openldap "| awk '{ print $1 }'` 36 | export OPENLDAP_SVC_ADDRESS="$OPENLDAP_SVC.default:636" 37 | fill_template toreplacedbyissuer $ISSUER dex_config.yaml 38 | fill_template toreplacedbyhost $OPENLDAP_SVC_ADDRESS dex_config.yaml 39 | fill_template toreplacebyldapaddress $OPENLDAP_SVC_ADDRESS dex_config.yaml 40 | fill_template toreplacedbyissuer $ISSUER $HELM_TEMP_DIR/dex-subchart/values.yaml 41 | fill_template toreplacedbyingresshosts $DEX_DOMAIN_NAME $HELM_TEMP_DIR/dex-subchart/values.yaml 42 | fill_template toreplacedbyingresstlshosts $DEX_DOMAIN_NAME $HELM_TEMP_DIR/dex-subchart/values.yaml 43 | helm install --name $RELEASE_NAME -f dex_config.yaml $HELM_TEMP_DIR/dex-subchart/ 44 | show_result $? "DEX installation succesful" "Failed to install DEX" 45 | -------------------------------------------------------------------------------- /installer/dns/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | . ../utils/messages.sh 19 | 20 | DOMAIN_NAME=$1 21 | EXTERNAL_IP="" 22 | header "Waiting for external ip address" 23 | while [ ! -z "x" ] 24 | do 25 | if [[ "$EXTERNAL_IP" != "" ]] 26 | then 27 | break 28 | fi 29 | 30 | EXTERNAL_IP=`kubectl get services -n ingress-nginx|grep ingress-nginx|awk '{ print $(NF-2) }'` 31 | sleep 5 32 | done 33 | 34 | success "External ip found: $EXTERNAL_IP" 35 | result=`curl https://foo.$DOMAIN_NAME:443 -k -v -c 1 2>&1|grep $EXTERNAL_IP` 36 | 37 | if [ -z "$result" ]; then 38 | 39 | if [ -f "../hooks/dns_entry_hook.sh" ]; then 40 | header "Found hook script for DNS entry, setting $DOMAIN_NAME to $EXTERNAL_IP" 41 | ../hooks/dns_entry_hook.sh $EXTERNAL_IP $DOMAIN_NAME 42 | else 43 | action_required "Please update DNS records for domain $DOMAIN_NAME to point $EXTERNAL_IP" 44 | fi 45 | 46 | 47 | header "Waiting in the loop for updated dns records" 48 | result="" 49 | wait_time=0 50 | while [ -z "$result" ] 51 | do 52 | result=`curl https://foo.$DOMAIN_NAME:443 -k -v -c 1 2>&1|grep $EXTERNAL_IP` 53 | if [ -z "$result" ]; then 54 | # try with ping 55 | result=`ping foo.$DOMAIN_NAME -c 1 2>&1|grep $EXTERNAL_IP` 56 | fi 57 | echo "dns check result: $result" 58 | sleep 20 59 | wait_time=$(($wait_time + 20)) 60 | print_ne "\r\r\r\r\r\r\r\r\r\r\r\r elapsed time: $wait_time s" 61 | done 62 | success "DNS records update confirmed" 63 | 64 | 65 | else 66 | success "DNS entry already present" 67 | fi 68 | -------------------------------------------------------------------------------- /installer/hooks/example_dns_entry_hook.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | IP_ADDRESS=$1 19 | DOMAIN_NAME=$2 20 | cd ../utils/route53 21 | ./apply.sh CREATE $IP_ADDRESS $DOMAIN_NAME 22 | cd - 23 | -------------------------------------------------------------------------------- /installer/ingress/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | . ../utils/messages.sh 19 | . ../utils/wait_for_pod.sh 20 | RELEASE_NAME="$IMM_RELEASE_PREFIX-ingress" 21 | header "Installing ingress controller" 22 | cd $HELM_TEMP_DIR/ing-subchart 23 | helm install --name $RELEASE_NAME . 24 | header "Waiting for ingress controller pod" 25 | wait_for_pod 60 nginx-ingress-controller ingress-nginx 26 | cd - 27 | -------------------------------------------------------------------------------- /installer/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | . utils/show_help.sh 19 | 20 | export B64DECODE="base64 --decode" 21 | export B64ENCODE="base64 -w0" 22 | export SED_CMD="sed" 23 | if [[ "$OSTYPE" == "darwin"* ]]; then 24 | export SED_CMD="gsed" 25 | export B64ENCODE="base64" 26 | fi 27 | 28 | . utils/check_required_tools.sh 29 | 30 | OPTIND=1 31 | kops_env="" 32 | domain="" 33 | gce_zone="us-west1" 34 | quiet="no" 35 | 36 | while getopts "h?qsvtk:d:z:g:p:f:A:S:U:V:R:" opt; do 37 | case "$opt" in 38 | h|\?) 39 | show_help 40 | exit 0 41 | ;; 42 | q) quiet="yes" 43 | ;; 44 | k) kops_env=$OPTARG 45 | ;; 46 | d) domain=$OPTARG 47 | ;; 48 | z) gce_zone=$OPTARG 49 | ;; 50 | s) export SKIP_K8S_INSTALLATION="true" 51 | ;; 52 | g) export GCE_USER=$OPTARG 53 | ;; 54 | p) export PROXY=$OPTARG 55 | ;; 56 | f) IMM_RELEASE_PREFIX=$OPTARG 57 | ;; 58 | A) export MINIO_ACCESS_KEY=$OPTARG 59 | ;; 60 | S) export MINIO_SECRET_KEY=$OPTARG 61 | ;; 62 | U) export MINIO_URL=$OPTARG 63 | ;; 64 | V) export MINIO_SIGNATURE=$OPTARG 65 | ;; 66 | R) export MINIO_REGION=$OPTARG 67 | ;; 68 | t) export MGT_API_AUTHORIZATION="true" 69 | export DEFAULT_TENANT_NAME="default-tenant" 70 | ;; 71 | v) export SKIP_VALIDATION="true" 72 | ;; 73 | esac 74 | done 75 | 76 | 77 | shift $((OPTIND-1)) 78 | 79 | 80 | FILTER_CMD="cat" 81 | if [[ "$quiet" == "yes" ]]; then 82 | echo "Enabling quiet mode" 83 | FILTER_CMD="grep --color=none '[[:cntrl:]]'" 84 | fi 85 | 86 | export IMM_RELEASE_PREFIX="${IMM_RELEASE_PREFIX:=imm}" 87 | unbuffer ./main.sh "$kops_env" "$domain" "$gce_zone" 2>&1 | tee install.log | ${FILTER_CMD} 88 | -------------------------------------------------------------------------------- /installer/k8s/create_kops_cluster_gke.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | . ../utils/progress_bar.sh 19 | . ../utils/fill_template.sh 20 | . ../utils/messages.sh 21 | ``` 22 | #### Create cluster 23 | ``` 24 | 25 | header "Installing kubernetes cluster" 26 | 27 | CLUSTER_NAME=$1 28 | GCE_REGION=$2 29 | cp ../kops/desiredcni.yaml ./cluster.yaml 30 | fill_template toreplacebyclustername $CLUSTER_NAME cluster.yaml 31 | fill_template us-west1 ${GCE_REGION} cluster.yaml 32 | kops create -f cluster.yaml 33 | kops update cluster $CLUSTER_NAME.k8s.local --yes 34 | show_result $? "Kubernetes cluster created" "Failed to create cluster" 35 | echo "Waiting 300 seconds for cluster to be ready" 36 | progress_bar 300 37 | header "Installing weave" 38 | kubectl create -f https://git.io/weave-kube-1.6 39 | show_result $? "Weave installed" "Failed to install weave" 40 | -------------------------------------------------------------------------------- /installer/k8s/get_ing_ca_crt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | kubectl get secret ca-ing -n dex -o yaml|grep ca.crt|awk '{ print $2 }'| $B64DECODE 19 | -------------------------------------------------------------------------------- /installer/k8s/install_tiller.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | . ../utils/wait_for_pod.sh 19 | . ../utils/progress_bar.sh 20 | . ../utils/messages.sh 21 | 22 | header "Installing tiller on k8s" 23 | 24 | kubectl -n kube-system create serviceaccount tiller 25 | 26 | kubectl create clusterrolebinding tiller \ 27 | --clusterrole cluster-admin \ 28 | --serviceaccount=kube-system:tiller 29 | 30 | helm init --service-account tiller 31 | show_result $? "Tiller installed" "Failed to install tiller" 32 | echo "Waiting for tiller pod to be ready" 33 | wait_for_pod 300 tiller-deploy kube-system 34 | # extra wait because presence of tiller is not enough 35 | echo "Extra wait for 30s" 36 | progress_bar 30 37 | 38 | 39 | -------------------------------------------------------------------------------- /installer/k8s/restart_k8sapi.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | . ../utils/fill_template.sh 19 | . ../utils/messages.sh 20 | ``` 21 | 22 | #### Update cluster 23 | 24 | ``` 25 | CLUSTER_NAME=$1 26 | ISSUER=$2 27 | DEX_NAMESPACE=$3 28 | 29 | header "Restarting k8s api with params: cluster name: $CLUSTER_NAME issuer: $ISSUER dex namespace: $DEX_NAMESPACE" 30 | 31 | cp ../kops/oidc_tmpl.yaml oidc.yaml 32 | 33 | fill_template toreplacebyissuer $ISSUER oidc.yaml 34 | 35 | DEX_ING_CA=`./get_ing_ca_crt.sh` 36 | echo "Found certificate: $DEX_ING_CA" 37 | echo "$DEX_ING_CA" > ca-ing.crt 38 | ${SED_CMD} -i -e 's/^/ /' ca-ing.crt 39 | ${SED_CMD} -i -e '/replacebycertificate/{r ca-ing.crt' -e 'd}' oidc.yaml 40 | OIDC_CFG=`cat oidc.yaml` 41 | 42 | kops get cluster --name $CLUSTER_NAME.k8s.local --output json > config.yaml 43 | yq m config.yaml oidc.yaml > config_oidc.yaml 44 | cat config_oidc.yaml 45 | kops replace -f config_oidc.yaml 46 | header "Configuration updated, restarting cluster" 47 | kops update cluster --yes 48 | kops rolling-update cluster --yes 49 | show_result $? "Restart succeded" "Restart failed" 50 | 51 | -------------------------------------------------------------------------------- /installer/kops/README.md: -------------------------------------------------------------------------------- 1 | ## Kubernetes deployment using Kops 2 | 3 | #### Install Kops 4 | ``` 5 | wget -O kops https://github.com/kubernetes/kops/releases/download/$(curl -s https://api.github.com/repos/kubernetes/kops/releases/latest | grep tag_name | cut -d '"' -f 4)/kops-linux-amd64 6 | chmod +x ./kops 7 | sudo mv ./kops /usr/local/bin/ 8 | ``` 9 | 10 | #### Create bucket to store k8s cluster configuration 11 | ``` 12 | gsutil mb gs://kubernetes-clusters-imm/ 13 | ``` 14 | 15 | #### Create all required environment variables 16 | ``` 17 | export PROJECT=`gcloud config get-value project` 18 | export KOPS_FEATURE_FLAGS=AlphaAllowGCE 19 | export GOOGLE_APPLICATION_CREDENTIALS="/home//.config/gcloud/legacy_credentials/@email.com/adc.json" 20 | ``` 21 | Replace bucket name if needed 22 | ``` 23 | export KOPS_STATE_STORE=gs://kubernetes-clusters-imm 24 | ``` 25 | 26 | #### Create cluster 27 | ``` 28 | kops create cluster .k8s.local --zones us-central1-a --state gs://kubernetes-clusters-imm --project=${PROJECT} 29 | kops update cluster .k8s.local --yes 30 | export NAME=.k8s.local 31 | kops export kubecfg ${NAME} 32 | ``` 33 | 34 | #### Validate deployment 35 | ``` 36 | kubectl get nodes --show-labels 37 | ``` 38 | 39 | #### Delete deployment 40 | ``` 41 | kops delete cluster --yes 42 | ``` 43 | -------------------------------------------------------------------------------- /installer/kops/SETUP.md: -------------------------------------------------------------------------------- 1 | 2 | ## CREATE CLUSTER MANUALLY 3 | ``` 4 | wget -O kops https://github.com/kubernetes/kops/releases/download/$(curl -s https://api.github.com/repos/kubernetes/kops/releases/latest | grep tag_name | cut -d '"' -f 4)/kops-linux-amd64 5 | 6 | chmod +x ./kops 7 | sudo mv ./kops /usr/local/bin/ 8 | export PROJECT=`gcloud config get-value project` 9 | export KOPS_FEATURE_FLAGS=AlphaAllowGCE 10 | export GOOGLE_APPLICATION_CREDENTIALS="/home/local/GER/username/.config/gcloud/legacy_credentials/user.name@intel.com/adc.json" 11 | 12 | export CLUSTER_NAME="" 13 | 14 | sed -i "s/toreplacebyclustername/${CLUSTER_NAME}/g" desired.yaml 15 | kops create -f desired.yaml 16 | export KOPS_STATE_STORE=gs://kubernetes-clusters-imm 17 | kops update cluster .k8s.local --yes 18 | export NAME=.k8s.local 19 | kops export kubecfg ${NAME} 20 | 21 | kubectl create sa tiller --namespace kube-system 22 | kubectl create clusterrolebinding tiller-cluster-rule --clusterrole=cluster-admin --serviceaccount=kube-system:tiller 23 | helm init --debug --upgrade --service-account tiller 24 | 25 | ``` 26 | ## ADD A RECORD IN AWS ROUTE 53 27 | 28 | ``` 29 | aws route53 change-resource-record-sets --hosted-zone-id Z11DOV0M5AJEBB --change-batch file://route_record.json 30 | ``` 31 | where route_record.json is a json file containing ingress ip (echo $ING_IP) and your domain name (example in /inferno-platform/installer/utils/route53 directory) 32 | 33 | 34 | -------------------------------------------------------------------------------- /installer/kops/desiredcni.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kops/v1alpha2 2 | kind: Cluster 3 | metadata: 4 | creationTimestamp: 2018-10-25T08:13:47Z 5 | name: toreplacebyclustername.k8s.local 6 | spec: 7 | api: 8 | loadBalancer: 9 | type: Public 10 | authorization: 11 | rbac: {} 12 | channel: stable 13 | cloudProvider: gce 14 | configBase: gs://kubernetes-clusters-imm/toreplacebyclustername.k8s.local 15 | etcdClusters: 16 | - etcdMembers: 17 | - instanceGroup: master-us-west1-a 18 | name: a 19 | name: main 20 | - etcdMembers: 21 | - instanceGroup: master-us-west1-a 22 | name: a 23 | name: events 24 | iam: 25 | allowContainerRegistry: true 26 | legacy: false 27 | kubernetesApiAccess: 28 | - 0.0.0.0/0 29 | kubernetesVersion: 1.10.6 30 | masterPublicName: api.toreplacebyclustername.k8s.local 31 | networking: 32 | cni: {} 33 | nonMasqueradeCIDR: 100.64.0.0/10 34 | project: constant-cubist-173123 35 | sshAccess: 36 | - 0.0.0.0/0 37 | subnets: 38 | - name: us-west1 39 | region: us-west1 40 | type: Public 41 | topology: 42 | dns: 43 | type: Public 44 | masters: public 45 | nodes: public 46 | 47 | --- 48 | 49 | apiVersion: kops/v1alpha2 50 | kind: InstanceGroup 51 | metadata: 52 | creationTimestamp: 2018-10-25T08:13:48Z 53 | labels: 54 | kops.k8s.io/cluster: toreplacebyclustername.k8s.local 55 | name: master-us-west1-a 56 | spec: 57 | image: cos-cloud/cos-stable-65-10323-99-0 58 | machineType: n1-standard-1 59 | maxSize: 1 60 | minSize: 1 61 | nodeLabels: 62 | kops.k8s.io/instancegroup: master-us-west1-a 63 | role: Master 64 | subnets: 65 | - us-west1 66 | zones: 67 | - us-west1-a 68 | 69 | --- 70 | 71 | apiVersion: kops/v1alpha2 72 | kind: InstanceGroup 73 | metadata: 74 | creationTimestamp: 2018-10-25T08:13:49Z 75 | labels: 76 | kops.k8s.io/cluster: toreplacebyclustername.k8s.local 77 | name: nodes 78 | spec: 79 | image: cos-cloud/cos-stable-65-10323-99-0 80 | machineType: n1-standard-2 81 | maxSize: 2 82 | minSize: 2 83 | nodeLabels: 84 | kops.k8s.io/instancegroup: nodes 85 | role: Node 86 | subnets: 87 | - us-west1 88 | zones: 89 | - us-west1-a 90 | 91 | -------------------------------------------------------------------------------- /installer/kops/oidc_tmpl.yaml: -------------------------------------------------------------------------------- 1 | spec: 2 | fileAssets: 3 | - content: | 4 | replacebycertificate 5 | name: paste-cert 6 | path: /etc/srv/kubernetes/ca.pem 7 | roles: 8 | - Master 9 | kubeAPIServer: 10 | oidcCAFile: /etc/srv/kubernetes/ca.pem 11 | oidcClientID: example-app 12 | oidcGroupsClaim: groups 13 | oidcIssuerURL: toreplacebyissuer 14 | oidcUsernameClaim: email 15 | -------------------------------------------------------------------------------- /installer/ldap/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | . ../utils/messages.sh 19 | . ../utils/wait_for_pod.sh 20 | RELEASE_NAME="$IMM_RELEASE_PREFIX-openldap" 21 | export LDAP_DOMAIN_NAME="$RELEASE_NAME.default" 22 | cd $HELM_TEMP_DIR/ldap-subchart/certs 23 | header "Installing LDAP" 24 | ./genereate_ldap_certs.sh 25 | cd - 26 | if [[ "$MGT_API_AUTHORIZATION" == "true" ]]; then 27 | helm install --name $RELEASE_NAME -f $HELM_TEMP_DIR/ldap-subchart/customLdifFiles.yaml $HELM_TEMP_DIR/ldap-subchart/ 28 | else 29 | # use test configuration 30 | helm install --name $RELEASE_NAME -f ../configs/test_LdifFiles.yaml $HELM_TEMP_DIR/ldap-subchart/ 31 | fi 32 | show_result $? "LDAP installation succeded" "Failed to install LDAP" 33 | header "Waiting for ldap to be ready" 34 | wait_for_pod 600 imm-openldap default 35 | -------------------------------------------------------------------------------- /installer/minio/install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | . ../utils/fill_template.sh 19 | . ../utils/messages.sh 20 | MINIO_ACCESS_KEY=$1 21 | MINIO_SECRET_KEY=$2 22 | MINIO_EXTERNAL_URI=`echo "$3" | awk -F/ '{print $3}'` 23 | RELEASE_NAME="$IMM_RELEASE_PREFIX-minio" 24 | 25 | header "Installing test minio storage" 26 | 27 | cd $HELM_TEMP_DIR/minio-subchart 28 | fill_template "" $MINIO_ACCESS_KEY values.yaml 29 | fill_template "" $MINIO_SECRET_KEY values.yaml 30 | helm dep up . 31 | helm install --name $RELEASE_NAME . 32 | FAILED=$? 33 | show_result "$FAILED" "Minio storage installed" "Failed to install Minio storage" 34 | cd - 35 | cp minio_ing_tmpl.yaml minio_ing.yaml 36 | fill_template "" $MINIO_EXTERNAL_URI minio_ing.yaml 37 | fill_template "" $RELEASE_NAME minio_ing.yaml 38 | kubectl create -f minio_ing.yaml 39 | FAILED=$? 40 | show_result "$FAILED" "Minio ingress created at $MINIO_EXTERNAL_URI" "Failed to install Minio ingress" 41 | 42 | -------------------------------------------------------------------------------- /installer/minio/minio_ing_tmpl.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Ingress 3 | metadata: 4 | name: minio-ingress 5 | annotations: 6 | kubernetes.io/ingress.class: nginx 7 | nginx.ingress.kubernetes.io/proxy-body-size: 32m 8 | spec: 9 | rules: 10 | - host: 11 | http: 12 | paths: 13 | - path: / 14 | backend: 15 | serviceName: 16 | servicePort: 9000 17 | -------------------------------------------------------------------------------- /installer/prerequisites_ubuntu.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | sudo apt-get install -y iputils-ping expect expect-dev software-properties-common libcap2-bin 19 | 20 | KOPS=`command -v kops` 21 | if [ -z "$KOPS" ]; then 22 | curl -LO https://github.com/kubernetes/kops/releases/download/$(curl -s https://api.github.com/repos/kubernetes/kops/releases/latest | grep tag_name | cut -d '"' -f 4)/kops-linux-amd64 23 | chmod +x kops-linux-amd64 24 | sudo mv kops-linux-amd64 /usr/local/bin/kops 25 | fi 26 | 27 | HELM=`command -v helm` 28 | if [ -z "$HELM" ]; then 29 | curl https://raw.githubusercontent.com/helm/helm/master/scripts/get > get_helm.sh 30 | chmod 700 get_helm.sh 31 | ./get_helm.sh 32 | helm init 33 | fi 34 | 35 | KUBECTL=`command -v kubectl` 36 | if [ -z "$KUBECTL" ]; then 37 | sudo apt-get update && sudo apt-get install -y apt-transport-https 38 | curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add - 39 | echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list 40 | sudo apt-get update && sudo apt-get install -y kubectl 41 | fi 42 | 43 | sudo apt-get install jq -y 44 | YQ=`command -v yq` 45 | if [ -z "$YQ" ]; then 46 | wget https://github.com/mikefarah/yq/releases/download/2.2.1/yq_linux_amd64 47 | chmod a+x yq_linux_amd64 48 | sudo mv yq_linux_amd64 /usr/local/bin/yq 49 | fi 50 | sudo add-apt-repository ppa:deadsnakes/ppa -y && sudo apt-get update && sudo apt-get install -y python3.6 proxytunnel python-pip python3-pip 51 | sudo pip3 install --upgrade virtualenv && sudo pip3 install --upgrade pip 52 | 53 | git clone https://github.com/bats-core/bats-core.git && cd bats-core && sudo ./install.sh /usr/local 54 | -------------------------------------------------------------------------------- /installer/utils/check_required_tools.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | 19 | # import from the same directory 20 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 21 | . $DIR/messages.sh 22 | 23 | tools=("ping" "unbuffer" "kops" "kubectl" "helm" "jq" "yq" "virtualenv" "python3.6" "$SED_CMD" "bats") 24 | 25 | missing="" 26 | for cmd in "${tools[@]}" 27 | do 28 | result=`command -v $cmd` 29 | if [ -z "$result" ] 30 | then 31 | missing="$missing $cmd " 32 | fi 33 | done 34 | 35 | if [ ! -z "$missing" ] 36 | then 37 | failure "Please install tools: [$missing]" 38 | exit 1 39 | fi 40 | 41 | -------------------------------------------------------------------------------- /installer/utils/fill_template.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | function fill_template() { 19 | PATTERN=$1 20 | REPLACEMENT=$2 21 | FILE=$3 22 | CMD="${SED_CMD} -i s@$PATTERN@$REPLACEMENT@g $FILE" && echo "$CMD" && `$CMD` 23 | } 24 | -------------------------------------------------------------------------------- /installer/utils/messages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | function header() { 19 | TEXT="$1" 20 | YELLOW='\033[1;33m' 21 | NC='\033[0m' # No Color 22 | printf "\n${YELLOW}$TEXT${NC}\n" 23 | } 24 | 25 | function action_required() { 26 | TEXT="$1" 27 | BOLD_YELLOW='\033[1;31m' 28 | NC='\033[0m' # No Color 29 | printf "${BOLD_YELLOW}ACTION_REQUIRED: $TEXT${NC}\n" 30 | } 31 | 32 | 33 | function success() { 34 | TEXT="$1" 35 | GREEN='\033[0;32m' 36 | NC='\033[0m' # No Color 37 | printf "${GREEN}$TEXT${NC}\n" 38 | } 39 | 40 | 41 | function print_ne() { 42 | TEXT="$1" 43 | CYAN='\033[0;36m' 44 | NC='\033[0m' # No Color 45 | echo -ne "${CYAN}$TEXT${NC}" 46 | } 47 | 48 | function failure() { 49 | TEXT="$1" 50 | RED='\033[0;31m' 51 | NC='\033[0m' # No Color 52 | printf "${RED}$TEXT${NC}\n" 53 | exit 1 54 | } 55 | 56 | function show_result() { 57 | RESULT="$1" 58 | SUCCESS_MSG="$2" 59 | FAIL_MSG="$3" 60 | if [ "$RESULT" -eq 0 ]; then 61 | success "$SUCCESS_MSG" 62 | else 63 | failure "$FAIL_MSG" 64 | exit 1 65 | fi 66 | } 67 | 68 | 69 | -------------------------------------------------------------------------------- /installer/utils/progress_bar.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | # import from the same directory 19 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 20 | . $DIR/messages.sh 21 | function progress_bar() { 22 | seconds=$1 23 | for (( i = $seconds; $i > 0; i=$i -1)); do 24 | sleep 1 25 | print_ne "\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r $i seconds left" 26 | done 27 | } 28 | 29 | 30 | -------------------------------------------------------------------------------- /installer/utils/route53/apply.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | OP=$1 # CREATE, UPSERT, DELETE 19 | IP_ADDR=$2 20 | DOMAIN=$3 21 | SED_CMD=sed 22 | if [ "$(uname)" == "Darwin" ]; then 23 | SED_CMD=gsed 24 | fi 25 | 26 | cp route_record_tmpl.json route_record.json 27 | $SED_CMD -i "s//$OP/g" route_record.json 28 | $SED_CMD -i "s//$IP_ADDR/g" route_record.json 29 | $SED_CMD -i "s//$DOMAIN/g" route_record.json 30 | echo "Created Route53 config:" 31 | cat route_record.json 32 | aws route53 change-resource-record-sets --hosted-zone-id Z11DOV0M5AJEBB --change-batch file://./route_record.json 33 | -------------------------------------------------------------------------------- /installer/utils/route53/route_record_tmpl.json: -------------------------------------------------------------------------------- 1 | { 2 | "Comment": "CREATE/DELETE/UPSERT a record ", 3 | "Changes": [{ 4 | "Action": "", 5 | "ResourceRecordSet": { 6 | "Name": "*." , 7 | "Type": "A", 8 | "TTL": 300, 9 | "ResourceRecords": [{ "Value": ""}] 10 | }}] 11 | } 12 | -------------------------------------------------------------------------------- /installer/utils/show_help.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | show_help() { 19 | cat << EOF 20 | Usage: 21 | ${0##*/} [-h?qskdz] 22 | Required optons: 23 | -k - cluster name 24 | -d - domain name 25 | Additional options 26 | -z - GCE cluster zone (if using kops and GCE) 27 | -q - silent mode (shows only important logs) 28 | -s - skip cluster creation via kops 29 | -p - set proxy (address:port) 30 | -t - single tenant mode 31 | -A - set minio access key 32 | -S - set minio secret key 33 | -U - set URL to minio (if this parameter is set, minio chart will not be deploy) 34 | -V - set signature version for minio (default: s3v4) 35 | -R - set region for minio (default: us-east-1) 36 | -h/? - show help 37 | Usage examples 38 | ${0##*/} -k -d 39 | ${0##*/} -k -d -z 40 | ${0##*/} -k -d -s -q 41 | ${0##*/} -k -d -s -q -p myproxy.com:911 -A minio_access_key -S minio_secret_key 42 | ${0##*/} -k -d -s -q -A minio_access_key -S minio_secret_key -U url_to_minio -R us-west-2 43 | EOF 44 | } 45 | -------------------------------------------------------------------------------- /installer/utils/validate_envs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | # import from the same directory 19 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 20 | . $DIR/messages.sh 21 | 22 | params=("DNS_DOMAIN_NAME") 23 | 24 | empty="" 25 | for var in "${params[@]}" 26 | do 27 | if [ -z "${!var}" ] 28 | then 29 | empty="$empty $var " 30 | fi 31 | done 32 | 33 | if [ ! -z "$empty" ] 34 | then 35 | failure "Variables $empty must be set before starting installation" 36 | exit 1 37 | fi 38 | 39 | -------------------------------------------------------------------------------- /installer/utils/wait_for_kubectl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | 19 | # import from the same directory 20 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 21 | . $DIR/messages.sh 22 | 23 | function wait_for_kubectl() { 24 | seconds=$1 25 | steps=$(($seconds/5)) 26 | for (( i = $steps; $i > 0; i=$i -1)); do 27 | ready=`kubectl get pods -n not_existing_namespace --request-timeout=5s 2>&1|grep "No resources"` 28 | if [ ! -z "$ready" ] 29 | then 30 | echo "Kubectl command available" 31 | return 32 | fi 33 | sleep 1 34 | echo -ne "\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r $i seconds left" 35 | done 36 | failure "Could not get working kubectl during time: $seconds s, aborting " 37 | exit 1 38 | } 39 | 40 | -------------------------------------------------------------------------------- /installer/utils/wait_for_pod.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" 19 | . $DIR/messages.sh 20 | 21 | function wait_for_pod() { 22 | seconds=$1 23 | pod_prefix=$2 24 | namespace=$3 25 | for (( i = $seconds; $i > 0; i=$i -1)); do 26 | ready=`kubectl get pods -n $namespace|grep $pod_prefix|grep "Running"|grep -v "0/"` 27 | if [ ! -z "$ready" ] 28 | then 29 | return 30 | fi 31 | sleep 1 32 | print_ne "\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r\r $i seconds left" 33 | done 34 | failure "Could not found pod with prefix: $pod_prefix, aborting" 35 | exit 1 36 | } 37 | 38 | -------------------------------------------------------------------------------- /installer/validate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | . ./utils/messages.sh 19 | 20 | cd ../scripts 21 | header "Running tests" 22 | bats imm_tests.bats 23 | RESULT=$? 24 | echo "Smoke tests exit code: $RESULT" 25 | cd - 26 | if [ $RESULT -eq 0 ]; then 27 | echo "IMM installation succeeded!!!" 28 | if [ ! -z $IMM_USER_CREDENTIALS ]; then 29 | echo "IMM login credentials: $IMM_USER_CREDENTIALS" 30 | fi 31 | else 32 | echo "IMM validation failed, please check logs" 33 | fi 34 | exit $RESULT 35 | -------------------------------------------------------------------------------- /management/.dockerignore: -------------------------------------------------------------------------------- 1 | /test/ 2 | /Makefile 3 | /run.sh 4 | /gcloud-push.sh 5 | /Dockerfile 6 | -------------------------------------------------------------------------------- /management/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM clearlinux:latest 2 | 3 | RUN swupd bundle-add python3-basic 4 | RUN rm -fr /run/lock/clrtrust.lock 5 | RUN clrtrust generate 6 | 7 | ENV WORKERS=4 8 | 9 | COPY . /management 10 | WORKDIR /management 11 | 12 | RUN pip --no-cache-dir install . 13 | 14 | ENV REQUESTS_CA_BUNDLE=/var/cache/ca-certs/compat/ca-roots.pem 15 | 16 | RUN useradd management-api-runner 17 | 18 | EXPOSE 9443 19 | ENTRYPOINT ./install_CA.sh && su management-api-runner -c "gunicorn --certfile=/certs/tls.crt --keyfile=/certs/tls.key -w $WORKERS -k gevent --bind 0.0.0.0:9443 management_api.runner:app" - 20 | -------------------------------------------------------------------------------- /management/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | IMAGE ?= management-api 18 | TAG ?= latest 19 | 20 | MANAGEMENT_HOSTNAME := "0.0.0.0" 21 | MANAGEMENT_PORT := 5000 22 | 23 | MINIO_ENDPOINT ?= 'http://127.0.0.1:9000' 24 | 25 | .PHONY: install docker_build docker_run docker_tag docker_push style circleci 26 | 27 | install: 28 | pip install -r requirements.txt 29 | pip install -e . 30 | 31 | docker_build: 32 | docker build --build-arg HTTP_PROXY=$(HTTP_PROXY) --build-arg HTTPS_PROXY=$(HTTPS_PROXY) -f Dockerfile -t $(IMAGE):$(TAG) . 33 | 34 | docker_run: 35 | docker run -d -e HOSTNAME=$(MANAGEMENT_HOSTNAME) -e PORT=$(MANAGEMENT_PORT) -p $(MANAGEMENT_PORT):$(MANAGEMENT_PORT) \ 36 | -e MINIO_ENDPOINT_ADDR=$(MINIO_ENDPOINT) -e MINIO_SECRET_ACCESS_KEY=$(MINIO_SECRET_ACCESS_KEY) -e MINIO_ACCESS_KEY_ID=$(MINIO_ACCESS_KEY_ID) \ 37 | \$(TAG) /management/run.sh 38 | 39 | docker_tag: 40 | docker tag $(IMAGE):$(TAG) gcr.io/constant-cubist-173123/$(IMAGE):$(TAG) 41 | 42 | docker_push: 43 | gcloud docker -- push gcr.io/constant-cubist-173123/$(IMAGE):$(TAG) 44 | 45 | style: 46 | flake8 --max-line-length 100 management_api/ test/ 47 | 48 | circleci: docker_build docker_tag docker_push 49 | 50 | -------------------------------------------------------------------------------- /management/gcloud-push.sh: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | export TAG=$(shell hashdeep -r -b . | md5sum | tr -d '-' | tr -d ' ') 18 | make circleci 19 | -------------------------------------------------------------------------------- /management/install_CA.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Copyright (c) 2018 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | dir="/custom_CA" 19 | 20 | for file in $(ls "$dir") 21 | do 22 | clrtrust add "$dir/$file" 23 | done 24 | -------------------------------------------------------------------------------- /management/management_api/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/management/management_api/__init__.py -------------------------------------------------------------------------------- /management/management_api/authenticate/__init__.py: -------------------------------------------------------------------------------- 1 | from .authenticate import Authenticate, Token, AuthMiddleware # noqa 2 | -------------------------------------------------------------------------------- /management/management_api/endpoints/__init__.py: -------------------------------------------------------------------------------- 1 | from .endpoints import Endpoints, EndpointScale, Endpoint # noqa 2 | -------------------------------------------------------------------------------- /management/management_api/main.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | from gevent import pywsgi 18 | 19 | import falcon 20 | 21 | 22 | from management_api.config import HOSTNAME, PORT 23 | from management_api.utils.routes import register_routes 24 | from management_api.utils.logger import get_logger 25 | from management_api.utils.errors_handling import add_error_handlers 26 | from management_api.authenticate import AuthMiddleware 27 | 28 | logger = get_logger(__name__) 29 | 30 | 31 | def create_app(): 32 | app = falcon.API(middleware=[AuthMiddleware()]) 33 | add_error_handlers(app) 34 | register_routes(app) 35 | return app 36 | 37 | 38 | def main(): 39 | pywsgi.WSGIServer((HOSTNAME, PORT), 40 | create_app()).serve_forever() 41 | 42 | 43 | if __name__ == '__main__': 44 | main() 45 | -------------------------------------------------------------------------------- /management/management_api/models/__init__.py: -------------------------------------------------------------------------------- 1 | from .models import Models # noqa 2 | -------------------------------------------------------------------------------- /management/management_api/models/models.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | import falcon 18 | from falcon.media.validators import jsonschema 19 | import json 20 | 21 | from management_api.models.model_utils import list_models, delete_model 22 | from management_api.schemas.models import model_delete_schema 23 | 24 | 25 | class Models(object): 26 | def on_get(self, req, resp, tenant_name): 27 | namespace = tenant_name 28 | response = list_models(namespace, req.params['Authorization']) 29 | resp.status = falcon.HTTP_OK 30 | resp.body = json.dumps({'status': 'OK', 'data': {'models': response}}) 31 | 32 | @jsonschema.validate(model_delete_schema) 33 | def on_delete(self, req, resp, tenant_name): 34 | """Handles DELETE requests""" 35 | namespace = tenant_name 36 | body = req.media 37 | response = delete_model(body, namespace, req.params['Authorization']) 38 | resp.status = falcon.HTTP_OK 39 | resp.body = json.dumps({'status': 'DELETED', 'data': {'model_path': response}}) 40 | -------------------------------------------------------------------------------- /management/management_api/runner.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | from .main import create_app 18 | 19 | app = create_app() 20 | -------------------------------------------------------------------------------- /management/management_api/schemas/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/management/management_api/schemas/__init__.py -------------------------------------------------------------------------------- /management/management_api/schemas/authenticate.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | from management_api.schemas.elements.verifications import auth_code, refresh_token 18 | 19 | 20 | authenticate_token_schema = { 21 | "type": "object", 22 | "title": "Authenticate token endpoint", 23 | "oneOf": [{ 24 | "required": [ 25 | "code" 26 | ] 27 | }, 28 | { 29 | "required": [ 30 | "refresh_token" 31 | ] 32 | }], 33 | "properties": { 34 | "code": auth_code, 35 | "refresh_token": refresh_token 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /management/management_api/schemas/elements/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/management/management_api/schemas/elements/__init__.py -------------------------------------------------------------------------------- /management/management_api/schemas/elements/models.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | VERSION_POLICY_REGEX = "^\s*{\s*(specific\s*{\s*(versions:\s*\d+\s+)*versions:\s*\d+\s*}|all\s*{\s*}|latest\s*{\s*})\s*}\s*$" # noqa 18 | 19 | model_name = { 20 | "type": "string", 21 | "title": "Model name", 22 | "minLength": 3 23 | } 24 | 25 | model_version = { 26 | "type": "integer", 27 | "title": "Model version", 28 | "minimum": 1 29 | } 30 | 31 | model_version_policy = { 32 | "type": "string", 33 | "title": "Model version policy", 34 | "pattern": VERSION_POLICY_REGEX, 35 | } 36 | 37 | file_name = { 38 | "type": "string", 39 | "title": "Model file name" 40 | } 41 | 42 | upload_id = { 43 | "type": "string", 44 | "title": "Upload ID to identify whose part is being uploaded" 45 | } 46 | 47 | parts = { 48 | "type": "array", 49 | "title": "Parts of uploads" 50 | } 51 | 52 | dir = { 53 | "type": "string", 54 | "title": "Directory to create", 55 | } 56 | -------------------------------------------------------------------------------- /management/management_api/schemas/elements/names.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | NAME_REGEX = "^[a-z0-9]([-a-z0-9]*[a-z0-9])?$" 18 | 19 | tenant_name = { 20 | "type": "string", 21 | "title": "Tenant name", 22 | "pattern": NAME_REGEX, 23 | "minLength": 3, 24 | "maxLength": 63 25 | } 26 | 27 | endpoint_name = { 28 | "type": "string", 29 | "title": "Endpoint name", 30 | "pattern": NAME_REGEX, 31 | "minLength": 3 32 | } 33 | 34 | scope_name = { 35 | "type": "string", 36 | "title": "Keystone scope name" 37 | } 38 | 39 | subject_name = { 40 | "type": "string", 41 | "title": "Subject name", 42 | "pattern": "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$" # noqa 43 | } 44 | 45 | template_name = { 46 | "type": "string", 47 | "title": "Template name", 48 | "minLength": 3, 49 | } 50 | -------------------------------------------------------------------------------- /management/management_api/schemas/elements/resources.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | from copy import deepcopy 18 | 19 | 20 | RESOURCE_REGEX = "^([+]?[0-9.]+)([eEinumkKMGTP]*[+]?[0-9]*)$" 21 | 22 | resources_dict = { 23 | "type": "string", 24 | "optional": True, 25 | "pattern": RESOURCE_REGEX 26 | } 27 | 28 | resources = { 29 | "type": "object", 30 | "title": "Resource quota", 31 | "properties": { 32 | "requests.cpu": resources_dict, 33 | "limits.cpu": resources_dict, 34 | "requests.memory": resources_dict, 35 | "limits.memory": resources_dict 36 | } 37 | } 38 | 39 | max_endpoints = { 40 | "type": "integer", 41 | "optional": True, 42 | "title": "maxEndpoints", 43 | "minimum": 1 44 | } 45 | 46 | quota = deepcopy(resources) 47 | quota["properties"]["maxEndpoints"] = max_endpoints 48 | 49 | replicas = { 50 | "type": "integer", 51 | "optional": True, 52 | "title": "Replicas", 53 | "minimum": 0 54 | } 55 | -------------------------------------------------------------------------------- /management/management_api/schemas/elements/verifications.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | cert = { 18 | "type": "string", 19 | "title": "Certificate" 20 | } 21 | 22 | auth_code = { 23 | "type": "string", 24 | "title": "Authentication code" 25 | } 26 | 27 | refresh_token = { 28 | "type": "string", 29 | "title": "Refresh token" 30 | } 31 | -------------------------------------------------------------------------------- /management/management_api/schemas/endpoints.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018-2019 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | from management_api.schemas.elements.models import model_name, model_version_policy 18 | from management_api.schemas.elements.names import endpoint_name, subject_name, template_name 19 | from management_api.schemas.elements.resources import replicas, resources 20 | 21 | 22 | endpoint_post_schema = { 23 | "type": "object", 24 | "title": "Endpoint POST Schema", 25 | "required": [ 26 | "endpointName", 27 | "modelName", 28 | "subjectName", 29 | ], 30 | "properties": { 31 | "endpointName": endpoint_name, 32 | "modelName": model_name, 33 | "modelVersionPolicy": model_version_policy, 34 | "subjectName": subject_name, 35 | "replicas": replicas, 36 | "resources": resources, 37 | "servingName": template_name 38 | } 39 | } 40 | 41 | endpoint_delete_schema = { 42 | "type": "object", 43 | "title": "Endpoint DELETE Schema", 44 | "required": [ 45 | "endpointName" 46 | ], 47 | "properties": { 48 | "endpointName": endpoint_name 49 | } 50 | } 51 | 52 | resources['optional'] = True 53 | 54 | endpoint_update_schema = { 55 | "type": "object", 56 | "title": "Endpoint PATCH Schema for updating", 57 | "properties": { 58 | "modelName": model_name, 59 | "modelVersionPolicy": model_version_policy, 60 | "resources": resources, 61 | "subjectName": subject_name 62 | } 63 | } 64 | 65 | endpoint_scale_schema = { 66 | "type": "object", 67 | "title": "Endpoint PATCH Schema for scaling", 68 | "required": [ 69 | "replicas" 70 | ], 71 | "properties": { 72 | "replicas": replicas, 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /management/management_api/schemas/models.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | from management_api.schemas.elements.models import model_name, model_version 18 | 19 | 20 | model_delete_schema = { 21 | "type": "object", 22 | "title": "Model DELETE Schema", 23 | "required": [ 24 | "modelName", 25 | "modelVersion", 26 | ], 27 | "properties": { 28 | "modelName": model_name, 29 | "modelVersion": model_version, 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /management/management_api/schemas/tenants.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | from management_api.schemas.elements.names import tenant_name, scope_name 18 | from management_api.schemas.elements.resources import quota 19 | from management_api.schemas.elements.verifications import cert 20 | 21 | 22 | tenant_post_schema = { 23 | "type": "object", 24 | "title": "Tenant POST Schema", 25 | "required": [ 26 | "name", 27 | "cert", 28 | "scope", 29 | "quota" 30 | ], 31 | "properties": { 32 | "name": tenant_name, 33 | "cert": cert, 34 | "scope": scope_name, 35 | "quota": quota 36 | } 37 | } 38 | 39 | tenant_delete_schema = { 40 | "type": "object", 41 | "title": "Tenant DELETE Schema", 42 | "required": [ 43 | "name" 44 | ], 45 | "properties": { 46 | "name": tenant_name 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /management/management_api/schemas/uploads.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | from management_api.schemas.elements.models import model_name, model_version, upload_id, \ 18 | file_name, parts, dir 19 | 20 | multipart_start_schema = { 21 | "type": "object", 22 | "title": "Multipart upload start schema", 23 | "required": [ 24 | "modelName", 25 | "modelVersion", 26 | "fileName" 27 | ], 28 | "properties": { 29 | "modelName": model_name, 30 | "modelVersion": model_version, 31 | "fileName": file_name 32 | } 33 | } 34 | 35 | multipart_done_schema = { 36 | "type": "object", 37 | "title": "Multipart upload done schema", 38 | "required": [ 39 | "modelName", 40 | "modelVersion", 41 | "fileName", 42 | "uploadId", 43 | "parts" 44 | ], 45 | "properties": { 46 | "modelName": model_name, 47 | "modelVersion": model_version, 48 | "fileName": file_name, 49 | "uploadId": upload_id, 50 | "parts": parts 51 | } 52 | } 53 | 54 | multipart_abort_schema = { 55 | "type": "object", 56 | "title": "Multipart upload abort schema", 57 | "required": [ 58 | "modelName", 59 | "modelVersion", 60 | "fileName", 61 | "uploadId" 62 | ], 63 | "properties": { 64 | "modelName": model_name, 65 | "modelVersion": model_version, 66 | "fileName": file_name, 67 | "uploadId": upload_id 68 | } 69 | } 70 | 71 | upload_dir_schema = { 72 | "type": "object", 73 | "title": "Create directory inside bucket", 74 | "required": [ 75 | "key" 76 | ], 77 | "properties": { 78 | "key": dir 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /management/management_api/servings/__init__.py: -------------------------------------------------------------------------------- 1 | from .servings import Servings, Serving # noqa 2 | -------------------------------------------------------------------------------- /management/management_api/servings/servings.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | import falcon 18 | import json 19 | 20 | from management_api.servings.servings_utils import list_servings, get_serving 21 | 22 | 23 | class Servings(object): 24 | def on_get(self, req, resp): 25 | response = list_servings(req.params['Authorization']) 26 | resp.status = falcon.HTTP_OK 27 | resp.body = json.dumps({'status': 'OK', 'data': response}) 28 | 29 | 30 | class Serving(object): 31 | def on_get(self, req, resp, serving_name): 32 | response = get_serving(req.params['Authorization'], serving_name) 33 | resp.status = falcon.HTTP_OK 34 | resp.body = json.dumps({'status': 'OK', 'data': response}) 35 | -------------------------------------------------------------------------------- /management/management_api/servings/servings_utils.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | from kubernetes.client.rest import ApiException 18 | 19 | from management_api.config import CRD_NAMESPACE 20 | from management_api.tenants.tenants_utils import is_namespace_available 21 | from management_api.utils.errors_handling import KubernetesGetException, \ 22 | ResourceIsNotAvailableException 23 | from management_api.utils.kubernetes_resources import get_k8s_api_client 24 | 25 | 26 | def list_servings(id_token): 27 | if not is_namespace_available(CRD_NAMESPACE, id_token): 28 | raise ResourceIsNotAvailableException('namespace', CRD_NAMESPACE) 29 | 30 | api_client = get_k8s_api_client(id_token) 31 | try: 32 | config_maps = api_client.list_namespaced_config_map(CRD_NAMESPACE, pretty='true') 33 | except ApiException as apiException: 34 | raise KubernetesGetException('config map', apiException) 35 | 36 | crd_config_maps = [] 37 | for item in config_maps.to_dict()['items']: 38 | crd_config_maps.append(item['metadata']['name']) 39 | 40 | return crd_config_maps 41 | 42 | 43 | def get_serving(id_token, serving_name): 44 | if not is_namespace_available(CRD_NAMESPACE, id_token): 45 | raise ResourceIsNotAvailableException('namespace', CRD_NAMESPACE) 46 | 47 | api_client = get_k8s_api_client(id_token) 48 | try: 49 | config_map = api_client.read_namespaced_config_map(serving_name, CRD_NAMESPACE, 50 | pretty='true') 51 | except ApiException as apiException: 52 | raise KubernetesGetException('config map', apiException) 53 | 54 | crd_config_map = dict() 55 | try: 56 | crd_config_map = config_map.to_dict()['data'] 57 | except KeyError: 58 | raise ResourceIsNotAvailableException('serving template configuration', serving_name) 59 | 60 | return crd_config_map 61 | -------------------------------------------------------------------------------- /management/management_api/tenants/__init__.py: -------------------------------------------------------------------------------- 1 | from .tenants import Tenants # noqa 2 | -------------------------------------------------------------------------------- /management/management_api/tenants/tenants.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | import falcon 18 | import json 19 | from falcon.media.validators import jsonschema 20 | 21 | from management_api.tenants.tenants_utils import list_tenants, create_tenant, delete_tenant 22 | from management_api.utils.logger import get_logger 23 | from management_api.schemas.tenants import tenant_post_schema, tenant_delete_schema 24 | 25 | logger = get_logger(__name__) 26 | 27 | 28 | class Tenants(object): 29 | 30 | def on_get(self, req, resp): 31 | logger.info("List tenants") 32 | tenants = list_tenants(id_token=req.params['Authorization']) 33 | resp.status = falcon.HTTP_200 34 | resp.body = json.dumps({'status': 'OK', 'data': {'tenants': tenants}}) 35 | 36 | @jsonschema.validate(tenant_post_schema) 37 | def on_post(self, req, resp): 38 | logger.info("Create new tenant") 39 | for k, v in req.params.items(): 40 | logger.info("Param {} val {}".format(k, v)) 41 | body = req.media 42 | name = create_tenant(parameters=body, id_token=req.params['Authorization']) 43 | resp.status = falcon.HTTP_200 44 | resp.body = json.dumps({'status': 'CREATED', 'data': {'name': name}}) 45 | 46 | @jsonschema.validate(tenant_delete_schema) 47 | def on_delete(self, req, resp): 48 | body = req.media 49 | name = delete_tenant(parameters=body, id_token=req.params['Authorization']) 50 | resp.status = falcon.HTTP_200 51 | resp.body = json.dumps({'status': 'DELETED', 'data': {'name': name}}) 52 | -------------------------------------------------------------------------------- /management/management_api/upload/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/management/management_api/upload/__init__.py -------------------------------------------------------------------------------- /management/management_api/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/management/management_api/utils/__init__.py -------------------------------------------------------------------------------- /management/management_api/utils/cert.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | import base64 18 | import binascii 19 | from cryptography import x509 20 | from cryptography.hazmat.backends import default_backend 21 | 22 | from management_api.config import ValidityMessage 23 | from management_api.utils.errors_handling import InvalidParamException 24 | from management_api.utils.logger import get_logger 25 | logger = get_logger(__name__) 26 | 27 | 28 | def validate_cert(cert): 29 | try: 30 | pem_data = base64.b64decode(cert, validate=True) 31 | x509.load_pem_x509_certificate(pem_data, default_backend()) 32 | except binascii.Error: 33 | raise InvalidParamException("cert", "Error certificate Base64 decoding", 34 | ValidityMessage.CERTIFICATE) 35 | except ValueError: 36 | raise InvalidParamException("cert", "Incorrect certificate format", 37 | ValidityMessage.CERTIFICATE) 38 | logger.info('Initial certificate validation succeeded') 39 | return True 40 | -------------------------------------------------------------------------------- /management/management_api/utils/logger.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | import logging 18 | import os 19 | 20 | 21 | def get_logger(name): 22 | logger = logging.getLogger(name) 23 | logging_level = os.getenv('LOG_LEVEL', 'INFO') 24 | logger.setLevel(logging_level) 25 | logging.basicConfig(level=logging_level, format='%(asctime)s %(levelname)s %(message)s') 26 | return logger 27 | -------------------------------------------------------------------------------- /management/management_api/utils/routes.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | from management_api.upload.multipart import StartMultiModel, CompleteMultiModel, WriteMultiModel, \ 18 | AbortMultiModel, UploadDir 19 | from management_api.tenants import Tenants 20 | from management_api.endpoints import Endpoints, EndpointScale, Endpoint 21 | from management_api.authenticate import Authenticate, Token 22 | from management_api.models import Models 23 | from management_api.servings import Servings, Serving 24 | 25 | routes = [ 26 | dict(resource=Tenants(), url='/tenants'), 27 | dict(resource=Endpoints(), url='/tenants/{tenant_name}/endpoints'), 28 | dict(resource=EndpointScale(), url='/tenants/{tenant_name}/endpoints/{endpoint_name}/replicas'), 29 | dict(resource=Endpoint(), url='/tenants/{tenant_name}/endpoints/{endpoint_name}'), 30 | dict(resource=StartMultiModel(), url='/tenants/{tenant_name}/upload/start'), 31 | dict(resource=WriteMultiModel(), url='/tenants/{tenant_name}/upload'), 32 | dict(resource=CompleteMultiModel(), url='/tenants/{tenant_name}/upload/done'), 33 | dict(resource=AbortMultiModel(), url='/tenants/{tenant_name}/upload/abort'), 34 | dict(resource=UploadDir(), url='/tenants/{tenant_name}/upload/dir'), 35 | dict(resource=Authenticate(), url='/authenticate'), 36 | dict(resource=Token(), url='/authenticate/token'), 37 | dict(resource=Models(), url='/tenants/{tenant_name}/models'), 38 | dict(resource=Servings(), url='/servings'), 39 | dict(resource=Serving(), url='/servings/{serving_name}'), 40 | ] 41 | 42 | 43 | def register_routes(app): 44 | for route in routes: 45 | app.add_route(route['url'], route['resource']) 46 | -------------------------------------------------------------------------------- /management/requirements.txt: -------------------------------------------------------------------------------- 1 | requests==2.20.0 2 | kubernetes==6.1.0 3 | boto3==1.7.73 4 | botocore==1.10.73 5 | tenacity==5.0.2 6 | falcon==1.4.1 7 | jsonschema==2.6.0 8 | cryptography==2.3 9 | gevent==1.3.6 10 | gunicorn==19.9.0 11 | requests_oauthlib==1.0.0 12 | jwt==0.5.4 13 | -------------------------------------------------------------------------------- /management/run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Copyright (c) 2018 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | exec management_api 19 | 20 | -------------------------------------------------------------------------------- /management/setup.cfg: -------------------------------------------------------------------------------- 1 | [aliases] 2 | test=pytest -------------------------------------------------------------------------------- /management/setup.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | from setuptools import find_packages, setup 18 | 19 | install_requires = [] 20 | 21 | with open('requirements.txt', 'r') as f: 22 | for line in f: 23 | line = line.strip() 24 | if line and not line.startswith('#'): 25 | install_requires.append(line) 26 | 27 | setup( 28 | name='management-api', 29 | version=0.1, 30 | description="Management API", 31 | long_description="""Management API""", 32 | keywords='', 33 | author_email='', 34 | packages=find_packages(exclude=['ez_setup']), 35 | include_package_data=True, 36 | zip_safe=False, 37 | install_requires=install_requires, 38 | setup_requires=["pytest-runner"], 39 | tests_require=["pytest==3.7.1", "pytest-mock==1.10.0"], 40 | entry_points={ 41 | 'console_scripts': [ 42 | 'management_api = management_api.main:main', 43 | ] 44 | }, 45 | ) 46 | -------------------------------------------------------------------------------- /management/test/test_auth/test_authenticate.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018-2019 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | import pytest 18 | import falcon 19 | 20 | 21 | @pytest.mark.parametrize("params, expected_redirect_url", [({'offline': True}, 'oob'), 22 | ({}, 'callback')]) 23 | def test_authenticate_get(client, params, expected_redirect_url): 24 | expected_status = falcon.HTTP_308 25 | result = client.simulate_request(method='GET', path='/authenticate', params=params) 26 | assert expected_status == result.status 27 | assert expected_redirect_url in result.headers['Location'] 28 | 29 | 30 | @pytest.mark.parametrize("body, expected_status", 31 | [({'code': 'test'}, falcon.HTTP_OK), 32 | ({'modelName': 'wrong'}, falcon.HTTP_400), 33 | ({'refresh_token': 'test'}, falcon.HTTP_OK)]) 34 | def test_token_post(mocker, client, body, expected_status): 35 | get_token_mock = mocker.patch('management_api.authenticate.authenticate.get_token') 36 | get_token_mock.return_value = "test" 37 | result = client.simulate_request(method='POST', json=body, path='/authenticate/token') 38 | assert expected_status == result.status 39 | if expected_status is falcon.HTTP_OK: 40 | get_token_mock.assert_called_once() 41 | assert 'token' in result.text 42 | -------------------------------------------------------------------------------- /management/test/test_endpoints/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/management/test/test_endpoints/__init__.py -------------------------------------------------------------------------------- /management/test/test_models/test_models.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | import falcon 18 | 19 | 20 | def test_models_get(mocker, client): 21 | list_models_mock = mocker.patch('management_api.models.models.list_models') 22 | list_models_mock.return_value = 'test' 23 | expected_status = falcon.HTTP_OK 24 | 25 | result = client.simulate_request(method='GET', path='/tenants/default/models', headers={}) 26 | 27 | assert expected_status == result.status 28 | list_models_mock.assert_called_once() 29 | 30 | 31 | def test_models_delete(mocker, client): 32 | delete_model_mock = mocker.patch('management_api.models.models.delete_model') 33 | delete_model_mock.return_value = 'test' 34 | body = {'modelName': 'test', 'modelVersion': 1} 35 | expected_status = falcon.HTTP_OK 36 | 37 | result = client.simulate_request(method='DELETE', path='/tenants/default/models', 38 | headers={}, 39 | json=body) 40 | 41 | assert expected_status == result.status 42 | delete_model_mock.assert_called_once() 43 | -------------------------------------------------------------------------------- /management/test/test_upload/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/management/test/test_upload/__init__.py -------------------------------------------------------------------------------- /management/test/test_utils/auth_middleware_mock.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | 18 | class AuthMiddlewareMock(object): 19 | 20 | def process_request(self, req, resp): 21 | user_groups = ['default'] 22 | req.context['groups'] = user_groups 23 | req.params['Authorization'] = "TOKEN" 24 | -------------------------------------------------------------------------------- /scripts/ca.conf: -------------------------------------------------------------------------------- 1 | # Mainly copied from (not available anymore): 2 | # http://swearingscience.com/2009/01/18/openssl-self-signed-ca/ 3 | 4 | [ ca ] 5 | default_ca = myca 6 | 7 | [ crl_ext ] 8 | # issuerAltName=issuer:copy #this would copy the issuer name to altname 9 | authorityKeyIdentifier=keyid:always 10 | 11 | [ myca ] 12 | dir = /tmp/ 13 | new_certs_dir = $dir 14 | unique_subject = no 15 | certificate = $dir/ca.crt 16 | database = $dir/certindex 17 | private_key = $dir/ca.key 18 | serial = $dir/certserial 19 | default_days = 730 20 | default_md = sha1 21 | policy = myca_policy 22 | x509_extensions = myca_extensions 23 | crlnumber = $dir/crlnumber 24 | default_crl_days = 730 25 | 26 | [ myca_policy ] 27 | commonName = supplied 28 | stateOrProvinceName = supplied 29 | countryName = optional 30 | emailAddress = optional 31 | organizationName = supplied 32 | organizationalUnitName = optional 33 | 34 | [ myca_extensions ] 35 | basicConstraints = CA:false 36 | subjectKeyIdentifier = hash 37 | authorityKeyIdentifier = keyid:always 38 | keyUsage = digitalSignature,keyEncipherment 39 | extendedKeyUsage = serverAuth 40 | crlDistributionPoints = URI:http://example.com/root.crl 41 | subjectAltName = @alt_names 42 | 43 | [alt_names] 44 | DNS.1 = example.com 45 | DNS.2 = *.example.com 46 | -------------------------------------------------------------------------------- /scripts/create_tenant_certs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | TENANT_NAME=$1 19 | export TENANT_CERTS_DIR=`pwd`/certs/$IMM_RELEASE_PREFIX/$TENANT_NAME 20 | . ./generate_certs.sh $TENANT_CERTS_DIR 21 | cd - 22 | -------------------------------------------------------------------------------- /scripts/delete_tenant_certs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | TENANT_NAME=$1 19 | 20 | rm -rf `pwd`/certs/$IMM_RELEASE_PREFIX/$TENANT_NAME 21 | cd - 22 | -------------------------------------------------------------------------------- /scripts/generate_certs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright (c) 2018-2019 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | TENANT_CERTS_DIR=$1 18 | mkdir -p $TENANT_CERTS_DIR 19 | cp ca.conf $TENANT_CERTS_DIR 20 | cd $TENANT_CERTS_DIR 21 | 22 | # Generate a CA to be used for creating client certificates 23 | openssl genrsa -out ca-cert-tf.key 4096 24 | openssl req -new -x509 -days 365 -key ca-cert-tf.key -out ca-cert-tf.crt -subj "/CN=ca" 25 | # Generate client key and certificate authorizing access to inference endpoints. Change the CN as needed. 26 | openssl genrsa -out client-tf.key 4096 27 | openssl req -new -key client-tf.key -out client-tf.csr -subj "/CN=client" 28 | openssl x509 -req -days 365 -in client-tf.csr -CA ca-cert-tf.crt -CAkey ca-cert-tf.key -set_serial 01 -out client-tf.crt 29 | echo 01 > /tmp/certserial 30 | echo 01 > /tmp/crlnumber 31 | touch /tmp/certindex 32 | openssl ca -config ca.conf -gencrl -keyfile ca-cert-tf.key -cert ca-cert-tf.crt -out root.crl.pem 33 | cat root.crl.pem >> ca-cert-tf.crt 34 | if [[ "$OSTYPE" == "darwin"* ]]; then 35 | export CERT=`cat ca-cert-tf.crt|base64` 36 | else 37 | export CERT=`cat ca-cert-tf.crt|base64 -w0` 38 | fi 39 | 40 | echo "Client certificates for inference are stored in $TENANT_CERTS_DIR" 41 | cd - 42 | -------------------------------------------------------------------------------- /scripts/get_cert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | ADDRESS=$1 19 | SUBJECT=$2 20 | PROXY=$3 21 | 22 | if [ ! -z "$PROXY" ]; then 23 | proxytunnel -p $PROXY -d $ADDRESS:443 -a 7000 & 24 | openssl s_client -connect localhost:7000 -servername $ADDRESS -showcerts < /dev/null 2>/dev/null |grep "s:.*CN.*${SUBJECT}" -A 100 | openssl x509 -outform pem 25 | kill `ps -ef | grep proxytunnel | awk '{print $2}'` 26 | else 27 | openssl s_client -connect $ADDRESS:443 -servername $ADDRESS -showcerts < /dev/null 2>/dev/null | grep "s:.*CN.*${SUBJECT}" -A 100| openssl x509 -outform pem 28 | fi 29 | 30 | -------------------------------------------------------------------------------- /scripts/get_cert_kubectl.sh: -------------------------------------------------------------------------------- 1 | kubectl get secret ca-ing -n dex -o json | jq '.data."ca.crt"' | tr -d '"' | base64 --decode 2 | -------------------------------------------------------------------------------- /scripts/images/airliner.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/scripts/images/airliner.jpeg -------------------------------------------------------------------------------- /scripts/images/arctic-fox.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/scripts/images/arctic-fox.jpeg -------------------------------------------------------------------------------- /scripts/images/bee.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/scripts/images/bee.jpeg -------------------------------------------------------------------------------- /scripts/images/golden_retriever.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/scripts/images/golden_retriever.jpeg -------------------------------------------------------------------------------- /scripts/images/gorilla.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/scripts/images/gorilla.jpeg -------------------------------------------------------------------------------- /scripts/images/magnetic_compass.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/scripts/images/magnetic_compass.jpeg -------------------------------------------------------------------------------- /scripts/images/peacock.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/scripts/images/peacock.jpeg -------------------------------------------------------------------------------- /scripts/images/pelican.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/scripts/images/pelican.jpeg -------------------------------------------------------------------------------- /scripts/images/snail.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/scripts/images/snail.jpeg -------------------------------------------------------------------------------- /scripts/images/zebra.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/scripts/images/zebra.jpeg -------------------------------------------------------------------------------- /scripts/prepare_env_single_tenant_mode.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | export DEFAULT_TENANT_NAME="default-tenant" 19 | 20 | -------------------------------------------------------------------------------- /scripts/prepare_test_env.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2018-2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | export DOMAIN_NAME=$1 19 | export PROXY=$2 20 | export DEX_DOMAIN_NAME="dex.$DOMAIN_NAME" 21 | export MGMT_DOMAIN_NAME="mgt.$DOMAIN_NAME" 22 | 23 | echo "Fetching CA for $MGMT_DOMAIN_NAME" 24 | ./get_cert_kubectl.sh > ca.pem 25 | cat ./ca.pem 26 | 27 | export REQUESTS_CA_BUNDLE=`pwd`/ca.pem 28 | export MANAGEMENT_CA_CERT_PATH=`pwd`/ca.pem 29 | export CURL_CA_BUNDLE=`pwd`/ca.pem 30 | 31 | 32 | if [ "$MGT_API_AUTHORIZATION" == "true" ]; then 33 | OPENLDAP_SECRET_LDIFF=`kubectl get secret|grep "customldif "| awk '{ print $1 }'` 34 | USER_PASSWD=`kubectl get secret $OPENLDAP_SECRET_LDIFF -o yaml|grep immconfig|awk '{ print $2 }'|base64 --decode|grep userpassword|awk '{ print $2 }'` 35 | USER_NAME=user@example.com 36 | export IMM_USER_CREDENTIALS=$USER_NAME:$USER_PASSWD 37 | fi 38 | 39 | export DEX_NAMESPACE="dex" 40 | export MGT_NAMESPACE="mgt-api" 41 | export DEX_URL=https://${DEX_DOMAIN_NAME}:443 42 | export HELM_INSTALL_DIR="../installer/helm-temp-dir" 43 | export CERT=`cat $HELM_INSTALL_DIR/management-api-subchart/certs/ca-cert-tf.crt | $B64ENCODE` 44 | -------------------------------------------------------------------------------- /scripts/refresh_token.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018-2019 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | import argparse 18 | import json 19 | from os import getenv 20 | from os.path import expanduser, join 21 | from common_token import get_dex_auth_token, save_to_file 22 | 23 | 24 | def check_cert(cert_path): 25 | return None if 'None' is cert_path else cert_path 26 | 27 | 28 | def read_config(file_path): 29 | with open(file_path, 'r') as file: 30 | data = json.load(file) 31 | return data 32 | 33 | 34 | def parse_args(): 35 | parser = argparse.ArgumentParser() 36 | parser.add_argument('-k', "--insecure", help='', required=False, default=False, 37 | action='store_true') 38 | 39 | args = parser.parse_args() 40 | 41 | return args 42 | 43 | 44 | def main(): 45 | args = parse_args() 46 | config_file_path = getenv('IMM_CONFIG_PATH', join(expanduser("~"), '.immconfig')) 47 | config = read_config(config_file_path) 48 | ca_cert_path = check_cert(config['ca_cert_path']) 49 | proxy_host = config.get('proxy_host', None) 50 | proxy_port = config.get('proxy_port', None) 51 | new_token = get_dex_auth_token(address=config['management_api_address'], 52 | port=config['management_api_port'], 53 | auth_dict={'refresh_token': config['refresh_token']}, 54 | ca_cert_path=ca_cert_path, proxy_host=proxy_host, 55 | proxy_port=proxy_port, insecure=args.insecure, offline=True) 56 | 57 | config.update(new_token) 58 | save_to_file(config_file_path, config) 59 | 60 | 61 | if __name__ == '__main__': 62 | main() 63 | -------------------------------------------------------------------------------- /scripts/requirements.txt: -------------------------------------------------------------------------------- 1 | requests==2.20.0 2 | -r ../examples/grpc_client/requirements.txt 3 | -------------------------------------------------------------------------------- /server-controller/.dockerignore: -------------------------------------------------------------------------------- 1 | # File prepared in order to leverage docker cache after ADD instructions. 2 | # There were problems with long dep operation being repeated after slight Dockerfile changes. 3 | *.md 4 | .dockerignore 5 | lint.json 6 | Dockerfile.prod 7 | server-controller 8 | vendor 9 | .git 10 | -------------------------------------------------------------------------------- /server-controller/Dockerfile.prod: -------------------------------------------------------------------------------- 1 | FROM clearlinux:latest as first 2 | 3 | ENV GOBIN=/go/bin 4 | ENV PATH=$PATH:$GOBIN 5 | 6 | RUN swupd bundle-add go-basic make 7 | RUN rm -fr /run/lock/clrtrust.lock 8 | RUN clrtrust generate 9 | 10 | RUN go get -u github.com/golang/dep/cmd/dep 11 | ADD . /go/src/github.com/IntelAI/inference-model-manager/server-controller 12 | WORKDIR /go/src/github.com/IntelAI/inference-model-manager/server-controller 13 | RUN dep ensure -v 14 | 15 | RUN CGO_ENABLED=0 GOOS=linux go install -a -v -ldflags '-extldflags "-static"' github.com/IntelAI/inference-model-manager/server-controller 16 | 17 | FROM clearlinux:latest 18 | 19 | USER 1000 20 | COPY --from=first /go/bin/server-controller / 21 | WORKDIR / 22 | CMD ./server-controller 23 | -------------------------------------------------------------------------------- /server-controller/Gopkg.toml: -------------------------------------------------------------------------------- 1 | # Gopkg.toml example 2 | # 3 | # Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md 4 | # for detailed Gopkg.toml documentation. 5 | # 6 | # required = ["github.com/user/thing/cmd/thing"] 7 | # ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] 8 | # 9 | # [[constraint]] 10 | # name = "github.com/user/project" 11 | # version = "1.0.0" 12 | # 13 | # [[constraint]] 14 | # name = "github.com/user/project2" 15 | # branch = "dev" 16 | # source = "github.com/myfork/project2" 17 | # 18 | # [[override]] 19 | # name = "github.com/x/y" 20 | # version = "2.4.0" 21 | # 22 | # [prune] 23 | # non-go = false 24 | # go-tests = true 25 | # unused-packages = true 26 | 27 | 28 | [[constraint]] 29 | revision = "d338676af9989addaea935d4fc094ce147b43f84" 30 | name = "github.com/intel/crd-reconciler-for-kubernetes" 31 | 32 | [[constraint]] 33 | revision = "8b0133f28359c1325bd4799207a34fd935367ba2" 34 | name = "k8s.io/apiextensions-apiserver" 35 | 36 | [[constraint]] 37 | revision = "b63e1e4b3f7d0681e9a6e15bd4729d3014049e4e" 38 | name = "k8s.io/apimachinery" 39 | 40 | [[constraint]] 41 | revision = "2554b0b4622d739c8af9da548e8fe2223176803c" 42 | name = "k8s.io/client-go" 43 | 44 | [[constraint]] 45 | revision = "f30e293246921de7f4ee46bb65b8762b2f890fc4" 46 | name = "k8s.io/api" 47 | 48 | [[override]] 49 | revision = "8c0409fcbb70099c748d71f714529204975f6c3f" 50 | name = "github.com/ugorji/go" 51 | 52 | [prune] 53 | go-tests = true 54 | unused-packages = true 55 | -------------------------------------------------------------------------------- /server-controller/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018-2019 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | all: docker 18 | 19 | VERSION := $(shell git describe --tags --always --dirty) 20 | 21 | IMAGE ?= server-controller-prod 22 | TAG ?= latest 23 | 24 | HTTP_PROXY := "$(http_proxy)" 25 | HTTPS_PROXY := "$(https_proxy)" 26 | 27 | docker_build: 28 | docker build --build-arg http_proxy=$(HTTP_PROXY) --build-arg https_proxy=$(HTTPS_PROXY) -f Dockerfile.prod -t $(IMAGE):$(TAG) . 29 | 30 | lint: 31 | gometalinter --config=lint.json . 32 | gometalinter --config=lint.json ./apis/... 33 | 34 | check-coverage: 35 | ./check_coverage.sh 36 | 37 | test: lint 38 | go test --cover . 39 | go test --cover ./apis/cr/v1 40 | 41 | install-linter: 42 | go get -u github.com/alecthomas/gometalinter 43 | gometalinter --install 44 | 45 | code-generation: 46 | deepcopy-gen --input-dirs=github.com/IntelAI/inference-model-manager/server-controller/apis/cr/v1/... 47 | 48 | docker_tag: 49 | @ echo "tagging image" 50 | docker tag $(IMAGE):$(TAG) gcr.io/constant-cubist-173123/$(IMAGE):$(TAG) 51 | 52 | docker_push: 53 | @ echo "pushing container to gcr.io" 54 | gcloud docker -- push gcr.io/constant-cubist-173123/$(IMAGE):$(TAG) 55 | 56 | circleci: docker_build docker_tag docker_push 57 | -------------------------------------------------------------------------------- /server-controller/apis/cr/v1/doc.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2018 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | // SPDX-License-Identifier: EPL-2.0 17 | // 18 | 19 | // +k8s:deepcopy-gen=package 20 | 21 | package v1 22 | -------------------------------------------------------------------------------- /server-controller/check_coverage.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (c) 2019 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | COVERAGE=`go test -cover | grep -o '[0-9]\{1,3\}.[0-9]\{1,2\}%' | sed 's/\%//g'` 19 | 20 | check_coverage() { 21 | if [[ $(echo "$1 < 50" | bc) -ne 0 ]]; then 22 | echo "Coverage is under 50%" 23 | return 1 24 | fi 25 | } 26 | 27 | check_coverage $COVERAGE 28 | -------------------------------------------------------------------------------- /server-controller/kubernetes/deployment.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/server-controller/kubernetes/deployment.yml -------------------------------------------------------------------------------- /server-controller/lint.json: -------------------------------------------------------------------------------- 1 | { 2 | "vendor": true, 3 | "deadline": "2m", 4 | "aggregate": true, 5 | "enable-gc": true, 6 | "concurrency": 1, 7 | "DisableAll": true, 8 | "Enable": ["vet", "gofmt", "misspell", "golint"] 9 | } 10 | -------------------------------------------------------------------------------- /server-controller/mock_client_test.go: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (c) 2019 Intel Corporation 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // 16 | 17 | package main 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | 22 | "github.com/intel/crd-reconciler-for-kubernetes/pkg/resource" 23 | "github.com/intel/crd-reconciler-for-kubernetes/pkg/states" 24 | "k8s.io/apimachinery/pkg/runtime" 25 | ) 26 | 27 | type mockClient struct { 28 | createError error 29 | patchError error 30 | updateError error 31 | deleteError error 32 | } 33 | 34 | func newMockClient(err mockClient) resource.Client { 35 | return &err 36 | } 37 | 38 | func (*mockClient) Reify(templateValues interface{}) ([]byte, error) { 39 | return nil, nil 40 | } 41 | 42 | func (c *mockClient) Create(namespace string, templateValues interface{}) error { 43 | return c.createError 44 | } 45 | 46 | func (c *mockClient) Delete(namespace string, name string) error { 47 | return c.deleteError 48 | } 49 | 50 | func (c *mockClient) Update(namespace string, name string, templateValues interface{}) error { 51 | return c.updateError 52 | } 53 | 54 | func (c *mockClient) Patch(namespace string, name string, data []byte) error { 55 | return c.patchError 56 | } 57 | 58 | func (*mockClient) Get(namespace, name string) (runtime.Object, error) { 59 | return nil, nil 60 | } 61 | 62 | func (*mockClient) List(namespace string, labels map[string]string) ([]metav1.Object, error) { 63 | return nil, nil 64 | } 65 | 66 | func (*mockClient) IsFailed(namespace string, name string) bool { 67 | return true 68 | } 69 | 70 | func (*mockClient) IsEphemeral() bool { 71 | return true 72 | } 73 | 74 | func (*mockClient) Plural() string { 75 | return "" 76 | } 77 | 78 | func (*mockClient) GetStatusState(runtime.Object) states.State { 79 | return states.Pending 80 | } 81 | -------------------------------------------------------------------------------- /tests/Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | test: 18 | ./run_test.sh 19 | 20 | style: 21 | flake8 --max-line-length 100 management_api_tests/ e2e_tests/ integration/ config.py conftest.py context.py 22 | -------------------------------------------------------------------------------- /tests/README.md: -------------------------------------------------------------------------------- 1 | ## Management API testing 2 | It is possible to check if platform is working properly by running tests. 3 | 4 | ### Prerequisites 5 | 6 | To run tests you need to create virtual environment: 7 | ```shell 8 | $ python3 -m venv .venv 9 | $ . .venv/bin/activate 10 | $ pip install -r requirements.txt 11 | ``` 12 | ### Run tests 13 | 14 | Simplest way to run tests against the platform is by script provided: 15 | ``` 16 | ./run_test.sh 17 | ``` 18 | 19 | #### Certificates 20 | If you use self-signed certificates for platform you have to install your CA and pass to python interpreter. 21 | For example for Ubuntu you could do something like this: 22 | ``` 23 | sudo cp /usr/local/share/ca-certificates/ 24 | sudo update-ca-certificates 25 | export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt 26 | ``` 27 | -------------------------------------------------------------------------------- /tests/e2e_tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/tests/e2e_tests/__init__.py -------------------------------------------------------------------------------- /tests/e2e_tests/config.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | import os 18 | 19 | TENANT_NAME = os.environ.get('E2E_TENANT_NAME', 'test') 20 | MODEL_NAME = os.environ.get('E2E_MODEL_NAME', 'e2emodel') 21 | ENDPOINT_NAME = os.environ.get('E2E_ENDPOINT_NAME', MODEL_NAME + 'endpoint') 22 | CREATE_ENDPOINT_VP = '{specific {versions: 1}}' 23 | UPDATE_ENDPOINT_VP = '{specific {versions: 2}}' 24 | -------------------------------------------------------------------------------- /tests/e2e_tests/inference_endpoints/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/tests/e2e_tests/inference_endpoints/__init__.py -------------------------------------------------------------------------------- /tests/e2e_tests/management_api_requests.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018-2019 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | import requests 18 | import json 19 | 20 | from management_api_tests.config import SCOPE_NAME 21 | 22 | from e2e_tests.config import TENANT_NAME, MODEL_NAME 23 | from config import CERT, ADMIN_HEADERS, TENANT_RESOURCES, TENANTS_MANAGEMENT_API_URL, \ 24 | DEFAULT_HEADERS, ENDPOINTS_MANAGEMENT_API_URL, \ 25 | ENDPOINT_MANAGEMENT_API_URL 26 | 27 | 28 | def create_tenant(name=TENANT_NAME, headers=ADMIN_HEADERS, 29 | scope=SCOPE_NAME, resources=TENANT_RESOURCES, cert=CERT): 30 | data = json.dumps({ 31 | 'name': name, 32 | 'cert': cert, 33 | 'scope': scope, 34 | 'quota': resources, 35 | }) 36 | url = TENANTS_MANAGEMENT_API_URL 37 | 38 | response = requests.post(url, data=data, headers=headers, verify=False) 39 | return response 40 | 41 | 42 | def delete_tenant(headers=ADMIN_HEADERS, name=TENANT_NAME): 43 | url = TENANTS_MANAGEMENT_API_URL 44 | data = json.dumps({ 45 | 'name': name, 46 | }) 47 | response = requests.delete(url, data=data, headers=headers, verify=False) 48 | return response 49 | 50 | 51 | def create_endpoint(params: dict, headers=DEFAULT_HEADERS, tenant=TENANT_NAME): 52 | data = json.dumps(params) 53 | url = ENDPOINTS_MANAGEMENT_API_URL.format(tenant_name=tenant) 54 | 55 | response = requests.post(url, data=data, headers=headers, verify=False) 56 | return response 57 | 58 | 59 | def update_endpoint(params: dict, headers=DEFAULT_HEADERS, name=MODEL_NAME, 60 | tenant=TENANT_NAME): 61 | data = json.dumps(params) 62 | url = ENDPOINT_MANAGEMENT_API_URL.format(tenant_name=tenant, endpoint_name=name + 'endpoint') 63 | 64 | response = requests.patch(url, data=data, headers=headers, verify=False) 65 | return response 66 | -------------------------------------------------------------------------------- /tests/e2e_tests/tf_serving_utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/tests/e2e_tests/tf_serving_utils/__init__.py -------------------------------------------------------------------------------- /tests/e2e_tests/tf_serving_utils/fox.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/tests/e2e_tests/tf_serving_utils/fox.jpg -------------------------------------------------------------------------------- /tests/e2e_tests/tf_serving_utils/images.npy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/tests/e2e_tests/tf_serving_utils/images.npy -------------------------------------------------------------------------------- /tests/e2e_tests/tf_serving_utils/load_numpy.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018-2019 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | import sys 17 | import os 18 | import numpy 19 | sys.path.append(os.path.realpath(os.path.join(os.path.realpath(__file__), '../../../../examples/grpc_client'))) # noqa 20 | from images_2_numpy import get_jpeg 21 | 22 | IMAGES = numpy.load("e2e_tests/tf_serving_utils/images.npy")[:2] 23 | LABELS = [277, 210] 24 | 25 | JPG_IMAGE = get_jpeg("e2e_tests/tf_serving_utils/fox.jpg", 224) 26 | -------------------------------------------------------------------------------- /tests/integration/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/tests/integration/__init__.py -------------------------------------------------------------------------------- /tests/management_api_tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/tests/management_api_tests/__init__.py -------------------------------------------------------------------------------- /tests/management_api_tests/authenticate/test_authenticate.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | import requests 18 | import pytest 19 | import json 20 | 21 | from config import AUTH_MANAGEMENT_API_URL, TOKEN_MANAGEMENT_API_URL 22 | from management_api_tests.authenticate import authenticate, MERCURY_CREDENTIALS 23 | 24 | 25 | def test_get_auth_redirection(): 26 | url = AUTH_MANAGEMENT_API_URL 27 | response = requests.get(url, allow_redirects=False) 28 | assert response.status_code == 308 29 | 30 | 31 | @pytest.mark.parametrize("body_key, refresh_token", [('code', False), ('refresh_token', True)]) 32 | def test_get_token(body_key, refresh_token): 33 | if 'code' in body_key: 34 | code = authenticate(username=MERCURY_CREDENTIALS['login'], 35 | password=MERCURY_CREDENTIALS['password'], 36 | token=refresh_token) 37 | else: 38 | code = authenticate(username=MERCURY_CREDENTIALS['login'], 39 | password=MERCURY_CREDENTIALS['password'], 40 | token=refresh_token)['refresh_token'] 41 | url = TOKEN_MANAGEMENT_API_URL 42 | data = json.dumps({ 43 | body_key: code 44 | }) 45 | response = requests.post(url, data=data) 46 | 47 | assert response.status_code == 200 48 | assert 'token' in response.text 49 | -------------------------------------------------------------------------------- /tests/management_api_tests/endpoints/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/tests/management_api_tests/endpoints/__init__.py -------------------------------------------------------------------------------- /tests/management_api_tests/models/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/tests/management_api_tests/models/__init__.py -------------------------------------------------------------------------------- /tests/management_api_tests/reused.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | import re 17 | 18 | from management_api_tests.config import PORTABLE_SECRETS_PATHS 19 | 20 | 21 | def transform_quota(quota): 22 | transformed = {} 23 | for k, v in quota.items(): 24 | keys = k.split('.') 25 | if len(keys) == 1: 26 | continue 27 | transformed.setdefault(keys[0], {})[keys[1]] = v 28 | return transformed 29 | 30 | 31 | def propagate_secret(api_instance, source_secret_path, target_namespace): 32 | source_secret_namespace, source_secret_name = source_secret_path.split('/') 33 | source_secret = api_instance.read_namespaced_secret( 34 | source_secret_name, source_secret_namespace) 35 | 36 | source_secret.metadata.namespace = target_namespace 37 | source_secret.metadata.resource_version = None 38 | 39 | api_instance.create_namespaced_secret(namespace=target_namespace, 40 | body=source_secret) 41 | 42 | 43 | def propagate_portable_secrets(api_instance, target_namespace): 44 | for portable_secret_path in PORTABLE_SECRETS_PATHS: 45 | propagate_secret(api_instance, portable_secret_path, target_namespace) 46 | 47 | 48 | def normalize_version_policy(version_policy): 49 | normalized_version_policy = re.sub(r'\s+', '', version_policy) 50 | normalized_version_policy = re.sub(r'(\d)', r'\1 ', normalized_version_policy) 51 | return normalized_version_policy 52 | -------------------------------------------------------------------------------- /tests/management_api_tests/servings/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/tests/management_api_tests/servings/__init__.py -------------------------------------------------------------------------------- /tests/management_api_tests/tenants/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intel/inference-model-manager/55b1a87bea2eb78b897bbd5cdb34332d3d1755ca/tests/management_api_tests/tenants/__init__.py -------------------------------------------------------------------------------- /tests/management_api_tests/upload/test_multipart_upload.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2019 Intel Corporation 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | import json 18 | import requests 19 | import pytest 20 | from config import DEFAULT_HEADERS, USER1_HEADERS, START_MULTIPART_UPLOAD_API_URL, USER2_HEADERS 21 | 22 | 23 | @pytest.mark.parametrize("tenant_fix, auth, body, expected_status", 24 | [('session_tenant', DEFAULT_HEADERS, {'modelName': 'resnet2', 25 | 'modelVersion': 1, 26 | 'fileName': 'saved_model.pb'}, 27 | 200), 28 | ('session_tenant', DEFAULT_HEADERS, {'modelName': 'resnet2'}, 400), 29 | ('fake_saturn_tenant', USER2_HEADERS, {'modelName': 'resnet2', 30 | 'modelVersion': 1, 31 | 'fileName': 'saved_model.pb'}, 32 | 404), 33 | ('session_tenant', USER1_HEADERS, {'modelName': 'resnet2', 34 | 'modelVersion': 1, 35 | 'fileName': 'saved_model.pb'}, 403), 36 | ]) 37 | def test_multipart_upload(request, tenant_fix, auth, body, expected_status): 38 | namespace, _ = request.getfixturevalue(tenant_fix) 39 | data = json.dumps(body) 40 | url = START_MULTIPART_UPLOAD_API_URL.format(tenant_name=namespace) 41 | response = requests.post(url, data=data, headers=auth) 42 | assert expected_status == response.status_code 43 | -------------------------------------------------------------------------------- /tests/requirements.txt: -------------------------------------------------------------------------------- 1 | requests==2.20.0 2 | kubernetes==6.0.0 3 | boto3==1.7.73 4 | botocore==1.10.73 5 | tenacity==5.0.2 6 | numpy==1.15.1 7 | tensorflow-serving-api==1.11.0 8 | tensorflow==1.11.0 9 | pytest==3.7.1 10 | utils==0.9.0 11 | beautifulsoup4==4.6.3 12 | Pillow==5.3.0 13 | -------------------------------------------------------------------------------- /tests/run_test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # Copyright (c) 2018 Intel Corporation 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | export MANAGEMENT_API_URL="https://${MGMT_DOMAIN_NAME}:443" 19 | echo "URL FOR MANAGEMENT API: $MANAGEMENT_API_URL" 20 | 21 | export DEX_URL="https://${DEX_DOMAIN_NAME}:443" 22 | echo "URL FOR DEX: $DEX_URL" 23 | 24 | MINIO_SECRET_KEY=`kubectl get secret minio-access-info -n mgt-api -o 'go-template={{index .data "minio.access_secret_key"}}' | base64 -d` 25 | echo $MINIO_SECRET_KEY 26 | 27 | MINIO_ACCESS_KEY=`kubectl get secret minio-access-info -n mgt-api -o 'go-template={{index .data "minio.access_key_id"}}' | base64 -d` 28 | echo $MINIO_ACCESS_KEY 29 | 30 | export MINIO_ENDPOINT_ADDR='http://127.0.0.1:9000' 31 | export MINIO_POD=`kubectl get pod | grep minio | awk '{print $1}'` 32 | kubectl port-forward ${MINIO_POD} 9000:9000 & 33 | 34 | pytest -v 35 | 36 | echo "Stop port forwarding" 37 | pkill -e -f "port-forward" 38 | echo "Pkill succeded" 39 | 40 | 41 | exit 0 42 | --------------------------------------------------------------------------------