Merge branch 'develop' into DLAB-1594-2
diff --git a/infrastructure-provisioning/scripts/deploy_repository/deploy_repository.py b/infrastructure-provisioning/scripts/deploy_repository/deploy_repository.py
index 3864229..0c761a5 100644
--- a/infrastructure-provisioning/scripts/deploy_repository/deploy_repository.py
+++ b/infrastructure-provisioning/scripts/deploy_repository/deploy_repository.py
@@ -1186,7 +1186,7 @@
'https://repo1.maven.org/maven2/org/jfree/jfreechart/{0}/jfreechart-{0}.jar'.format('1.0.19'),
'https://repo1.maven.org/maven2/org/jfree/jcommon/{0}/jcommon-{0}.jar'.format('1.0.24'),
'--no-check-certificate https://brunelvis.org/jar/spark-kernel-brunel-all-{0}.jar'.format('2.3'),
- 'http://archive.apache.org/dist/incubator/toree/0.2.0-incubating/toree-pip/toree-0.2.0.tar.gz',
+ 'http://archive.apache.org/dist/incubator/toree/0.3.0-incubating/toree-pip/toree-0.3.0.tar.gz',
'https://download2.rstudio.org/server/trusty/amd64/rstudio-server-{}-amd64.deb'.format(
configuration['notebook_rstudio_version']),
'http://us.download.nvidia.com/XFree86/Linux-x86_64/{0}/NVIDIA-Linux-x86_64-{0}.run'.format(
@@ -1222,10 +1222,10 @@
configuration['notebook_livy_version']),
'https://dl.bintray.com/spark-packages/maven/tapanalyticstoolkit/spark-tensorflow-connector/'
'1.0.0-s_2.11/spark-tensorflow-connector-1.0.0-s_2.11.jar',
- 'https://archive.apache.org/dist/incubator/toree/0.2.0-incubating/toree/'
- 'toree-0.2.0-incubating-bin.tar.gz',
- 'https://repo1.maven.org/maven2/org/apache/toree/toree-assembly/0.2.0-incubating/'
- 'toree-assembly-0.2.0-incubating.jar',
+ 'https://archive.apache.org/dist/incubator/toree/0.3.0-incubating/toree/'
+ 'toree-0.3.0-incubating-bin.tar.gz',
+ 'https://repo1.maven.org/maven2/org/apache/toree/toree-assembly/0.3.0-incubating/'
+ 'toree-assembly-0.3.0-incubating.jar',
'https://cran.r-project.org/src/contrib/Archive/keras/keras_{}.tar.gz'.format(
configuration['notebook_keras_version'])
]
diff --git a/infrastructure-provisioning/scripts/jenkins/sonar.py b/infrastructure-provisioning/scripts/jenkins/sonar.py
new file mode 100644
index 0000000..207ffef
--- /dev/null
+++ b/infrastructure-provisioning/scripts/jenkins/sonar.py
@@ -0,0 +1,36 @@
+#!/usr/bin/python
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+import requests
+import sys
+import time
+import urllib
+
+time.sleep(30) # wait for new code to be analyzed by SonarQube
+
+PROJECT_KEY = urllib.quote(sys.argv[1])
+TOKEN = sys.argv[2]
+
+
+def get_sonarqube_status():
+ response = requests.get('http://localhost:9000/sonar/api/qualitygates/project_status?projectKey=' + PROJECT_KEY,
+ auth=(TOKEN, '')).json()
+ return response['projectStatus']['status']
+
+
+print(get_sonarqube_status())
diff --git a/infrastructure-provisioning/src/dataengine/scripts/configure_dataengine.py b/infrastructure-provisioning/src/dataengine/scripts/configure_dataengine.py
index e5aacb8..2089613 100644
--- a/infrastructure-provisioning/src/dataengine/scripts/configure_dataengine.py
+++ b/infrastructure-provisioning/src/dataengine/scripts/configure_dataengine.py
@@ -53,6 +53,7 @@
caffe2_version = os.environ['notebook_caffe2_version']
cmake_version = os.environ['notebook_cmake_version']
cntk_version = os.environ['notebook_cntk_version']
+cntk2_version = os.environ['notebook_cntk2_version']
mxnet_version = os.environ['notebook_mxnet_version']
python3_version = "3.4"
scala_link = "http://www.scala-lang.org/files/archive/"
@@ -173,10 +174,10 @@
if os.environ['application'] == 'deeplearning':
print("Installing Caffe2")
install_caffe2(args.os_user, caffe2_version, cmake_version)
- print("Installing Torch")
- install_torch(args.os_user)
+ #print("Installing Torch")
+ #install_torch(args.os_user)
print("Install CNTK Python library")
- install_cntk(args.os_user, cntk_version)
+ install_cntk(args.os_user, cntk2_version, cntk_version)
print("Installing MXNET")
install_mxnet(args.os_user, mxnet_version)
@@ -202,3 +203,25 @@
if os.environ['application'] == 'zeppelin' and os.environ['notebook_r_enabled'] == 'true':
print("Install additional R packages")
install_r_packages(args.os_user)
+
+ # INSTALL LIVY
+ if not exists('/home/{0}/.ensure_dir/livy_ensured'.format(args.os_user)):
+ livy_version = '0.7.0'
+ sudo(
+ 'wget -nv --timeout=30 --tries=5 --retry-connrefused https://archive.apache.org/dist/incubator/livy/{0}-incubating/apache-livy-{0}-incubating-bin.zip -P /tmp/'.format(
+ livy_version))
+ sudo('unzip -q /tmp/apache-livy-{}-incubating-bin.zip -d /tmp/'.format(livy_version))
+ sudo('mv /tmp/apache-livy-{}-incubating-bin /opt/livy'.format(livy_version))
+ sudo('mkdir /var/log/livy')
+ put('~/templates/livy-env.sh', '/tmp/livy-env.sh')
+ sudo('mv /tmp/livy-env.sh /opt/livy/conf/livy-env.sh')
+ sudo('chown -R -L {0}:{0} /opt/livy/'.format(args.os_user))
+ sudo('chown -R {0}:{0} /var/log/livy'.format(args.os_user))
+ put('~/templates/livy.service', '/tmp/livy.service')
+ sudo("sed -i 's|OS_USER|{}|' /tmp/livy.service".format(args.os_user))
+ sudo('mv /tmp/livy.service /etc/systemd/system/livy.service')
+ sudo('systemctl daemon-reload')
+ sudo('systemctl enable livy.service')
+ sudo('systemctl start livy.service')
+ sudo('touch /home/{0}/.ensure_dir/livy_ensured'.format(args.os_user))
+
diff --git a/infrastructure-provisioning/src/deeplearning/scripts/configure_deep_learning_node.py b/infrastructure-provisioning/src/deeplearning/scripts/configure_deep_learning_node.py
index 741ca18..b2e93d0 100644
--- a/infrastructure-provisioning/src/deeplearning/scripts/configure_deep_learning_node.py
+++ b/infrastructure-provisioning/src/deeplearning/scripts/configure_deep_learning_node.py
@@ -56,14 +56,15 @@
caffe2_version = os.environ['notebook_caffe2_version']
cmake_version = os.environ['notebook_cmake_version']
cntk_version = os.environ['notebook_cntk_version']
+cntk2_version = os.environ['notebook_cntk2_version']
mxnet_version = os.environ['notebook_mxnet_version']
-keras_version = '2.0.8'
+keras_version = os.environ['notebook_keras_version']
theano_version = os.environ['notebook_theano_version']
-tensorflow_version = '1.4.0'
-cuda_version = '8.0'
-cuda_file_name = 'cuda_8.0.44_linux-run'
-cudnn_version = '6.0'
-cudnn_file_name = 'cudnn-8.0-linux-x64-v6.0.tgz'
+tensorflow_version = os.environ['notebook_tensorflow_version']
+cuda_version = os.environ['notebook_cuda_version']
+cuda_file_name = os.environ['notebook_cuda_file_name']
+cudnn_version = os.environ['notebook_cudnn_version']
+cudnn_file_name = os.environ['notebook_cudnn_file_name']
if args.region == 'cn-north-1':
spark_link = "http://mirrors.hust.edu.cn/apache/spark/spark-" + spark_version + "/spark-" + spark_version + \
@@ -83,6 +84,9 @@
if not exists('/home/{}/.ensure_dir/itorch_ensured'.format(os_user)):
run('git clone https://github.com/facebook/iTorch.git')
with cd('/home/{}/iTorch/'.format(os_user)):
+ run('luarocks install luacrypto')
+ run('luarocks install uuid')
+ run('luarocks install lzmq')
run('luarocks make')
sudo('cp -rf /home/{0}/.ipython/kernels/itorch/ /home/{0}/.local/share/jupyter/kernels/'.format(os_user))
sudo('chown -R {0}:{0} /home/{0}/.local/share/jupyter/'.format(os_user))
@@ -125,10 +129,10 @@
install_keras(args.os_user, keras_version)
print("Installing Caffe2")
install_caffe2(args.os_user, caffe2_version, cmake_version)
- print("Installing Torch")
- install_torch(args.os_user)
+ #print("Installing Torch")
+ #install_torch(args.os_user)
print("Install CNTK Python library")
- install_cntk(args.os_user, cntk_version)
+ install_cntk(args.os_user,cntk2_version, cntk_version)
print("Installing MXNET")
install_mxnet(args.os_user, mxnet_version)
@@ -149,8 +153,8 @@
ensure_pyspark_local_kernel(args.os_user, pyspark_local_path_dir, templates_dir, spark_version)
print("Install py3spark local kernel for Jupyter")
ensure_py3spark_local_kernel(args.os_user, py3spark_local_path_dir, templates_dir, spark_version)
- print("Installing ITorch kernel for Jupyter")
- install_itorch(args.os_user)
+ #print("Installing ITorch kernel for Jupyter")
+ #install_itorch(args.os_user)
# INSTALL UNGIT
print("Install nodejs")
@@ -169,7 +173,7 @@
ensure_additional_python_libs(args.os_user)
print("Install Matplotlib")
ensure_matplot(args.os_user)
-
+
#POST INSTALLATION PROCESS
print("Updating pyOpenSSL library")
update_pyopenssl_lib(args.os_user)
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/conf/dlab.ini b/infrastructure-provisioning/src/general/conf/dlab.ini
index 98b621d..e11158e 100644
--- a/infrastructure-provisioning/src/general/conf/dlab.ini
+++ b/infrastructure-provisioning/src/general/conf/dlab.ini
@@ -62,7 +62,7 @@
network_type = public
### Additional tags in format 'Key1:Value1;Key2:Value2'
# additional_tags =
-pip_version = 9.0.3
+pip_version = 20.1
### Billing tag key
billing_tag_key = product
### Billing tag value
@@ -119,7 +119,7 @@
### Amazon zone letter for ssn, edge and notebook subnet provisioning
# zone =
### Amazon ami name based on debian conf_os_family for all dlab instances
-debian_image_name = ubuntu/images/hvm-ssd/ubuntu-xenial-16.04-amd64-server-20190212
+debian_image_name = ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-20200112
### Amazon ami name based on RedHat conf_os_family for all dlab instances
redhat_image_name = RHEL-7.4_HVM-20180103-x86_64-2-Hourly2-GP2
### Amazon account ID
@@ -151,7 +151,7 @@
### Slave node size for Data Engine
# dataengine_slave_size =
### Azure image name based on debian conf_os_family for all dlab instances
-debian_image_name = Canonical_UbuntuServer_16.04-LTS
+debian_image_name = Canonical_UbuntuServer_18.04-LTS
### Azure image name based on RedHat conf_os_family for all dlab instances
redhat_image_name = RedHat_RHEL_7.3
### Azure AD user name
@@ -189,7 +189,7 @@
### GCP zone name for whole dlab provisioning
zone = us-west1-a
### GCP ami name based on debian conf_os_family for all dlab instances
-debian_image_name = /projects/ubuntu-os-cloud/global/images/ubuntu-1604-xenial-v20190807
+debian_image_name = /projects/ubuntu-os-cloud/global/images/ubuntu-1804-bionic-v20200317
### GCP ami name based on RedHat conf_os_family for all dlab instances
redhat_image_name =
### Prefix of the private subnet
@@ -223,6 +223,8 @@
# user_name =
### Elastic IP which will be associated with Edge node
# elastic_ip =
+### Edge node is NAT
+is_nat = true
#--- [notebook] section contains all parameters that are using for all notebooks provisioning ---#
[notebook]
@@ -237,7 +239,7 @@
### Version of Jupyter to be installed on notebook
jupyter_version = 6.0.2
### Version of TensorFlow to be installed on notebook
-tensorflow_version = 1.8.0
+tensorflow_version = 2.1.0
### Version of Zeppelin to be installed on notebook
zeppelin_version = 0.8.2
### Version of Rstudio to be installed on notebook
@@ -251,30 +253,34 @@
### R China mirror
r_mirror = http://mirror.lzu.edu.cn/CRAN/
### NVidia driver version for Tensor/DeepLearning notebooks
-nvidia_version = 418.43
+nvidia_version = 418.126.02
### Caffe library version for DeepLearning notebook
caffe_version = 1.0
### Caffe2 library version for DeepLearning notebook
-caffe2_version = 0.4.0
+caffe2_version = 1.5
+### Pytorch branch used during caffe2 installation for DeepLearning notebook
+pytorch_branch = release/1.5
### Cmake version for DeepLearning notebook
-cmake_version = 3.11.3
-### CNTK library version for DeepLearning notebook
+cmake_version = 3.15.5
+### CNTK library version for DeepLearning notebook for python2
### All releases 2.4+ officially only support Ubuntu 16.04.
-cntk_version = 2.3.1
-### MXNet library version for DeepLearning notebook
-mxnet_version = 1.3.1
+cntk2_version = 2.3.1
+### CNTK library version for DeepLearning notebook for python3
+cntk_version = 2.7
+### MXNet library version for DeepLearning notebook for python
+mxnet_version = 1.6.0
### Keras library version for Tensor/DeepLearning notebook
keras_version = 2.1.6
### Theano library version for Tensor/DeepLearning notebook
theano_version = 1.0.3
### Version of CUDA
-cuda_version = 9.0
+cuda_version = 10.1
### Name of CUDA file
-cuda_file_name = cuda_9.0.176_384.81_linux-run
+cuda_file_name = cuda_10.1.243_418.87.00_linux.run
### Version of CUDNN
-cudnn_version = 7.1.4
+cudnn_version = 7.6.5
### Name of CUDNN file
-cudnn_file_name = cudnn-9.0-linux-x64-v7.1.tgz
+cudnn_file_name = cudnn-10.1-linux-x64-v7.6.5.32.tgz
### R enabled on Jupyter/Zeppelin notebook
r_enabled = true
### Temporary fixed python libraries due to dependencies
@@ -283,7 +289,9 @@
### Version of ungit if previous needed. Use latest as default.
ungit_version = 1.4.36
### Numpy version
-numpy_version = 1.14.3
+numpy_version = 1.18.3
+### Numpy version for python 2
+numpy2_version = 1.16.6
### Apache Ivy version
ivy_version = 2.4.0
### Matplotlib version
@@ -294,6 +302,8 @@
superset_version = 0.35.1
### GCS-connector version
gcs_connector_version = 2.0.1
+### Setuptools version
+setuptools_version = 41.0.0
#--- [emr] section contains all parameters that are using for emr provisioning ---#
[emr]
@@ -364,4 +374,4 @@
#--- [reverse_proxy] reverse proxy settings ---#
[reverse_proxy]
### Nginx version
-nginx_version = 1.15.1
+nginx_version = 1.15.1
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/files/aws/base_Dockerfile b/infrastructure-provisioning/src/general/files/aws/base_Dockerfile
index 48f5e2d..e298f18 100644
--- a/infrastructure-provisioning/src/general/files/aws/base_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/aws/base_Dockerfile
@@ -19,7 +19,7 @@
#
# ******************************************************************************
-FROM ubuntu:16.04
+FROM ubuntu:18.04
ARG OS
ARG SRC_PATH
@@ -30,7 +30,7 @@
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Install any python dependencies
-RUN pip install -UI pip==9.0.3 && \
+RUN pip install -UI pip==20.1 && \
pip install boto3 backoff fabric==1.14.0 fabvenv awscli argparse requests ujson jupyter pycrypto
# Configuring ssh for user
diff --git a/infrastructure-provisioning/src/general/files/aws/dataengine-service_description.json b/infrastructure-provisioning/src/general/files/aws/dataengine-service_description.json
index b4e5ba2..c95503d 100644
--- a/infrastructure-provisioning/src/general/files/aws/dataengine-service_description.json
+++ b/infrastructure-provisioning/src/general/files/aws/dataengine-service_description.json
@@ -24,7 +24,7 @@
},
"templates":
[
- {"version":"emr-5.19.0", "applications": [{"Name":"Hadoop", "Version": "2.8.5"}, {"Name":"Spark", "Version": "2.3.2"}, {"Name":"Hive", "Version": "2.3.3"}]},
- {"version":"emr-5.28.0", "applications": [{"Name":"Hadoop", "Version": "2.8.5"}, {"Name":"Spark", "Version": "2.4.4"}, {"Name":"Hive", "Version": "2.3.6"}]}
+ {"version":"emr-5.30.0", "applications": [{"Name":"Hadoop", "Version": "2.8.5"}, {"Name":"Spark", "Version": "2.4.4"}, {"Name":"Hive", "Version": "2.3.6"}]},
+ {"version":"emr-6.0.0", "applications": [{"Name":"Hadoop", "Version": "3.2.1"}, {"Name":"Spark", "Version": "2.4.4"}, {"Name":"Hive", "Version": "3.1.2"}]}
]
}
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/files/aws/dataengine_Dockerfile b/infrastructure-provisioning/src/general/files/aws/dataengine_Dockerfile
index a0be3e1..313ddd2 100644
--- a/infrastructure-provisioning/src/general/files/aws/dataengine_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/aws/dataengine_Dockerfile
@@ -36,6 +36,8 @@
COPY general/templates/os/notebook_spark-defaults_local.conf /root/templates/
COPY general/templates/os/tensorboard.service /root/templates/
COPY general/templates/os/${OS}/spark-* /root/templates/
+COPY general/templates/os/${OS}/livy.service /root/templates/
+COPY general/templates/os/livy-env.sh /root/templates/
RUN chmod a+x /root/fabfile.py; \
chmod a+x /root/scripts/*
diff --git a/infrastructure-provisioning/src/general/files/aws/deeplearning_Dockerfile b/infrastructure-provisioning/src/general/files/aws/deeplearning_Dockerfile
index e460e39..587a1b6 100644
--- a/infrastructure-provisioning/src/general/files/aws/deeplearning_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/aws/deeplearning_Dockerfile
@@ -40,8 +40,9 @@
COPY general/templates/os/inactive.sh /root/templates/
COPY general/templates/os/inactive.service /root/templates/
COPY general/templates/os/inactive.timer /root/templates/
-COPY general/files/os/toree-assembly-0.2.0.jar /root/files/
+COPY general/files/os/toree-assembly-0.3.0.jar /root/files/
COPY general/files/os/toree_kernel.tar.gz /root/files/
+COPY general/templates/os/sparkmagic_config_template.json /root/templates/
COPY general/templates/os/pyspark_dataengine-service_template.json /root/templates/
COPY general/templates/os/r_dataengine-service_template.json /root/templates/
COPY general/templates/os/toree_dataengine-service_* /root/templates/
diff --git a/infrastructure-provisioning/src/general/files/aws/jupyter_Dockerfile b/infrastructure-provisioning/src/general/files/aws/jupyter_Dockerfile
index 1f401fc..a2d6198 100644
--- a/infrastructure-provisioning/src/general/files/aws/jupyter_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/aws/jupyter_Dockerfile
@@ -35,13 +35,14 @@
COPY general/templates/os/py3spark_local_template.json /root/templates/
COPY general/templates/os/pyspark_dataengine-service_template.json /root/templates/
COPY general/templates/os/r_dataengine-service_template.json /root/templates/
+COPY general/templates/os/sparkmagic_config_template.json /root/templates/
COPY general/templates/os/r_template.json /root/templates/
COPY general/templates/os/run_template.sh /root/templates/
COPY general/templates/os/toree_dataengine-service_* /root/templates/
COPY general/templates/os/inactive.sh /root/templates/
COPY general/templates/os/inactive.service /root/templates/
COPY general/templates/os/inactive.timer /root/templates/
-COPY general/files/os/toree-assembly-0.2.0.jar /root/files/
+COPY general/files/os/toree-assembly-0.3.0.jar /root/files/
COPY general/files/os/toree_kernel.tar.gz /root/files/
COPY general/templates/os/pyspark_dataengine_template.json /root/templates/
COPY general/templates/os/r_dataengine_template.json /root/templates/
diff --git a/infrastructure-provisioning/src/general/files/aws/jupyterlab_Dockerfile b/infrastructure-provisioning/src/general/files/aws/jupyterlab_Dockerfile
index 203809c..592955e 100644
--- a/infrastructure-provisioning/src/general/files/aws/jupyterlab_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/aws/jupyterlab_Dockerfile
@@ -37,7 +37,7 @@
COPY general/templates/os/r_template.json /root/templates/
COPY general/templates/os/run_template.sh /root/templates/
COPY general/templates/os/toree_dataengine-service_* /root/templates/
-COPY general/files/os/toree-assembly-0.2.0.jar /root/files/
+COPY general/files/os/toree-assembly-0.3.0.jar /root/files/
COPY general/files/os/toree_kernel.tar.gz /root/files/
COPY general/templates/os/pyspark_dataengine_template.json /root/templates/
COPY general/templates/os/r_dataengine_template.json /root/templates/
diff --git a/infrastructure-provisioning/src/general/files/azure/base_Dockerfile b/infrastructure-provisioning/src/general/files/azure/base_Dockerfile
index dcf939e..883225d 100644
--- a/infrastructure-provisioning/src/general/files/azure/base_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/azure/base_Dockerfile
@@ -19,7 +19,7 @@
#
# ******************************************************************************
-FROM ubuntu:16.04
+FROM ubuntu:18.04
ARG OS
ARG SRC_PATH
@@ -30,7 +30,7 @@
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Install any python dependencies
-RUN pip install -UI pip==9.0.3 && \
+RUN pip install -UI pip==20.1 && \
pip install backoff fabric==1.14.0 fabvenv argparse requests ujson jupyter pycrypto azure==2.0.0 azure-mgmt-authorization pyyaml
# Configuring ssh for user
diff --git a/infrastructure-provisioning/src/general/files/azure/dataengine_Dockerfile b/infrastructure-provisioning/src/general/files/azure/dataengine_Dockerfile
index 8e394cc..daefa72 100644
--- a/infrastructure-provisioning/src/general/files/azure/dataengine_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/azure/dataengine_Dockerfile
@@ -37,6 +37,8 @@
COPY general/templates/os/tensorboard.service /root/templates/
COPY general/templates/azure/core-site* /root/templates/
COPY general/templates/os/${OS}/spark-* /root/templates/
+COPY general/templates/os/${OS}/livy.service /root/templates/
+COPY general/templates/os/livy-env.sh /root/templates/
RUN chmod a+x /root/fabfile.py; \
chmod a+x /root/scripts/*
diff --git a/infrastructure-provisioning/src/general/files/azure/deeplearning_Dockerfile b/infrastructure-provisioning/src/general/files/azure/deeplearning_Dockerfile
index 220086e..d072a63 100644
--- a/infrastructure-provisioning/src/general/files/azure/deeplearning_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/azure/deeplearning_Dockerfile
@@ -40,7 +40,7 @@
COPY general/templates/os/inactive.sh /root/templates/
COPY general/templates/os/inactive.service /root/templates/
COPY general/templates/os/inactive.timer /root/templates/
-COPY general/files/os/toree-assembly-0.2.0.jar /root/files/
+COPY general/files/os/toree-assembly-0.3.0.jar /root/files/
COPY general/files/os/toree_kernel.tar.gz /root/files/
COPY general/templates/azure/core-site* /root/templates/
diff --git a/infrastructure-provisioning/src/general/files/azure/jupyter_Dockerfile b/infrastructure-provisioning/src/general/files/azure/jupyter_Dockerfile
index acbb7a8..8a39401 100644
--- a/infrastructure-provisioning/src/general/files/azure/jupyter_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/azure/jupyter_Dockerfile
@@ -35,7 +35,7 @@
COPY general/templates/os/py3spark_local_template.json /root/templates/
COPY general/templates/os/r_template.json /root/templates/
COPY general/templates/os/run_template.sh /root/templates/
-COPY general/files/os/toree-assembly-0.2.0.jar /root/files/
+COPY general/files/os/toree-assembly-0.3.0.jar /root/files/
COPY general/files/os/toree_kernel.tar.gz /root/files/
COPY general/templates/os/pyspark_dataengine_template.json /root/templates/
COPY general/templates/os/r_dataengine_template.json /root/templates/
diff --git a/infrastructure-provisioning/src/general/files/azure/jupyterlab_Dockerfile b/infrastructure-provisioning/src/general/files/azure/jupyterlab_Dockerfile
index 97739c1..0ff6810 100644
--- a/infrastructure-provisioning/src/general/files/azure/jupyterlab_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/azure/jupyterlab_Dockerfile
@@ -35,7 +35,7 @@
COPY general/templates/os/py3spark_local_template.json /root/templates/
COPY general/templates/os/r_template.json /root/templates/
COPY general/templates/os/run_template.sh /root/templates/
-COPY general/files/os/toree-assembly-0.2.0.jar /root/files/
+COPY general/files/os/toree-assembly-0.3.0.jar /root/files/
COPY general/files/os/toree_kernel.tar.gz /root/files/
COPY general/templates/os/pyspark_dataengine_template.json /root/templates/
COPY general/templates/os/r_dataengine_template.json /root/templates/
diff --git a/infrastructure-provisioning/src/general/files/gcp/base_Dockerfile b/infrastructure-provisioning/src/general/files/gcp/base_Dockerfile
index 8a66b82..d8f6447 100644
--- a/infrastructure-provisioning/src/general/files/gcp/base_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/gcp/base_Dockerfile
@@ -19,7 +19,7 @@
#
# ******************************************************************************
-FROM ubuntu:16.04
+FROM ubuntu:18.04
ARG OS
ARG SRC_PATH
@@ -30,7 +30,7 @@
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
# Install any python dependencies
-RUN pip install -UI pip==9.0.3 && \
+RUN pip install -UI pip==20.1 && \
pip install boto3 backoff fabric==1.14.0 fabvenv argparse ujson jupyter pycrypto google-api-python-client google-cloud-storage \
pyyaml google-auth-httplib2 oauth2client
diff --git a/infrastructure-provisioning/src/general/files/gcp/dataengine-service_description.json b/infrastructure-provisioning/src/general/files/gcp/dataengine-service_description.json
index 1bf4fb6..789ac05 100644
--- a/infrastructure-provisioning/src/general/files/gcp/dataengine-service_description.json
+++ b/infrastructure-provisioning/src/general/files/gcp/dataengine-service_description.json
@@ -25,7 +25,6 @@
},
"templates":
[
- {"version":"1.3", "applications": [{"Name":"Hadoop", "Version": "2.9.2"}, {"Name":"Spark", "Version": "2.3.2"}, {"Name":"Hive", "Version": "2.3.4"}]},
- {"version":"1.4", "applications": [{"Name":"Hadoop", "Version": "2.9.2"}, {"Name":"Spark", "Version": "2.4.4"}, {"Name":"Hive", "Version": "2.3.6"}]}
+ {"version":"1.4", "applications": [{"Name":"Hadoop", "Version": "2.10.0"}, {"Name":"Spark", "Version": "2.4.5"}, {"Name":"Hive", "Version": "2.3.6"}]}
]
}
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/files/gcp/dataengine_Dockerfile b/infrastructure-provisioning/src/general/files/gcp/dataengine_Dockerfile
index 0f4f14a..139e565 100644
--- a/infrastructure-provisioning/src/general/files/gcp/dataengine_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/gcp/dataengine_Dockerfile
@@ -37,6 +37,8 @@
COPY general/templates/os/tensorboard.service /root/templates/
COPY general/templates/gcp/core-site.xml /root/templates/
COPY general/templates/os/${OS}/spark-* /root/templates/
+COPY general/templates/os/${OS}/livy.service /root/templates/
+COPY general/templates/os/livy-env.sh /root/templates/
RUN chmod a+x /root/fabfile.py; \
chmod a+x /root/scripts/*
diff --git a/infrastructure-provisioning/src/general/files/gcp/deeplearning_Dockerfile b/infrastructure-provisioning/src/general/files/gcp/deeplearning_Dockerfile
index 0a3ad63..2aa2ca4 100644
--- a/infrastructure-provisioning/src/general/files/gcp/deeplearning_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/gcp/deeplearning_Dockerfile
@@ -40,7 +40,7 @@
COPY general/templates/os/inactive.sh /root/templates/
COPY general/templates/os/inactive.service /root/templates/
COPY general/templates/os/inactive.timer /root/templates/
-COPY general/files/os/toree-assembly-0.2.0.jar /root/files/
+COPY general/files/os/toree-assembly-0.3.0.jar /root/files/
COPY general/files/os/toree_kernel.tar.gz /root/files/
COPY general/templates/os/pyspark_dataengine-service_template.json /root/templates/
COPY general/templates/os/r_dataengine-service_template.json /root/templates/
diff --git a/infrastructure-provisioning/src/general/files/gcp/jupyter_Dockerfile b/infrastructure-provisioning/src/general/files/gcp/jupyter_Dockerfile
index 8e5dabd..bd4b1bd 100644
--- a/infrastructure-provisioning/src/general/files/gcp/jupyter_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/gcp/jupyter_Dockerfile
@@ -34,6 +34,7 @@
COPY general/templates/os/pyspark_local_template.json /root/templates/
COPY general/templates/os/py3spark_local_template.json /root/templates/
COPY general/templates/os/pyspark_dataengine-service_template.json /root/templates/
+COPY general/templates/os/sparkmagic_config_template.json /root/templates/
COPY general/templates/os/r_dataengine-service_template.json /root/templates/
COPY general/templates/os/r_template.json /root/templates/
COPY general/templates/os/run_template.sh /root/templates/
@@ -41,7 +42,7 @@
COPY general/templates/os/inactive.sh /root/templates/
COPY general/templates/os/inactive.service /root/templates/
COPY general/templates/os/inactive.timer /root/templates/
-COPY general/files/os/toree-assembly-0.2.0.jar /root/files/
+COPY general/files/os/toree-assembly-0.3.0.jar /root/files/
COPY general/files/os/toree_kernel.tar.gz /root/files/
COPY general/templates/os/pyspark_dataengine_template.json /root/templates/
COPY general/templates/os/r_dataengine_template.json /root/templates/
diff --git a/infrastructure-provisioning/src/general/files/gcp/jupyterlab_Dockerfile b/infrastructure-provisioning/src/general/files/gcp/jupyterlab_Dockerfile
index 4d68e2f..9c30f94 100644
--- a/infrastructure-provisioning/src/general/files/gcp/jupyterlab_Dockerfile
+++ b/infrastructure-provisioning/src/general/files/gcp/jupyterlab_Dockerfile
@@ -37,7 +37,7 @@
COPY general/templates/os/r_template.json /root/templates/
COPY general/templates/os/run_template.sh /root/templates/
COPY general/templates/os/toree_dataengine-service_* /root/templates/
-COPY general/files/os/toree-assembly-0.2.0.jar /root/files/
+COPY general/files/os/toree-assembly-0.3.0.jar /root/files/
COPY general/files/os/toree_kernel.tar.gz /root/files/
COPY general/templates/os/pyspark_dataengine_template.json /root/templates/
COPY general/templates/os/r_dataengine_template.json /root/templates/
diff --git a/infrastructure-provisioning/src/general/files/gcp/ssn_policy.json b/infrastructure-provisioning/src/general/files/gcp/ssn_policy.json
index bd95d12..4f0ad6a 100644
--- a/infrastructure-provisioning/src/general/files/gcp/ssn_policy.json
+++ b/infrastructure-provisioning/src/general/files/gcp/ssn_policy.json
@@ -16,5 +16,7 @@
"compute.images.get",
"compute.images.delete",
"compute.images.setLabels",
- "compute.images.list"
+ "compute.images.list",
+ "compute.routes.create",
+ "compute.routes.get"
]
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/lib/aws/actions_lib.py b/infrastructure-provisioning/src/general/lib/aws/actions_lib.py
index 9519053..8b9ffab 100644
--- a/infrastructure-provisioning/src/general/lib/aws/actions_lib.py
+++ b/infrastructure-provisioning/src/general/lib/aws/actions_lib.py
@@ -224,6 +224,24 @@
"error_message": str(err) + "\n Traceback: " + traceback.print_exc(file=sys.stdout)}))
traceback.print_exc(file=sys.stdout)
+def create_nat_rt(vpc_id, infra_tag_value, edge_instance_id, private_subnet_id):
+ try:
+ ec2 = boto3.client('ec2')
+ nat_rt = ec2.create_route_table(VpcId=vpc_id)
+ nat_rt_id = nat_rt.get('RouteTable').get('RouteTableId')
+ tag = {"Key": 'Name', "Value": infra_tag_value}
+ create_tag(nat_rt_id, json.dumps(tag))
+ ec2 = boto3.resource('ec2')
+ route_table = ec2.RouteTable(nat_rt_id)
+ route_table.create_route(DestinationCidrBlock='0.0.0.0/0', InstanceId=edge_instance_id)
+ route_table.associate_with_subnet(SubnetId=private_subnet_id)
+ except Exception as err:
+ logging.info(
+ "Unable to create Route Table: " + str(err) + "\n Traceback: " + traceback.print_exc(file=sys.stdout))
+ append_result(str({"error": "Unable to create Route Table",
+ "error_message": str(err) + "\n Traceback: " + traceback.print_exc(file=sys.stdout)}))
+ traceback.print_exc(file=sys.stdout)
+
def create_subnet(vpc_id, subnet, tag, zone):
try:
@@ -474,6 +492,15 @@
"error_message": str(err) + "\n Traceback: " + traceback.print_exc(file=sys.stdout)}))
traceback.print_exc(file=sys.stdout)
+def modify_instance_sourcedescheck(instance_id):
+ try:
+ ec2 = boto3.client('ec2')
+ ec2.modify_instance_attribute(InstanceId=instance_id, SourceDestCheck={'Value': False})
+ except Exception as err:
+ logging.info("Unable to modify EC2: " + str(err) + "\n Traceback: " + traceback.print_exc(file=sys.stdout))
+ append_result(str({"error": "Unable to modify EC2",
+ "error_message": str(err) + "\n Traceback: " + traceback.print_exc(file=sys.stdout)}))
+ traceback.print_exc(file=sys.stdout)
def tag_intance_volume(instance_id, node_name, instance_tag):
try:
@@ -1620,6 +1647,10 @@
endpoint_url))
sudo('echo "spark.hadoop.fs.s3a.server-side-encryption-algorithm AES256" >> '
'/tmp/notebook_spark-defaults_local.conf')
+ if not exists('/opt/spark/conf/spark-env.sh'):
+ sudo('mv /opt/spark/conf/spark-env.sh.template /opt/spark/conf/spark-env.sh')
+ java_home = run("update-alternatives --query java | grep -o \'/.*/java-8.*/jre\'").splitlines()[0]
+ sudo("echo 'export JAVA_HOME=\'{}\'' >> /opt/spark/conf/spark-env.sh".format(java_home))
if os.environ['application'] == 'zeppelin':
sudo('echo \"spark.jars $(ls -1 ' + jars_dir + '* | tr \'\\n\' \',\')\" >> '
'/tmp/notebook_spark-defaults_local.conf')
diff --git a/infrastructure-provisioning/src/general/lib/azure/actions_lib.py b/infrastructure-provisioning/src/general/lib/azure/actions_lib.py
index 8cac3c4..761be9c 100644
--- a/infrastructure-provisioning/src/general/lib/azure/actions_lib.py
+++ b/infrastructure-provisioning/src/general/lib/azure/actions_lib.py
@@ -1126,6 +1126,10 @@
sudo('sed -i "/spark.*.memory/d" /opt/spark/conf/spark-defaults.conf')
sudo('echo "spark.{0}.memory {1}m" >> /opt/spark/conf/spark-defaults.conf'.format(memory_type,
spark_memory))
+ if not exists('/opt/spark/conf/spark-env.sh'):
+ sudo('mv /opt/spark/conf/spark-env.sh.template /opt/spark/conf/spark-env.sh')
+ java_home = run("update-alternatives --query java | grep -o \'/.*/java-8.*/jre\'").splitlines()[0]
+ sudo("echo 'export JAVA_HOME=\'{}\'' >> /opt/spark/conf/spark-env.sh".format(java_home))
if 'spark_configurations' in os.environ:
dlab_header = sudo('cat /tmp/notebook_spark-defaults_local.conf | grep "^#"')
spark_configurations = ast.literal_eval(os.environ['spark_configurations'])
diff --git a/infrastructure-provisioning/src/general/lib/gcp/actions_lib.py b/infrastructure-provisioning/src/general/lib/gcp/actions_lib.py
index b1d0acb..e550d9d 100644
--- a/infrastructure-provisioning/src/general/lib/gcp/actions_lib.py
+++ b/infrastructure-provisioning/src/general/lib/gcp/actions_lib.py
@@ -177,6 +177,37 @@
file=sys.stdout)}))
traceback.print_exc(file=sys.stdout)
+ def create_nat_route(self, nat_route_params):
+ request = self.service.routes().insert(project=self.project, body=nat_route_params)
+ try:
+ result = request.execute()
+ meta_lib.GCPMeta().wait_for_operation(result['name'])
+ print('NAT route {} created.'.format(nat_route_params['name']))
+ return result
+ except Exception as err:
+ logging.info(
+ "Unable to create NAT route: " + str(err) + "\n Traceback: " + traceback.print_exc(file=sys.stdout))
+ append_result(str({"error": "Unable to create NAT route",
+ "error_message": str(err) + "\n Traceback: " + traceback.print_exc(
+ file=sys.stdout)}))
+ traceback.print_exc(file=sys.stdout)
+
+ def delete_nat_route(self, nat_route_name):
+ request = self.service.routes().delete(project=self.project, route=nat_route_name)
+ try:
+ result = request.execute()
+ meta_lib.GCPMeta().wait_for_operation(result['name'])
+ print('NAT route {} deleteed.'.format(nat_route_name))
+ return result
+ except Exception as err:
+ logging.info(
+ "Unable to delete NAT route: " + str(err) + "\n Traceback: " + traceback.print_exc(file=sys.stdout))
+ append_result(str({"error": "Unable to delete NAT route",
+ "error_message": str(err) + "\n Traceback: " + traceback.print_exc(
+ file=sys.stdout)}))
+ traceback.print_exc(file=sys.stdout)
+
+
def create_bucket(self, bucket_name):
try:
bucket = self.storage_client.create_bucket(bucket_name)
@@ -1377,6 +1408,10 @@
sudo('sed -i "/spark.*.memory/d" /opt/spark/conf/spark-defaults.conf')
sudo('echo "spark.{0}.memory {1}m" >> /opt/spark/conf/spark-defaults.conf'.format(memory_type,
spark_memory))
+ if not exists('/opt/spark/conf/spark-env.sh'):
+ sudo('mv /opt/spark/conf/spark-env.sh.template /opt/spark/conf/spark-env.sh')
+ java_home = run("update-alternatives --query java | grep -o \'/.*/java-8.*/jre\'").splitlines()[0]
+ sudo("echo 'export JAVA_HOME=\'{}\'' >> /opt/spark/conf/spark-env.sh".format(java_home))
if 'spark_configurations' in os.environ:
dlab_header = sudo('cat /tmp/notebook_spark-defaults_local.conf | grep "^#"')
spark_configurations = ast.literal_eval(os.environ['spark_configurations'])
diff --git a/infrastructure-provisioning/src/general/lib/gcp/meta_lib.py b/infrastructure-provisioning/src/general/lib/gcp/meta_lib.py
index cc16028..6b7582b 100644
--- a/infrastructure-provisioning/src/general/lib/gcp/meta_lib.py
+++ b/infrastructure-provisioning/src/general/lib/gcp/meta_lib.py
@@ -157,6 +157,25 @@
file=sys.stdout)}))
traceback.print_exc(file=sys.stdout)
+ def get_route(self, route_name):
+ request = self.service.routes().get(
+ project=self.project,
+ route=route_name)
+ try:
+ return request.execute()
+ except errors.HttpError as err:
+ if err.resp.status == 404:
+ return ''
+ else:
+ raise err
+ except Exception as err:
+ logging.info(
+ "Unable to get Route: " + str(err) + "\n Traceback: " + traceback.print_exc(file=sys.stdout))
+ append_result(str({"error": "Unable to get Route",
+ "error_message": str(err) + "\n Traceback: " + traceback.print_exc(
+ file=sys.stdout)}))
+ traceback.print_exc(file=sys.stdout)
+
def get_bucket(self, bucket_name):
try:
bucket = self.storage_client.get_bucket(bucket_name)
diff --git a/infrastructure-provisioning/src/general/lib/os/debian/common_lib.py b/infrastructure-provisioning/src/general/lib/os/debian/common_lib.py
index 5e44166..296d9ab 100644
--- a/infrastructure-provisioning/src/general/lib/os/debian/common_lib.py
+++ b/infrastructure-provisioning/src/general/lib/os/debian/common_lib.py
@@ -28,51 +28,47 @@
import time
-def manage_pkg(command, environment, requisites):
+def manage_pkg(command, environment, requisites, warn='False'):
try:
- attempt = 0
- installed = False
- while not installed:
- print('Pkg installation attempt: {}'.format(attempt))
- if attempt > 60:
+ allow = False
+ counter = 0
+ while not allow:
+ if counter > 60:
print("Notebook is broken please recreate it.")
sys.exit(1)
else:
- try:
- allow = False
- counter = 0
- while not allow:
- if counter > 60:
- print("Notebook is broken please recreate it.")
- sys.exit(1)
- else:
- print('Package manager is:')
- if environment == 'remote':
- if sudo('pgrep "^apt" -a && echo "busy" || echo "ready"') == 'busy':
- counter += 1
- time.sleep(10)
- else:
- allow = True
- sudo('apt-get {0} {1}'.format(command, requisites))
- elif environment == 'local':
- if local('sudo pgrep "^apt" -a && echo "busy" || echo "ready"', capture=True) == 'busy':
- counter += 1
- time.sleep(10)
- else:
- allow = True
- local('sudo apt-get {0} {1}'.format(command, requisites), capture=True)
- else:
- print('Wrong environment')
- installed = True
- except:
- print("Will try to install with nex attempt.")
- sudo('dpkg --configure -a')
- attempt += 1
+ print('Package manager is:')
+ if environment == 'remote':
+ if sudo('pgrep "^apt" -a && echo "busy" || echo "ready"') == 'busy':
+ counter += 1
+ time.sleep(10)
+ else:
+ allow = True
+ sudo('sudo dpkg --configure -a')
+ sudo('sudo apt update')
+ try:
+ sudo('apt-get {0} {1}'.format(command, requisites), warn_only=warn)
+ except:
+ sudo('lsof /var/lib/dpkg/lock')
+ sudo('lsof /var/lib/apt/lists/lock')
+ sudo('lsof /var/cache/apt/archives/lock')
+ sudo('rm -f /var/lib/apt/lists/lock')
+ sudo('rm -f /var/cache/apt/archives/lock')
+ sudo('rm -f /var/lib/dpkg/lock')
+ elif environment == 'local':
+ if local('sudo pgrep "^apt" -a && echo "busy" || echo "ready"', capture=True) == 'busy':
+ counter += 1
+ time.sleep(10)
+ else:
+ allow = True
+ local('sudo apt-get {0} {1}'.format(command, requisites), capture=True)
+ else:
+ print('Wrong environment')
except:
sys.exit(1)
def ensure_pkg(user, requisites='linux-headers-generic python-pip python-dev '
- 'groff gcc vim less git wget sysv-rc-conf '
+ 'groff gcc vim less git wget '
'libssl-dev unattended-upgrades nmap '
'libffi-dev unzip libxml2-dev haveged'):
try:
@@ -109,7 +105,8 @@
def renew_gpg_key():
try:
- sudo('mv /etc/apt/trusted.gpg /etc/apt/trusted.bkp')
+# if exists('/etc/apt/trusted.gpg'):
+# sudo('mv /etc/apt/trusted.gpg /etc/apt/trusted.bkp')
sudo('apt-key update')
except:
sys.exit(1)
diff --git a/infrastructure-provisioning/src/general/lib/os/debian/edge_lib.py b/infrastructure-provisioning/src/general/lib/os/debian/edge_lib.py
index 57940db..836fd64 100644
--- a/infrastructure-provisioning/src/general/lib/os/debian/edge_lib.py
+++ b/infrastructure-provisioning/src/general/lib/os/debian/edge_lib.py
@@ -54,8 +54,7 @@
for cidr in config['allowed_ip_cidr']:
replace_string += 'acl AllowedCIDRS src {}\\n'.format(cidr)
sudo('sed -i "s|ALLOWED_CIDRS|{}|g" /etc/squid/squid.conf'.format(replace_string))
- sudo('service squid reload')
- sudo('sysv-rc-conf squid on')
+ sudo('systemctl restart squid')
sudo('touch /tmp/http_proxy_ensured')
except Exception as err:
print("Failed to install and configure squid: " + str(err))
@@ -66,8 +65,12 @@
keycloak_client_secret, user, hostname, step_cert_sans):
try:
if not os.path.exists('/tmp/nginx_installed'):
- manage_pkg('-y install', 'remote', 'wget')
- manage_pkg('-y install', 'remote', 'gcc build-essential make automake zlib1g-dev libpcre++-dev libssl-dev git libldap2-dev libc6-dev libgd-dev libgeoip-dev libpcre3-dev apt-utils autoconf liblmdb-dev libtool libxml2-dev libyajl-dev pkgconf liblua5.1-0 liblua5.1-0-dev libreadline-dev libreadline6-dev libtinfo-dev libtool-bin lua5.1 zip readline-doc')
+ manage_pkg('-y install', 'remote',
+ 'gcc build-essential make automake zlib1g-dev libpcre++-dev libssl-dev git libldap2-dev '
+ 'libc6-dev libgd-dev libgeoip-dev libpcre3-dev apt-utils autoconf liblmdb-dev libtool '
+ 'libxml2-dev libyajl-dev pkgconf libreadline-dev libreadline6-dev libtinfo-dev '
+ 'libtool-bin zip readline-doc perl curl liblua5.1-0 liblua5.1-0-dev lua5.1')
+ manage_pkg('-y install --no-install-recommends', 'remote', 'wget gnupg ca-certificates')
if os.environ['conf_stepcerts_enabled'] == 'true':
sudo('mkdir -p /home/{0}/keys'.format(user))
sudo('''bash -c 'echo "{0}" | base64 --decode > /etc/ssl/certs/root_ca.crt' '''.format(
@@ -111,66 +114,26 @@
else:
sudo('openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /etc/ssl/certs/dlab.key \
-out /etc/ssl/certs/dlab.crt -subj "/C=US/ST=US/L=US/O=dlab/CN={}"'.format(hostname))
- sudo('mkdir -p /tmp/lua')
+
sudo('mkdir -p /tmp/src')
with cd('/tmp/src/'):
- sudo('wget http://nginx.org/download/nginx-{}.tar.gz'.format(nginx_version))
- sudo('tar -xzf nginx-{}.tar.gz'.format(nginx_version))
+ sudo('wget https://luarocks.org/releases/luarocks-3.3.1.tar.gz')
+ sudo('tar -xzf luarocks-3.3.1.tar.gz')
- sudo('wget https://github.com/openresty/lua-nginx-module/archive/v0.10.15.tar.gz')
- sudo('tar -xzf v0.10.15.tar.gz')
+ sudo('wget -O - https://openresty.org/package/pubkey.gpg | sudo apt-key add -')
+ sudo('add-apt-repository -y "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main"')
+ sudo('apt-get update')
+ sudo('apt-get -y install openresty=1.15.8.1-1~bionic1')
- sudo('wget https://github.com/simplresty/ngx_devel_kit/archive/v0.3.1.tar.gz')
- sudo('tar -xzf v0.3.1.tar.gz')
-
- sudo('wget http://luajit.org/download/LuaJIT-2.0.5.tar.gz')
- sudo('tar -xzf LuaJIT-2.0.5.tar.gz')
-
- sudo('wget http://keplerproject.github.io/luarocks/releases/luarocks-2.2.2.tar.gz')
- sudo('tar -xzf luarocks-2.2.2.tar.gz')
-
- sudo('ln -sf nginx-{} nginx'.format(nginx_version))
-
- with cd('/tmp/src/LuaJIT-2.0.5/'):
- sudo('make')
- sudo('make install')
-
- with cd('/tmp/src/nginx/'), shell_env(LUAJIT_LIB='/usr/local/lib/', LUAJIT_INC='/usr/local/include/luajit-2.0'):
- sudo('./configure --user=nginx --group=nginx --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx \
- --conf-path=/etc/nginx/nginx.conf --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx \
- --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log \
- --with-http_gzip_static_module --with-http_stub_status_module --with-http_ssl_module --with-pcre \
- --with-http_realip_module --with-file-aio --with-ipv6 --with-http_v2_module --with-ld-opt="-Wl,-rpath,$LUAJIT_LIB" \
- --without-http_scgi_module --without-http_uwsgi_module --without-http_fastcgi_module --with-http_sub_module \
- --add-dynamic-module=/tmp/src/ngx_devel_kit-0.3.1 --add-dynamic-module=/tmp/src/lua-nginx-module-0.10.15')
- sudo('make')
- sudo('make install')
-
- with cd('/tmp/src/luarocks-2.2.2/'):
+ with cd('/tmp/src/luarocks-3.3.1/'):
sudo('./configure')
- sudo('make build')
sudo('make install')
- sudo('wget https://luarocks.org/manifests/cdbattags/lua-resty-jwt-0.2.0-0.src.rock')
- sudo('luarocks build lua-resty-jwt-0.2.0-0.src.rock')
- sudo('wget https://luarocks.org/manifests/bungle/lua-resty-session-2.26-1.src.rock')
- sudo('luarocks build lua-resty-session-2.26-1.src.rock')
- sudo('wget https://luarocks.org/manifests/pintsized/lua-resty-http-0.15-0.src.rock')
- sudo('luarocks build lua-resty-http-0.15-0.src.rock')
- sudo('wget https://luarocks.org/manifests/hanszandbelt/lua-resty-openidc-1.7.2-1.src.rock')
- sudo('luarocks build lua-resty-openidc-1.7.2-1.src.rock')
- sudo('wget https://luarocks.org/manifests/starius/luacrypto-0.3.2-2.src.rock')
- sudo('luarocks build luacrypto-0.3.2-2.src.rock')
- sudo('wget https://luarocks.org/manifests/openresty/lua-cjson-2.1.0.6-1.src.rock')
- sudo('luarocks build lua-cjson-2.1.0.6-1.src.rock')
- sudo('wget https://luarocks.org/manifests/avlubimov/lua-resty-core-0.1.17-4.src.rock')
- sudo('luarocks build lua-resty-core-0.1.17-4.src.rock')
- sudo('wget https://luarocks.org/manifests/hjpotter92/random-1.1-0.rockspec')
- sudo('luarocks install random-1.1-0.rockspec')
- sudo('wget https://luarocks.org/manifests/rsander/lua-resty-string-0.09-0.rockspec')
- sudo('luarocks install lua-resty-string-0.09-0.rockspec')
+ sudo('luarocks install lua-resty-openidc --tree /usr/local/openresty/lualib/resty/')
+
+ sudo('luarocks install lua-resty-openidc')
sudo('useradd -r nginx')
- sudo('rm -f /etc/nginx/nginx.conf')
+
sudo('mkdir -p /opt/dlab/templates')
put('/root/templates', '/opt/dlab', use_sudo=True)
sudo('sed -i \'s/EDGE_IP/{}/g\' /opt/dlab/templates/conf.d/proxy.conf'.format(edge_ip))
@@ -183,15 +146,11 @@
sudo('sed -i \'s/KEYCLOAK_CLIENT_SECRET/{}/g\' /opt/dlab/templates/conf.d/proxy.conf'.format(
keycloak_client_secret))
- sudo('cp /opt/dlab/templates/nginx.conf /etc/nginx/')
- sudo('mkdir /etc/nginx/conf.d')
- sudo('cp /opt/dlab/templates/conf.d/proxy.conf /etc/nginx/conf.d/')
- sudo('mkdir /etc/nginx/locations')
- sudo('cp /opt/dlab/templates/nginx_debian /etc/init.d/nginx')
- sudo('chmod +x /etc/init.d/nginx')
- sudo('systemctl daemon-reload')
- sudo('systemctl enable nginx')
- sudo('/etc/init.d/nginx start')
+ sudo('cp /opt/dlab/templates/nginx.conf /usr/local/openresty/nginx/conf')
+ sudo('mkdir /usr/local/openresty/nginx/conf/conf.d')
+ sudo('cp /opt/dlab/templates/conf.d/proxy.conf /usr/local/openresty/nginx/conf/conf.d/')
+ sudo('mkdir /usr/local/openresty/nginx/conf/locations')
+ sudo('systemctl start openresty')
sudo('touch /tmp/nginx_installed')
if os.environ['conf_letsencrypt_enabled'] == 'true':
print("Configuring letsencrypt certificates.")
@@ -203,4 +162,26 @@
configure_nginx_LE(os.environ['conf_letsencrypt_domain_name'], os.environ['project_name'])
except Exception as err:
print("Failed install nginx with ldap: " + str(err))
+ sys.exit(1)
+
+def configure_nftables(config):
+ try:
+ if not exists('/tmp/nftables_ensured'):
+ manage_pkg('-y install', 'remote', 'nftables')
+ sudo('systemctl enable nftables.service')
+ sudo('systemctl start nftables')
+ sudo('sysctl net.ipv4.ip_forward=1')
+ if os.environ['conf_cloud_provider'] == 'aws':
+ interface = 'eth0'
+ elif os.environ['conf_cloud_provider'] == 'gcp':
+ interface = 'ens4'
+ sudo('sed -i \'s/#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/g\' /etc/sysctl.conf')
+ sudo('sed -i \'s/EDGE_IP/{}/g\' /opt/dlab/templates/nftables.conf'.format(config['edge_ip']))
+ sudo('sed -i "s|INTERFACE|{}|g" /opt/dlab/templates/nftables.conf'.format(interface))
+ sudo('sed -i "s|SUBNET_CIDR|{}|g" /opt/dlab/templates/nftables.conf'.format(config['exploratory_subnet']))
+ sudo('cp /opt/dlab/templates/nftables.conf /etc/')
+ sudo('systemctl restart nftables')
+ sudo('touch /tmp/nftables_ensured')
+ except Exception as err:
+ print("Failed to configure nftables: " + str(err))
sys.exit(1)
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/lib/os/debian/notebook_lib.py b/infrastructure-provisioning/src/general/lib/os/debian/notebook_lib.py
index 18d7f59..1ee213d 100644
--- a/infrastructure-provisioning/src/general/lib/os/debian/notebook_lib.py
+++ b/infrastructure-provisioning/src/general/lib/os/debian/notebook_lib.py
@@ -39,6 +39,7 @@
def enable_proxy(proxy_host, proxy_port):
try:
proxy_string = "http://%s:%s" % (proxy_host, proxy_port)
+ proxy_https_string = "http://%s:%s" % (proxy_host, proxy_port)
sudo('sed -i "/^export http_proxy/d" /etc/profile')
sudo('sed -i "/^export https_proxy/d" /etc/profile')
sudo('echo export http_proxy=' + proxy_string + ' >> /etc/profile')
@@ -46,6 +47,7 @@
if exists('/etc/apt/apt.conf'):
sudo("sed -i '/^Acquire::http::Proxy/d' /etc/apt/apt.conf")
sudo("echo 'Acquire::http::Proxy \"" + proxy_string + "\";' >> /etc/apt/apt.conf")
+ sudo("echo 'Acquire::http::Proxy \"" + proxy_https_string + "\";' >> /etc/apt/apt.conf")
print("Renewing gpg key")
renew_gpg_key()
@@ -118,25 +120,35 @@
sudo('gdebi -n rstudio-server-{}-amd64.deb'.format(rstudio_version))
sudo('mkdir -p /mnt/var')
sudo('chown {0}:{0} /mnt/var'.format(os_user))
+ http_proxy = run('echo $http_proxy')
+ https_proxy = run('echo $https_proxy')
sudo("sed -i '/Type=forking/a \Environment=USER=dlab-user' /etc/systemd/system/rstudio-server.service")
sudo("sed -i '/ExecStart/s|=/usr/lib/rstudio-server/bin/rserver|=/bin/bash -c \"export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/cudnn/lib64:/usr/local/cuda/lib64; /usr/lib/rstudio-server/bin/rserver --auth-none 1|g' /etc/systemd/system/rstudio-server.service")
sudo("sed -i '/ExecStart/s|$|\"|g' /etc/systemd/system/rstudio-server.service")
+ sudo(
+ 'sed -i \'/\[Service\]/a Environment=\"HTTP_PROXY={}\"\' /etc/systemd/system/rstudio-server.service'.format(
+ http_proxy))
+ sudo(
+ 'sed -i \'/\[Service\]/a Environment=\"HTTPS_PROXY={}\"\' /etc/systemd/system/rstudio-server.service'.format(
+ https_proxy))
+ java_home = run("update-alternatives --query java | grep -o \'/.*/java-8.*/jre\'").splitlines()[0]
+ sudo('sed -i \'/\[Service\]/ a\Environment=\"JAVA_HOME={}\"\' /etc/systemd/system/rstudio-server.service'.format(
+ java_home))
sudo("systemctl daemon-reload")
sudo('touch /home/{}/.Renviron'.format(os_user))
sudo('chown {0}:{0} /home/{0}/.Renviron'.format(os_user))
sudo('''echo 'SPARK_HOME="{0}"' >> /home/{1}/.Renviron'''.format(local_spark_path, os_user))
+ sudo('''echo 'JAVA_HOME="{0}"' >> /home/{1}/.Renviron'''.format(java_home, os_user))
sudo('touch /home/{}/.Rprofile'.format(os_user))
sudo('chown {0}:{0} /home/{0}/.Rprofile'.format(os_user))
sudo('''echo 'library(SparkR, lib.loc = c(file.path(Sys.getenv("SPARK_HOME"), "R", "lib")))' >> /home/{}/.Rprofile'''.format(os_user))
- http_proxy = run('echo $http_proxy')
- https_proxy = run('echo $https_proxy')
sudo('''echo 'Sys.setenv(http_proxy = \"{}\")' >> /home/{}/.Rprofile'''.format(http_proxy, os_user))
sudo('''echo 'Sys.setenv(https_proxy = \"{}\")' >> /home/{}/.Rprofile'''.format(https_proxy, os_user))
sudo('rstudio-server start')
sudo('echo "{0}:{1}" | chpasswd'.format(os_user, rstudio_pass))
- sudo("sed -i '/exit 0/d' /etc/rc.local")
- sudo('''bash -c "echo \'sed -i 's/^#SPARK_HOME/SPARK_HOME/' /home/{}/.Renviron\' >> /etc/rc.local"'''.format(os_user))
- sudo("bash -c 'echo exit 0 >> /etc/rc.local'")
+ #sudo("sed -i '/exit 0/d' /etc/rc.local")
+ #sudo('''bash -c "echo \'sed -i 's/^#SPARK_HOME/SPARK_HOME/' /home/{}/.Renviron\' >> /etc/rc.local"'''.format(os_user))
+ #sudo("bash -c 'echo exit 0 >> /etc/rc.local'")
sudo('touch /home/{}/.ensure_dir/rstudio_ensured'.format(os_user))
except:
sys.exit(1)
@@ -156,8 +168,8 @@
sudo('pip2 install matplotlib==2.0.2 --no-cache-dir')
sudo('pip3 install matplotlib==2.0.2 --no-cache-dir')
if os.environ['application'] in ('tensor', 'deeplearning'):
- sudo('python2.7 -m pip install -U numpy=={} --no-cache-dir'.format(os.environ['notebook_numpy_version']))
- sudo('python3.5 -m pip install -U numpy=={} --no-cache-dir'.format(os.environ['notebook_numpy_version']))
+ sudo('python2.7 -m pip install -U numpy=={} --no-cache-dir'.format(os.environ['notebook_numpy2_version']))
+ sudo('python3.6 -m pip install -U numpy=={} --no-cache-dir'.format(os.environ['notebook_numpy_version']))
sudo('touch /home/' + os_user + '/.ensure_dir/matplot_ensured')
except:
sys.exit(1)
@@ -165,13 +177,14 @@
@backoff.on_exception(backoff.expo, SystemExit, max_tries=10)
def add_sbt_key():
sudo(
- 'apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 642AC823')
+ 'curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | sudo apt-key add')
def ensure_sbt(os_user):
if not exists('/home/' + os_user + '/.ensure_dir/sbt_ensured'):
try:
manage_pkg('-y install', 'remote', 'apt-transport-https')
sudo('echo "deb https://dl.bintray.com/sbt/debian /" | sudo tee -a /etc/apt/sources.list.d/sbt.list')
+
add_sbt_key()
manage_pkg('update', 'remote', '')
manage_pkg('-y install', 'remote', 'sbt')
@@ -195,6 +208,8 @@
try:
manage_pkg('-y install', 'remote', 'default-jre')
manage_pkg('-y install', 'remote', 'default-jdk')
+ manage_pkg('-y install', 'remote', 'openjdk-8-jdk')
+ manage_pkg('-y install', 'remote', 'openjdk-8-jre')
sudo('touch /home/' + os_user + '/.ensure_dir/jre_jdk_ensured')
except:
sys.exit(1)
@@ -205,7 +220,7 @@
try:
manage_pkg('-y install', 'remote', 'libjpeg8-dev zlib1g-dev')
if os.environ['application'] in ('jupyter', 'zeppelin'):
- sudo('pip2 install NumPy=={} SciPy pandas Sympy Pillow sklearn --no-cache-dir'.format(os.environ['notebook_numpy_version']))
+ sudo('pip2 install NumPy=={} SciPy pandas Sympy Pillow sklearn --no-cache-dir'.format(os.environ['notebook_numpy2_version']))
sudo('pip3 install NumPy=={} SciPy pandas Sympy Pillow sklearn --no-cache-dir'.format(os.environ['notebook_numpy_version']))
if os.environ['application'] in ('tensor', 'deeplearning'):
sudo('pip2 install opencv-python h5py --no-cache-dir')
@@ -231,10 +246,10 @@
if not exists('/home/' + os_user + '/.ensure_dir/python2_libraries_ensured'):
try:
try:
- manage_pkg('-y install', 'remote', 'libssl-dev python-virtualenv')
+ manage_pkg('-y install', 'remote', 'libssl1.0-dev python-virtualenv')
except:
sudo('pip2 install virtualenv --no-cache-dir')
- manage_pkg('-y install', 'remote', 'libssl-dev')
+ manage_pkg('-y install', 'remote', 'libssl1.0-dev')
try:
sudo('pip2 install tornado=={0} ipython ipykernel=={1} --no-cache-dir' \
.format(os.environ['notebook_tornado_version'], os.environ['notebook_ipykernel_version']))
@@ -252,13 +267,15 @@
def ensure_python3_libraries(os_user):
if not exists('/home/' + os_user + '/.ensure_dir/python3_libraries_ensured'):
try:
- manage_pkg('-y install', 'remote', 'python3-setuptools')
+ #manage_pkg('-y install', 'remote', 'python3-setuptools')
manage_pkg('-y install', 'remote', 'python3-pip')
+ manage_pkg('-y install', 'remote', 'libkrb5-dev')
+ sudo('pip3 install setuptools=={}'.format(os.environ['notebook_setuptools_version']))
try:
- sudo('pip3 install tornado=={0} ipython==7.9.0 ipykernel=={1} --no-cache-dir' \
+ sudo('pip3 install tornado=={0} ipython==7.9.0 ipykernel=={1} sparkmagic --no-cache-dir' \
.format(os.environ['notebook_tornado_version'], os.environ['notebook_ipykernel_version']))
except:
- sudo('pip3 install tornado=={0} ipython==5.0.0 ipykernel=={1} --no-cache-dir' \
+ sudo('pip3 install tornado=={0} ipython==5.0.0 ipykernel=={1} sparkmagic --no-cache-dir' \
.format(os.environ['notebook_tornado_version'], os.environ['notebook_ipykernel_version']))
sudo('pip3 install -U pip=={} --no-cache-dir'.format(os.environ['conf_pip_version']))
sudo('pip3 install boto3 --no-cache-dir')
@@ -278,39 +295,53 @@
sudo('echo "options nouveau modeset=0" >> /etc/modprobe.d/blacklist-nouveau.conf')
sudo('update-initramfs -u')
with settings(warn_only=True):
- reboot(wait=150)
- manage_pkg('-y install', 'remote', 'dkms')
+ reboot(wait=180)
+ manage_pkg('-y install', 'remote', 'dkms libglvnd-dev')
kernel_version = run('uname -r | tr -d "[..0-9-]"')
if kernel_version == 'azure':
manage_pkg('-y install', 'remote', 'linux-modules-`uname -r`')
else:
- #legacy support for old kernels
- sudo('if [[ $(apt-cache search linux-image-`uname -r`) ]]; then apt-get -y install linux-image-`uname -r`; else apt-get -y install linux-modules-`uname -r`; fi;')
- sudo('wget http://us.download.nvidia.com/XFree86/Linux-x86_64/{0}/NVIDIA-Linux-x86_64-{0}.run -O /home/{1}/NVIDIA-Linux-x86_64-{0}.run'.format(nvidia_version, os_user))
+ # legacy support for old kernels
+ sudo('if [[ $(apt-cache search linux-image-`uname -r`) ]]; then apt-get -y '
+ 'install linux-image-`uname -r`; else apt-get -y install linux-modules-`uname -r`; fi;')
+ sudo('wget http://us.download.nvidia.com/tesla/{0}/NVIDIA-Linux-x86_64-{0}.run -O '
+ '/home/{1}/NVIDIA-Linux-x86_64-{0}.run'.format(nvidia_version, os_user))
sudo('/bin/bash /home/{0}/NVIDIA-Linux-x86_64-{1}.run -s --dkms'.format(os_user, nvidia_version))
sudo('rm -f /home/{0}/NVIDIA-Linux-x86_64-{1}.run'.format(os_user, nvidia_version))
# install cuda
- sudo('python3.5 -m pip install --upgrade pip=={0} wheel numpy=={1} --no-cache-dir'. format(os.environ['conf_pip_version'], os.environ['notebook_numpy_version']))
- sudo('wget -P /opt https://developer.nvidia.com/compute/cuda/{0}/prod/local_installers/{1}'.format(cuda_version, cuda_file_name))
+ sudo('python3 -m pip install --upgrade pip=={0} wheel numpy=={1} --no-cache-dir'.format(
+ os.environ['conf_pip_version'], os.environ['notebook_numpy_version']))
+ sudo('wget -P /opt http://developer.download.nvidia.com/compute/cuda/{0}/Prod/local_installers/{1}'.format(
+ cuda_version, cuda_file_name))
sudo('sh /opt/{} --silent --toolkit'.format(cuda_file_name))
sudo('mv /usr/local/cuda-{} /opt/'.format(cuda_version))
sudo('ln -s /opt/cuda-{0} /usr/local/cuda-{0}'.format(cuda_version))
sudo('rm -f /opt/{}'.format(cuda_file_name))
# install cuDNN
- run('wget http://developer.download.nvidia.com/compute/redist/cudnn/v{0}/{1} -O /tmp/{1}'.format(cudnn_version, cudnn_file_name))
+ run('wget http://developer.download.nvidia.com/compute/redist/cudnn/v{0}/{1} -O /tmp/{1}'.format(
+ cudnn_version, cudnn_file_name))
run('tar xvzf /tmp/{} -C /tmp'.format(cudnn_file_name))
sudo('mkdir -p /opt/cudnn/include')
sudo('mkdir -p /opt/cudnn/lib64')
sudo('mv /tmp/cuda/include/cudnn.h /opt/cudnn/include')
sudo('mv /tmp/cuda/lib64/libcudnn* /opt/cudnn/lib64')
sudo('chmod a+r /opt/cudnn/include/cudnn.h /opt/cudnn/lib64/libcudnn*')
- run('echo "export LD_LIBRARY_PATH=\"$LD_LIBRARY_PATH:/opt/cudnn/lib64:/usr/local/cuda/lib64\"" >> ~/.bashrc')
+ run(
+ 'echo "export LD_LIBRARY_PATH=\"$LD_LIBRARY_PATH:/opt/cudnn/lib64:/usr/local/cuda/lib64\"" >> ~/.bashrc')
# install TensorFlow and run TensorBoard
- sudo('python2.7 -m pip install --upgrade https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-{}-cp27-none-linux_x86_64.whl --no-cache-dir'.format(tensorflow_version))
- sudo('python3 -m pip install --upgrade https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-{}-cp35-cp35m-linux_x86_64.whl --no-cache-dir'.format(tensorflow_version))
+ # sudo('python2.7 -m pip install --upgrade https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-{}-cp27-none-linux_x86_64.whl --no-cache-dir'.format(tensorflow_version))
+ sudo('python3 -m pip install --upgrade '
+ 'https://storage.googleapis.com/tensorflow/linux/gpu/tensorflow_gpu-{}-cp36-cp36m-manylinux2010_x86_64.whl'
+ ' --no-cache-dir'.format(tensorflow_version))
sudo('mkdir /var/log/tensorboard; chown {0}:{0} -R /var/log/tensorboard'.format(os_user))
put('{}tensorboard.service'.format(templates_dir), '/tmp/tensorboard.service')
sudo("sed -i 's|OS_USR|{}|' /tmp/tensorboard.service".format(os_user))
+ http_proxy = run('echo $http_proxy')
+ https_proxy = run('echo $https_proxy')
+ sudo('sed -i \'/\[Service\]/ a\Environment=\"HTTP_PROXY={}\"\' /tmp/tensorboard.service'.format(
+ http_proxy))
+ sudo('sed -i \'/\[Service\]/ a\Environment=\"HTTPS_PROXY={}\"\' /tmp/tensorboard.service'.format(
+ https_proxy))
sudo("chmod 644 /tmp/tensorboard.service")
sudo('\cp /tmp/tensorboard.service /etc/systemd/system/')
sudo("systemctl daemon-reload")
@@ -358,7 +389,7 @@
def install_nodejs(os_user):
if not exists('/home/{}/.ensure_dir/nodejs_ensured'.format(os_user)):
- sudo('curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -')
+ sudo('curl -sL https://deb.nodesource.com/setup_13.x | sudo -E bash -')
manage_pkg('-y install', 'remote', 'nodejs')
sudo('touch /home/{}/.ensure_dir/nodejs_ensured'.format(os_user))
@@ -372,53 +403,57 @@
manage_pkg('update', 'remote', '')
for os_pkg in requisites:
if os_pkg[1] != '' and os_pkg[1] !='N/A':
+ version = os_pkg[1]
os_pkg = "{}={}".format(os_pkg[0], os_pkg[1])
else:
+ version = 'N/A'
os_pkg = os_pkg[0]
- sudo('DEBIAN_FRONTEND=noninteractive apt-get -y install {0} 2>&1 | tee /tmp/tee.tmp; if ! grep -w -E "({1})" /tmp/tee.tmp > '
+ sudo('DEBIAN_FRONTEND=noninteractive apt-get -y install --allow-downgrades {0} 2>&1 | tee /tmp/tee.tmp; if ! grep -w -E "({1})" /tmp/tee.tmp > '
'/tmp/os_install_{0}.log; then echo "" > /tmp/os_install_{0}.log;fi'.format(os_pkg, error_parser))
err = sudo('cat /tmp/os_install_{}.log'.format(os_pkg)).replace('"', "'")
- sudo('cat /tmp/tee.tmp | if ! grep -w -E -A 20 "({1})" /tmp/tee.tmp > '
+ sudo('cat /tmp/tee.tmp | if ! grep -w -E -A 30 "({1})" /tmp/tee.tmp > '
'/tmp/os_install_{0}.log; then echo "" > /tmp/os_install_{0}.log;fi'.format(os_pkg, new_pkgs_parser))
dep = sudo('cat /tmp/os_install_{}.log'.format(os_pkg))
- if err == '':
- dep = dep[len(new_pkgs_parser): dep.find(" upgraded, ") - 1].replace('\r', '') \
- .replace('\n', '').replace(' ', ' ').replace(' {} '.format(os_pkg.split("=")[0]), ' ').strip().split(' ')
- if dep == '' or dep == os_pkg.split("=")[0]:
- dep = []
- else:
- for n, i in enumerate(dep):
- pkg = sudo('apt list --installed 2>&1 | grep {}'.format(i))
- if pkg == '':
- pkg = sudo('apt list --installed 2>&1 | grep {}'.format(i.lower()))
- if i == os_pkg.split("=")[0]:
- dep[n] = ''
- elif "/" in pkg:
- dep[n] = '{} v.{}'.format(pkg.split('/')[0], pkg.split(' ')[1])
- dep = [i for i in dep if i]
- else:
+ if dep == '':
dep = []
- if 'E: Version' in err and 'was not found' in err:
- versions = sudo ('apt-cache policy {} | grep 500 | grep -v Packages'.format(os_pkg.split("=")[0])).replace('\r\n', '').replace(' 500', '').replace(' ', ' ').strip().split(' ')
- status_msg = 'invalid version'
else:
- versions = []
- status_msg = 'failed'
+ dep = dep[len(new_pkgs_parser): dep.find(" upgraded, ") - 1].replace('\r', '') \
+ .replace('\n', '').replace(' ', ' ').strip().split(' ')
+ for n, i in enumerate(dep):
+ if i == os_pkg.split("=")[0]:
+ dep[n] = ''
+ else:
+ sudo('apt show {0} 2>&1 | if ! grep Version: > '
+ '/tmp/os_install_{0}.log; then echo "" > /tmp/os_install_{0}.log;fi'.format(i))
+ dep[n] =sudo('cat /tmp/os_install_{}.log'.format(i)).replace('Version: ', '{} v.'.format(i))
+ dep = [i for i in dep if i]
+ versions = []
sudo('apt list --installed | if ! grep {0}/ > /tmp/os_install_{1}.list; then echo "" > /tmp/os_install_{1}.list;fi'.format(os_pkg.split("=")[0], os_pkg))
res = sudo('cat /tmp/os_install_{}.list'.format(os_pkg))
- if res:
+ if err:
+ status_msg = 'installation_error'
+ elif res:
ansi_escape = re.compile(r'\x1b[^m]*m')
ver = ansi_escape.sub('', res).split("\r\n")
version = [i for i in ver if os_pkg.split("=")[0] in i][0].split(' ')[1]
- status.append({"group": "os_pkg", "name": os_pkg.split("=")[0], "version": version, "status": "installed", "add_pkgs": dep})
- else:
- status.append({"group": "os_pkg", "name": os_pkg.split("=")[0], "status": status_msg, "error_message": err, "available_versions": versions})
+ status_msg = "installed"
+ if 'E: Version' in err and 'was not found' in err:
+ versions = sudo ('apt-cache policy {} | grep 500 | grep -v Packages'.format(os_pkg.split("=")[0]))\
+ .replace('\r\n', '').replace(' 500', '').replace(' ', ' ').replace('***', '').strip().split(' ')
+ if versions != '':
+ status_msg = 'invalid_version'
+ status.append({"group": "os_pkg", "name": os_pkg.split("=")[0], "version": version, "status": status_msg,
+ "error_message": err, "add_pkgs": dep, "available_versions": versions})
sudo('unattended-upgrades -v')
sudo('export LC_ALL=C')
return status
except Exception as err:
- append_result("Failed to install OS packages", str(err))
- sys.exit(1)
+ for os_pkg in requisites:
+ name, vers = os_pkg
+ status.append(
+ {"group": "os_pkg", "name": name, "version": vers, "status": 'installation_error', "error_message": err})
+ print("Failed to install OS packages: {}".format(requisites))
+ return status
@backoff.on_exception(backoff.expo, SystemExit, max_tries=10)
@@ -448,17 +483,19 @@
if not exists('/home/{}/.ensure_dir/caffe2_ensured'.format(os_user)):
env.shell = "/bin/bash -l -c -i"
manage_pkg('update', 'remote', '')
- manage_pkg('-y install --no-install-recommends', 'remote', 'build-essential cmake git libgoogle-glog-dev libprotobuf-dev protobuf-compiler python-dev python-pip')
- sudo('pip2 install numpy=={} protobuf --no-cache-dir'.format(os.environ['notebook_numpy_version']))
+ manage_pkg('-y install --no-install-recommends', 'remote', 'build-essential cmake git libgoogle-glog-dev '
+ 'libprotobuf-dev protobuf-compiler python-dev python-pip')
+ sudo('pip2 install numpy=={} protobuf --no-cache-dir'.format(os.environ['notebook_numpy2_version']))
sudo('pip3 install numpy=={} protobuf --no-cache-dir'.format(os.environ['notebook_numpy_version']))
manage_pkg('-y install --no-install-recommends', 'remote', 'libgflags-dev')
- manage_pkg('-y install --no-install-recommends', 'remote', 'libgtest-dev libiomp-dev libleveldb-dev liblmdb-dev libopencv-dev libopenmpi-dev libsnappy-dev openmpi-bin openmpi-doc python-pydot')
+ manage_pkg('-y install --no-install-recommends', 'remote', 'libgtest-dev libiomp-dev libleveldb-dev liblmdb-dev '
+ 'libopencv-dev libopenmpi-dev libsnappy-dev openmpi-bin openmpi-doc python-pydot')
sudo('pip2 install flask graphviz hypothesis jupyter matplotlib==2.0.2 pydot python-nvd3 pyyaml requests scikit-image '
'scipy setuptools tornado --no-cache-dir')
sudo('pip3 install flask graphviz hypothesis jupyter matplotlib==2.0.2 pydot python-nvd3 pyyaml requests scikit-image '
'scipy setuptools tornado --no-cache-dir')
- sudo('cp -f /opt/cudnn/include/* /opt/cuda-8.0/include/')
- sudo('cp -f /opt/cudnn/lib64/* /opt/cuda-8.0/lib64/')
+ sudo('cp -f /opt/cudnn/include/* /opt/cuda-{}/include/'.format(os.environ['notebook_cuda_version']))
+ sudo('cp -f /opt/cudnn/lib64/* /opt/cuda-{}/lib64/'.format(os.environ['notebook_cuda_version']))
sudo('wget https://cmake.org/files/v{2}/cmake-{1}.tar.gz -O /home/{0}/cmake-{1}.tar.gz'.format(
os_user, cmake_version, cmake_version.split('.')[0] + "." + cmake_version.split('.')[1]))
sudo('tar -zxvf cmake-{}.tar.gz'.format(cmake_version))
@@ -469,16 +506,16 @@
with cd('/home/{}/pytorch/'.format(os_user)):
sudo('git submodule update --init')
with settings(warn_only=True):
- sudo('git checkout v{}'.format(caffe2_version))
- sudo('git submodule update --recursive')
- sudo('mkdir build && cd build && cmake{} .. && make "-j$(nproc)" install'.format(cmake_version))
+ sudo('git checkout {}'.format(os.environ['notebook_pytorch_branch']))
+ sudo('git submodule update --init --recursive')
+ sudo('python3 setup.py install')
sudo('touch /home/' + os_user + '/.ensure_dir/caffe2_ensured')
-def install_cntk(os_user, cntk_version):
+def install_cntk(os_user, cntk2_version, cntk_version):
if not exists('/home/{}/.ensure_dir/cntk_ensured'.format(os_user)):
- sudo('pip2 install https://cntk.ai/PythonWheel/GPU/cntk-{}-cp27-cp27mu-linux_x86_64.whl --no-cache-dir'.format(cntk_version))
- sudo('pip3 install https://cntk.ai/PythonWheel/GPU/cntk-{}-cp35-cp35m-linux_x86_64.whl --no-cache-dir'.format(cntk_version))
+ sudo('pip2 install https://cntk.ai/PythonWheel/GPU/cntk-{}-cp27-cp27mu-linux_x86_64.whl --no-cache-dir'.format(cntk2_version))
+ sudo('pip3 install https://cntk.ai/PythonWheel/GPU/cntk_gpu-{}.post1-cp36-cp36m-manylinux1_x86_64.whl --no-cache-dir'.format(cntk_version))
sudo('touch /home/{}/.ensure_dir/cntk_ensured'.format(os_user))
@@ -498,19 +535,19 @@
def install_mxnet(os_user, mxnet_version):
if not exists('/home/{}/.ensure_dir/mxnet_ensured'.format(os_user)):
- sudo('pip2 install mxnet-cu80=={} opencv-python --no-cache-dir'.format(mxnet_version))
- sudo('pip3 install mxnet-cu80=={} opencv-python --no-cache-dir'.format(mxnet_version))
+ sudo('pip2 install mxnet-cu101=={} opencv-python --no-cache-dir'.format(mxnet_version))
+ sudo('pip3 install mxnet-cu101=={} opencv-python --no-cache-dir'.format(mxnet_version))
sudo('touch /home/{}/.ensure_dir/mxnet_ensured'.format(os_user))
-def install_torch(os_user):
- if not exists('/home/{}/.ensure_dir/torch_ensured'.format(os_user)):
- run('git clone https://github.com/torch/distro.git ~/torch --recursive')
- with cd('/home/{}/torch/'.format(os_user)):
- run('bash install-deps;')
- run('./install.sh -b')
- run('source /home/{}/.bashrc'.format(os_user))
- sudo('touch /home/{}/.ensure_dir/torch_ensured'.format(os_user))
+#def install_torch(os_user):
+# if not exists('/home/{}/.ensure_dir/torch_ensured'.format(os_user)):
+# run('git clone https://github.com/nagadomi/distro.git ~/torch --recursive')
+# with cd('/home/{}/torch/'.format(os_user)):
+# run('bash install-deps;')
+# run('./install.sh -b')
+# run('source /home/{}/.bashrc'.format(os_user))
+# sudo('touch /home/{}/.ensure_dir/torch_ensured'.format(os_user))
def install_gitlab_cert(os_user, certfile):
diff --git a/infrastructure-provisioning/src/general/lib/os/debian/ssn_lib.py b/infrastructure-provisioning/src/general/lib/os/debian/ssn_lib.py
index ff89fec..0c38603 100644
--- a/infrastructure-provisioning/src/general/lib/os/debian/ssn_lib.py
+++ b/infrastructure-provisioning/src/general/lib/os/debian/ssn_lib.py
@@ -91,8 +91,8 @@
sudo("find /var/lib/jenkins/jobs/ -type f | xargs sed -i \'s/OS_USR/{}/g; s/SBN/{}/g; s/CTUN/{}/g; s/SGI/{}/g; s/VPC/{}/g; s/SNI/{}/g; s/AKEY/{}/g\'".format(os_user, config['service_base_name'], tag_resource_id, config['security_group_id'], config['vpc_id'], config['subnet_id'], config['admin_key']))
sudo('chown -R jenkins:jenkins /var/lib/jenkins')
sudo('/etc/init.d/jenkins stop; sleep 5')
- sudo('sysv-rc-conf jenkins on')
- sudo('service jenkins start')
+ sudo('systemctl enable jenkins')
+ sudo('systemctl start jenkins')
sudo('touch ' + dlab_path + '/tmp/jenkins_configured')
sudo('echo "jenkins ALL = NOPASSWD:ALL" >> /etc/sudoers')
except Exception as err:
diff --git a/infrastructure-provisioning/src/general/lib/os/fab.py b/infrastructure-provisioning/src/general/lib/os/fab.py
index 4505cf0..df8cbe1 100644
--- a/infrastructure-provisioning/src/general/lib/os/fab.py
+++ b/infrastructure-provisioning/src/general/lib/os/fab.py
@@ -54,19 +54,23 @@
def install_pip_pkg(requisites, pip_version, lib_group):
status = list()
- error_parser = "Could not|No matching|ImportError:|failed|EnvironmentError:"
+ error_parser = "Could not|No matching|ImportError:|failed|EnvironmentError:|requires|FileNotFoundError:|RuntimeError:|error:"
try:
if pip_version == 'pip3' and not exists('/bin/pip3'):
- sudo('ln -s /bin/pip3.5 /bin/pip3')
+ for v in range(4, 8):
+ if exists('/bin/pip3.{}'.format(v)):
+ sudo('ln -s /bin/pip3.{} /bin/pip3'.format(v))
sudo('{} install -U pip=={} setuptools'.format(pip_version, os.environ['conf_pip_version']))
sudo('{} install -U pip=={} --no-cache-dir'.format(pip_version, os.environ['conf_pip_version']))
sudo('{} install --upgrade pip=={}'.format(pip_version, os.environ['conf_pip_version']))
for pip_pkg in requisites:
if pip_pkg[1] == '' or pip_pkg[1] == 'N/A':
pip_pkg = pip_pkg[0]
+ version = 'N/A'
else:
+ version = pip_pkg[1]
pip_pkg = "{}=={}".format(pip_pkg[0], pip_pkg[1])
- sudo('{0} install {1} --no-cache-dir 2>&1 | tee /tmp/tee.tmp; if ! grep -w -i -E "({2})" /tmp/tee.tmp > /tmp/{0}install_{1}.log; then echo "" > /tmp/{0}install_{1}.log;fi'.format(pip_version, pip_pkg, error_parser))
+ sudo('{0} install -U {1} --no-cache-dir 2>&1 | tee /tmp/tee.tmp; if ! grep -w -i -E "({2})" /tmp/tee.tmp > /tmp/{0}install_{1}.log; then echo "" > /tmp/{0}install_{1}.log;fi'.format(pip_version, pip_pkg, error_parser))
err = sudo('cat /tmp/{0}install_{1}.log'.format(pip_version, pip_pkg)).replace('"', "'")
sudo('{0} freeze | if ! grep -w -i {1} > /tmp/{0}install_{1}.list; then echo "" > /tmp/{0}install_{1}.list;fi'.format(pip_version, pip_pkg))
res = sudo('cat /tmp/{0}install_{1}.list'.format(pip_version, pip_pkg))
@@ -77,7 +81,9 @@
sudo('{0} freeze | if ! grep -w -i {1} > /tmp/{0}install_{1}.list; then echo "" > '
'/tmp/{0}install_{1}.list;fi'.format(pip_version, changed_pip_pkg))
res = sudo('cat /tmp/{0}install_{1}.list'.format(pip_version, changed_pip_pkg))
- if res:
+ if err:
+ status_msg = 'installation_error'
+ elif res:
res = res.lower()
ansi_escape = re.compile(r'\x1b[^m]*m')
ver = ansi_escape.sub('', res).split("\r\n")
@@ -85,41 +91,41 @@
version = [i for i in ver if changed_pip_pkg.lower() in i][0].split('==')[1]
else:
version = \
- [i for i in ver if pip_pkg.split("==")[0].lower() in i][0].split(
- '==')[1]
- sudo('if ! grep -w -i -E "Installing collected packages:" /tmp/tee.tmp > /tmp/{0}install_{1}.log; then echo "" > /tmp/{0}install_{1}.log;fi'.format(pip_version, pip_pkg))
- dep = sudo('cat /tmp/{0}install_{1}.log'.format(pip_version, pip_pkg)).replace('\r\n', '').strip()[31:]
- if dep == '' or dep == pip_pkg.split("==")[0]:
- dep = []
- else:
- dep = dep.split(', ')
- for n, i in enumerate(dep):
- if i == pip_pkg.split("==")[0]:
- dep[n] = ''
- else:
- dep[n] = sudo('{} freeze 2>&1 | grep {}=='.format(pip_version , i)).replace('==', ' v.')
- if dep[n] == '':
- dep[n] = sudo('{} freeze 2>&1 | grep {}=='.format(pip_version, i.lower())).replace('==', ' v.')
- dep = [i for i in dep if i]
-
- status.append({"group": "{}".format(lib_group), "name": pip_pkg.split("==")[0], "version": version, "status": "installed", "add_pkgs": dep})
- else:
- err_status = 'failed'
- versions = ''
- if 'Could not find a version that satisfies the requirement' in err:
- versions = err[err.find("(from versions: ") + 16: err.find(")\r\n")]
- err_status = 'invalid version'
- if versions == '':
- versions = []
- else:
+ [i for i in ver if pip_pkg.split("==")[0].lower() in i][0].split('==')[1]
+ status_msg = "installed"
+ versions = []
+ if 'Could not find a version that satisfies the requirement' in err:
+ versions = err[err.find("(from versions: ") + 16: err.find(")\r\n")]
+ if versions != '':
versions = versions.split(', ')
- status.append({"group": "{}".format(lib_group), "name": pip_pkg.split("==")[0], "status": err_status,
- "error_message": err, "available_versions": versions})
+ status_msg = 'invalid_version'
+ else:
+ versions = []
+
+ sudo('if ! grep -w -i -E "Installing collected packages:" /tmp/tee.tmp > /tmp/{0}install_{1}.log; '
+ 'then echo "" > /tmp/{0}install_{1}.log;fi'.format(pip_version, pip_pkg))
+ dep = sudo('cat /tmp/{0}install_{1}.log'.format(pip_version, pip_pkg)).replace('\r\n', '').strip()[31:]
+ if dep == '':
+ dep = []
+ else:
+ dep = dep.split(', ')
+ for n, i in enumerate(dep):
+ if i == pip_pkg.split("==")[0]:
+ dep[n] = ''
+ else:
+ sudo('{0} show {1} 2>&1 | if ! grep Version: /tmp/tee.tmp > '
+ '/tmp/{0}_install_{1}.log; then echo "" > /tmp/{0}_install_{1}.log;fi'.format(pip_version, i))
+ dep[n] = sudo('cat /tmp/{0}_install_{1}.log'.format(pip_version, i)).replace('Version: ', '{} v.'.format(i))
+ dep = [i for i in dep if i]
+ status.append({"group": lib_group, "name": pip_pkg.split("==")[0], "version": version, "status": status_msg,
+ "error_message": err, "available_versions": versions, "add_pkgs": dep})
return status
except Exception as err:
- append_result("Failed to install {} packages".format(pip_version), str(err))
+ for pip_pkg in requisites:
+ name, vers = pip_pkg
+ status.append({"group": lib_group, "name": name, "version": vers, "status": 'installation_error', "error_message": err})
print("Failed to install {} packages".format(pip_version))
- sys.exit(1)
+ return status
def id_generator(size=10, chars=string.digits + string.ascii_letters):
@@ -180,8 +186,8 @@
try:
sudo('pip2 install notebook==5.7.8 --no-cache-dir')
sudo('pip2 install jupyter --no-cache-dir')
- sudo('pip3.5 install notebook=={} --no-cache-dir'.format(jupyter_version))
- sudo('pip3.5 install jupyter --no-cache-dir')
+ sudo('pip3 install notebook=={} --no-cache-dir'.format(jupyter_version))
+ sudo('pip3 install jupyter --no-cache-dir')
sudo('rm -rf {}'.format(jupyter_conf_file))
run('jupyter notebook --generate-config --config {}'.format(jupyter_conf_file))
with cd('/home/{}'.format(os_user)):
@@ -203,6 +209,15 @@
"/caffe/python:/home/" + os_user + "/pytorch/build:$PYTHONPATH ; |g' /tmp/jupyter-notebook.service")
sudo("sed -i 's|CONF_PATH|{}|' /tmp/jupyter-notebook.service".format(jupyter_conf_file))
sudo("sed -i 's|OS_USR|{}|' /tmp/jupyter-notebook.service".format(os_user))
+ http_proxy = run('echo $http_proxy')
+ https_proxy = run('echo $https_proxy')
+ #sudo('sed -i \'/\[Service\]/ a\Environment=\"HTTP_PROXY={}\"\' /tmp/jupyter-notebook.service'.format(
+ # http_proxy))
+ #sudo('sed -i \'/\[Service\]/ a\Environment=\"HTTPS_PROXY={}\"\' /tmp/jupyter-notebook.service'.format(
+ # https_proxy))
+ java_home = run("update-alternatives --query java | grep -o \'/.*/java-8.*/jre\'").splitlines()[0]
+ sudo('sed -i \'/\[Service\]/ a\Environment=\"JAVA_HOME={}\"\' /tmp/jupyter-notebook.service'.format(
+ java_home))
sudo('\cp /tmp/jupyter-notebook.service /etc/systemd/system/jupyter-notebook.service')
sudo('chown -R {0}:{0} /home/{0}/.local'.format(os_user))
sudo('mkdir -p /mnt/var')
@@ -234,7 +249,7 @@
stable"')
manage_pkg('update', 'remote', '')
sudo('apt-cache policy docker-ce')
- manage_pkg('-y install', 'remote', 'docker-ce={}~ce~3-0~ubuntu'.format(docker_version))
+ manage_pkg('-y install', 'remote', 'docker-ce={}~ce~3-0~ubuntu'.format(docker_version), 'True')
sudo('touch /home/{}/.ensure_dir/docker_ensured'.format(os_user))
except Exception as err:
print('Failed to configure Docker:', str(err))
@@ -419,6 +434,7 @@
try:
for r_pkg in requisites:
name, vers = r_pkg
+ version = vers
if vers =='N/A':
vers = ''
else:
@@ -436,30 +452,37 @@
else:
dep = dep.split(' ')
for n, i in enumerate(dep):
- dep[n] = '{} v.{}'.format(dep[n], dep_ver[n])
+ if i == name:
+ dep[n] = ''
+ else:
+ dep[n] = '{} v.{}'.format(dep[n], dep_ver[n])
dep = [i for i in dep if i]
err = sudo('cat /tmp/install_{0}.log'.format(name)).replace('"', "'")
sudo('R -e \'installed.packages()[,c(3:4)]\' | if ! grep -w {0} > /tmp/install_{0}.list; then echo "" > /tmp/install_{0}.list;fi'.format(name))
res = sudo('cat /tmp/install_{0}.list'.format(name))
- if res:
+ if err:
+ status_msg = 'installation_error'
+ elif res:
ansi_escape = re.compile(r'\x1b[^m]*m')
version = ansi_escape.sub('', res).split("\r\n")[0].split('"')[1]
- status.append({"group": "r_pkg", "name": name, "version": version, "status": "installed", "add_pkgs": dep})
- else:
- if 'Error in download_version_url(package, version, repos, type) :' in err:
- sudo('R -e \'install.packages("versions", repos="https://cloud.r-project.org", dep=TRUE)\'')
- versions = sudo('R -e \'library(versions); available.versions("' + name + '")\' 2>&1 | grep -A 50 '
+ status_msg = 'installed'
+ if 'Error in download_version_url(package, version, repos, type) :' in err:
+ sudo('R -e \'install.packages("versions", repos="https://cloud.r-project.org", dep=TRUE)\'')
+ versions = sudo('R -e \'library(versions); available.versions("' + name + '")\' 2>&1 | grep -A 50 '
'\'date available\' | awk \'{print $2}\'').replace('\r\n', ' ')[5:].split(' ')
- status_msg = 'invalid version'
- else:
- versions = []
- status_msg = 'failed'
- status.append({"group": "r_pkg", "name": name, "status": status_msg, "error_message": err, "available_versions": versions})
+ if versions != ['']:
+ status_msg = 'invalid_version'
+ else:
+ versions = []
+ status.append({"group": "r_pkg", "name": name, "version": version, "status": status_msg, "error_message": err, "available_versions": versions, "add_pkgs": dep})
return status
except Exception as err:
- append_result("Failed to install R packages", str(err))
+ for r_pkg in requisites:
+ name, vers = r_pkg
+ status.append(
+ {"group": "r_pkg", "name": name, "version": vers, "status": 'installation_error', "error_message": err})
print("Failed to install R packages")
- sys.exit(1)
+ return status
def update_spark_jars(jars_dir='/opt/jars'):
@@ -517,14 +540,16 @@
sudo('cp -f $(find {0} -name "*.jar" | xargs) {1}'.format(ivy_cache_dir, dest_dir))
status.append({"group": "java", "name": "{0}:{1}".format(group, artifact), "version": version, "status": "installed"})
else:
- status.append({"group": "java", "name": "{0}:{1}".format(group, artifact), "status": "failed", "error_message": err})
+ status.append({"group": "java", "name": "{0}:{1}".format(group, artifact), "status": "installation_error", "error_message": err})
update_spark_jars()
return status
except Exception as err:
- append_result("Failed to install {} packages".format(requisites), str(err))
+ for java_pkg in requisites:
+ group, artifact, version, override = java_pkg
+ status.append({"group": "java", "name": "{0}:{1}".format(group, artifact), "status": "installation_error",
+ "error_message": err})
print("Failed to install {} packages".format(requisites))
- sys.exit(1)
-
+ return status
def get_available_r_pkgs():
try:
@@ -547,8 +572,8 @@
sudo('ln -s /opt/spark/ /usr/local/spark')
sudo('jupyter toree install')
sudo('mv ' + scala_kernel_path + 'lib/* /tmp/')
- put(files_dir + 'toree-assembly-0.2.0.jar', '/tmp/toree-assembly-0.2.0.jar')
- sudo('mv /tmp/toree-assembly-0.2.0.jar ' + scala_kernel_path + 'lib/')
+ put(files_dir + 'toree-assembly-0.3.0.jar', '/tmp/toree-assembly-0.3.0.jar')
+ sudo('mv /tmp/toree-assembly-0.3.0.jar ' + scala_kernel_path + 'lib/')
sudo(
'sed -i "s|Apache Toree - Scala|Local Apache Toree - Scala (Scala-' + scala_version +
', Spark-' + spark_version + ')|g" ' + scala_kernel_path + 'kernel.json')
@@ -686,18 +711,28 @@
sys.exit(1)
-def configure_data_engine_service_pip(hostname, os_user, keyfile):
+def configure_data_engine_service_pip(hostname, os_user, keyfile, emr=False):
env['connection_attempts'] = 100
env.key_filename = [keyfile]
env.host_string = os_user + '@' + hostname
if not exists('/usr/bin/pip2'):
- sudo('ln -s /usr/bin/pip-2.7 /usr/bin/pip2')
+ if not exists('/usr/bin/pip-2.7'):
+ manage_pkg('-y install', 'remote', 'python2-pip')
+ else:
+ sudo('ln -s /usr/bin/pip-2.7 /usr/bin/pip2')
+ manage_pkg('-y install', 'remote', 'python3-pip')
if not exists('/usr/bin/pip3') and sudo("python3.4 -V 2>/dev/null | awk '{print $2}'"):
sudo('ln -s /usr/bin/pip-3.4 /usr/bin/pip3')
elif not exists('/usr/bin/pip3') and sudo("python3.5 -V 2>/dev/null | awk '{print $2}'"):
sudo('ln -s /usr/bin/pip-3.5 /usr/bin/pip3')
elif not exists('/usr/bin/pip3') and sudo("python3.6 -V 2>/dev/null | awk '{print $2}'"):
sudo('ln -s /usr/bin/pip-3.6 /usr/bin/pip3')
+ elif not exists('/usr/bin/pip3') and sudo("python3.7 -V 2>/dev/null | awk '{print $2}'"):
+ sudo('ln -s /usr/bin/pip-3.7 /usr/bin/pip3')
+ if emr:
+ sudo('pip3 install -U pip=={}'.format(os.environ['conf_pip_version']))
+ sudo('pip2 install -U pip=={}'.format(os.environ['conf_pip_version']))
+ sudo('ln -s /usr/local/bin/pip3.7 /bin/pip3.7')
sudo('echo "export PATH=$PATH:/usr/local/bin" >> /etc/profile')
sudo('source /etc/profile')
run('source /etc/profile')
diff --git a/infrastructure-provisioning/src/general/lib/os/redhat/notebook_lib.py b/infrastructure-provisioning/src/general/lib/os/redhat/notebook_lib.py
index 34bae34..d159289 100644
--- a/infrastructure-provisioning/src/general/lib/os/redhat/notebook_lib.py
+++ b/infrastructure-provisioning/src/general/lib/os/redhat/notebook_lib.py
@@ -346,23 +346,62 @@
def install_os_pkg(requisites):
status = list()
error_parser = "Could not|No matching|Error:|failed|Requires:|Errno"
+ new_pkgs_parser = "Dependency Installed:"
try:
print("Updating repositories and installing requested tools: {}".format(requisites))
manage_pkg('update-minimal --security -y --skip-broken', 'remote', '')
sudo('export LC_ALL=C')
for os_pkg in requisites:
- manage_pkg('-y install', 'remote', '{0} --nogpgcheck 2>&1 | if ! grep -w -E "({1})" > /tmp/os_install_{0}.log; then echo "" > /tmp/os_install_{0}.log;fi'.format(os_pkg, error_parser))
+ name, vers = os_pkg
+ if vers != '' and vers !='N/A':
+ version = vers
+ os_pkg = "{}-{}".format(name, vers)
+ else:
+ version = 'N/A'
+ os_pkg = name
+ manage_pkg('-y install', 'remote', '{0} --nogpgcheck 2>&1 | tee /tmp/tee.tmp; if ! grep -w -E "({1})" /tmp/tee.tmp > /tmp/os_install_{0}.log; then echo "" > /tmp/os_install_{0}.log;fi'.format(os_pkg, error_parser))
+ install_output = sudo('cat /tmp/tee.tmp')
err = sudo('cat /tmp/os_install_{}.log'.format(os_pkg)).replace('"', "'")
- try:
- res = sudo('python -c "import os,sys,yum; yb = yum.YumBase(); pl = yb.doPackageLists(); print [pkg.vr for pkg in pl.installed if pkg.name == \'{0}\'][0]"'.format(os_pkg))
+ sudo('cat /tmp/tee.tmp | if ! grep -w -E -A 30 "({1})" /tmp/tee.tmp > '
+ '/tmp/os_install_{0}.log; then echo "" > /tmp/os_install_{0}.log;fi'.format(os_pkg, new_pkgs_parser))
+ dep = sudo('cat /tmp/os_install_{}.log'.format(os_pkg))
+ if dep == '':
+ dep = []
+ else:
+ dep = dep[len(new_pkgs_parser): dep.find("Complete!") - 1].replace(' ', '').strip().split('\r\n')
+ for n, i in enumerate(dep):
+ i = i.split('.')[0]
+ sudo('yum info {0} 2>&1 | if ! grep Version > /tmp/os_install_{0}.log; then echo "" > /tmp/os_install_{0}.log;fi'.format(i))
+ dep[n] =sudo('cat /tmp/os_install_{}.log'.format(i)).replace('Version : ', '{} v.'.format(i))
+ dep = [i for i in dep if i]
+ versions = []
+ res = sudo(
+ 'python -c "import os,sys,yum; yb = yum.YumBase(); pl = yb.doPackageLists(); print [pkg.vr for pkg in pl.installed if pkg.name == \'{0}\'][0]"'.format(
+ name))
+ if err:
+ status_msg = 'installation_error'
+ elif res:
version = res.split('\r\n')[1].replace("'", "\"")
- status.append({"group": "os_pkg", "name": os_pkg, "version": version, "status": "installed"})
- except:
- status.append({"group": "os_pkg", "name": os_pkg, "status": "failed", "error_message": err})
+ status_msg = "installed"
+ if 'No package {} available'.format(os_pkg) in install_output:
+ versions = sudo ('yum --showduplicates list ' + name + ' | expand | grep -A 10 "Available Packages" | grep -v "Available Packages"| awk \'{print $2}\'').replace('\r\n', '').split(' ')
+ if versions != '':
+ status_msg = 'invalid_version'
+ for n, i in enumerate(versions):
+ if ':' in i:
+ versions[n] = i.split(':')[1].split('-')[0]
+ else:
+ versions[n] = i.split('-')[0]
+ status.append({"group": "os_pkg", "name": name, "version": version, "status": status_msg,
+ "error_message": err, "add_pkgs": dep, "available_versions": versions})
return status
- except:
- return "Fail to install OS packages"
-
+ except Exception as err:
+ for os_pkg in requisites:
+ name, vers = os_pkg
+ status.append(
+ {"group": "os_pkg", "name": name, "version": vers, "status": 'installation_error', "error_message": err})
+ print("Failed to install OS packages: {}".format(requisites))
+ return status
def remove_os_pkg(pkgs):
try:
@@ -462,14 +501,14 @@
sudo('touch /home/{}/.ensure_dir/mxnet_ensured'.format(os_user))
-def install_torch(os_user):
- if not exists('/home/{}/.ensure_dir/torch_ensured'.format(os_user)):
- run('git clone https://github.com/torch/distro.git ~/torch --recursive')
- with cd('/home/{}/torch/'.format(os_user)):
- manage_pkg('-y install --nogpgcheck', 'remote', 'cmake curl readline-devel ncurses-devel gcc-c++ gcc-gfortran git gnuplot unzip libjpeg-turbo-devel libpng-devel ImageMagick GraphicsMagick-devel fftw-devel sox-devel sox zeromq3-devel qt-devel qtwebkit-devel sox-plugins-freeworld qt-devel')
- run('./install.sh -b')
- run('source /home/{}/.bashrc'.format(os_user))
- sudo('touch /home/{}/.ensure_dir/torch_ensured'.format(os_user))
+#def install_torch(os_user):
+# if not exists('/home/{}/.ensure_dir/torch_ensured'.format(os_user)):
+# run('git clone https://github.com/torch/distro.git ~/torch --recursive')
+# with cd('/home/{}/torch/'.format(os_user)):
+# manage_pkg('-y install --nogpgcheck', 'remote', 'cmake curl readline-devel ncurses-devel gcc-c++ gcc-gfortran git gnuplot unzip libjpeg-turbo-devel libpng-devel ImageMagick GraphicsMagick-devel fftw-devel sox-devel sox zeromq3-devel qt-devel qtwebkit-devel sox-plugins-freeworld qt-devel')
+# run('./install.sh -b')
+# run('source /home/{}/.bashrc'.format(os_user))
+# sudo('touch /home/{}/.ensure_dir/torch_ensured'.format(os_user))
def install_gitlab_cert(os_user, certfile):
diff --git a/infrastructure-provisioning/src/general/scripts/aws/common_create_subnet.py b/infrastructure-provisioning/src/general/scripts/aws/common_create_subnet.py
index b4dc3c6..83dd48a 100644
--- a/infrastructure-provisioning/src/general/scripts/aws/common_create_subnet.py
+++ b/infrastructure-provisioning/src/general/scripts/aws/common_create_subnet.py
@@ -129,20 +129,23 @@
subnet_id = get_subnet_by_cidr(subnet_check)
print("SUBNET_ID: {}".format(subnet_id))
if not args.ssn:
- print("Associating route_table with the subnet")
- ec2 = boto3.resource('ec2')
- if os.environ['conf_duo_vpc_enable'] == 'true':
- rt = get_route_table_by_tag(args.infra_tag_value + '-secondary-tag', args.infra_tag_value)
+ if os.environ['edge_is_nat'] == 'true':
+ print('Subnet will be associted with route table for NAT')
else:
- rt = get_route_table_by_tag(args.infra_tag_name, args.infra_tag_value)
- route_table = ec2.RouteTable(rt)
- try:
- route_table.associate_with_subnet(SubnetId=subnet_id)
+ print("Associating route_table with the subnet")
+ ec2 = boto3.resource('ec2')
if os.environ['conf_duo_vpc_enable'] == 'true':
- create_peer_routes(os.environ['aws_peering_id'], args.infra_tag_value)
- except exceptions.ClientError as err:
- if 'Resource.AlreadyAssociated' in str(err):
- print('Other route table is already associted with this subnet. Skipping...')
+ rt = get_route_table_by_tag(args.infra_tag_value + '-secondary-tag', args.infra_tag_value)
+ else:
+ rt = get_route_table_by_tag(args.infra_tag_name, args.infra_tag_value)
+ route_table = ec2.RouteTable(rt)
+ try:
+ route_table.associate_with_subnet(SubnetId=subnet_id)
+ if os.environ['conf_duo_vpc_enable'] == 'true':
+ create_peer_routes(os.environ['aws_peering_id'], args.infra_tag_value)
+ except exceptions.ClientError as err:
+ if 'Resource.AlreadyAssociated' in str(err):
+ print('Other route table is already associted with this subnet. Skipping...')
else:
print("Associating route_table with the subnet")
ec2 = boto3.resource('ec2')
diff --git a/infrastructure-provisioning/src/general/scripts/aws/common_prepare_notebook.py b/infrastructure-provisioning/src/general/scripts/aws/common_prepare_notebook.py
index 5c481ac..5a1a6f0 100644
--- a/infrastructure-provisioning/src/general/scripts/aws/common_prepare_notebook.py
+++ b/infrastructure-provisioning/src/general/scripts/aws/common_prepare_notebook.py
@@ -78,7 +78,7 @@
notebook_config['project_name'],
notebook_config['endpoint_name'],
notebook_config['exploratory_name'], args.uuid)
- notebook_config['primary_disk_size'] = (lambda x: '30' if x == 'deeplearning' else '12')(
+ notebook_config['primary_disk_size'] = (lambda x: '30' if x == 'deeplearning' else '16')(
os.environ['application'])
notebook_config['role_profile_name'] = '{}-{}-{}-nb-de-profile'.format(
notebook_config['service_base_name'], notebook_config['project_name'], notebook_config['endpoint_name'])
diff --git a/infrastructure-provisioning/src/general/scripts/aws/dataengine-service_configure.py b/infrastructure-provisioning/src/general/scripts/aws/dataengine-service_configure.py
index 9e9fb40..147247a 100644
--- a/infrastructure-provisioning/src/general/scripts/aws/dataengine-service_configure.py
+++ b/infrastructure-provisioning/src/general/scripts/aws/dataengine-service_configure.py
@@ -33,6 +33,7 @@
import logging
import argparse
import multiprocessing
+from dlab.common_lib import manage_pkg
parser = argparse.ArgumentParser()
@@ -81,12 +82,13 @@
print('[CONFIGURE DATAENGINE SERVICE]')
try:
dlab.fab.configure_data_engine_service_pip(emr_conf['instance_ip'], emr_conf['os_user'],
- emr_conf['key_path'])
+ emr_conf['key_path'], True)
env['connection_attempts'] = 100
env.key_filename = emr_conf['key_path']
env.host_string = emr_conf['os_user'] + '@' + emr_conf['instance_ip']
sudo('echo "[main]" > /etc/yum/pluginconf.d/priorities.conf ; echo "enabled = 0" >> '
'/etc/yum/pluginconf.d/priorities.conf')
+ manage_pkg('-y install', 'remote', 'R-devel')
except:
traceback.print_exc()
raise Exception
@@ -174,7 +176,7 @@
emr_conf['computational_name'] = os.environ['computational_name']
else:
emr_conf['computational_name'] = ''
- emr_conf['apps'] = 'Hadoop Hive Hue Spark'
+ emr_conf['apps'] = 'Hadoop Hive Hue Spark Livy'
emr_conf['service_base_name'] = os.environ['conf_service_base_name']
emr_conf['project_name'] = os.environ['project_name']
emr_conf['endpoint_name'] = os.environ['endpoint_name']
diff --git a/infrastructure-provisioning/src/general/scripts/aws/dataengine-service_jars_parser.py b/infrastructure-provisioning/src/general/scripts/aws/dataengine-service_jars_parser.py
index 0626285..699f07c 100644
--- a/infrastructure-provisioning/src/general/scripts/aws/dataengine-service_jars_parser.py
+++ b/infrastructure-provisioning/src/general/scripts/aws/dataengine-service_jars_parser.py
@@ -63,7 +63,7 @@
with open('/tmp/r_version', 'w') as outfile:
outfile.write(r_ver)
os.system('touch /tmp/python_version')
- for v in range(4, 7):
+ for v in range(4, 8):
python_ver_checker = "python3.{} -V 2>/dev/null".format(v) + " | awk '{print $2}'"
python_ver = subprocess.check_output(python_ver_checker, shell=True)
if python_ver != '':
diff --git a/infrastructure-provisioning/src/general/scripts/aws/edge_configure.py b/infrastructure-provisioning/src/general/scripts/aws/edge_configure.py
index d96ef49..2a809f6 100644
--- a/infrastructure-provisioning/src/general/scripts/aws/edge_configure.py
+++ b/infrastructure-provisioning/src/general/scripts/aws/edge_configure.py
@@ -161,6 +161,21 @@
except:
traceback.print_exc()
raise Exception
+ print('RESTARTING EDGE NODE')
+ try:
+ print('Stoping EDGE node')
+ dlab.actions_lib.stop_ec2(edge_conf['tag_name'], edge_conf['instance_name'])
+ except Exception as err:
+ print('Error: {0}'.format(err))
+ dlab.fab.append_result("Failed to stop edge.", str(err))
+ sys.exit(1)
+ try:
+ print('Starting EDGE node')
+ dlab.actions_lib.start_ec2(edge_conf['tag_name'], edge_conf['instance_name'])
+ except Exception as err:
+ print('Error: {0}'.format(err))
+ dlab.fab.append_result("Failed to start edge.", str(err))
+ sys.exit(1)
except Exception as err:
dlab.fab.append_result("Failed installing apps: apt & pip.", str(err))
clear_resources()
@@ -245,6 +260,25 @@
sys.exit(1)
try:
+ print('[CONFIGRING EDGE AS NAT]')
+ if os.environ['edge_is_nat'] == 'true':
+ print('Installing nftables')
+ additional_config = {"exploratory_subnet": edge_conf['private_subnet_cidr'],
+ "edge_ip": edge_conf['edge_private_ip']}
+ params = "--hostname {} --keyfile {} --additional_config '{}' --user {}".format(
+ edge_conf['instance_hostname'], edge_conf['keyfile_name'], json.dumps(additional_config),
+ edge_conf['dlab_ssh_user'])
+ try:
+ local("~/scripts/{}.py {}".format('configure_nftables', params))
+ except:
+ traceback.print_exc()
+ raise Exception
+ except Exception as err:
+ dlab.fab.append_result("Failed to configure NAT." + str(err))
+ clear_resources()
+ sys.exit(1)
+
+ try:
print('[SUMMARY]')
logging.info('[SUMMARY]')
print("Instance name: {}".format(edge_conf['instance_name']))
diff --git a/infrastructure-provisioning/src/general/scripts/aws/edge_configure_route_table.py b/infrastructure-provisioning/src/general/scripts/aws/edge_configure_route_table.py
new file mode 100644
index 0000000..c3ac2e4
--- /dev/null
+++ b/infrastructure-provisioning/src/general/scripts/aws/edge_configure_route_table.py
@@ -0,0 +1,38 @@
+#!/usr/bin/python
+
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
+import argparse
+from dlab.actions_lib import *
+from dlab.meta_lib import *
+
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--vpc_id', type=str, default='')
+parser.add_argument('--infra_tag_value', type=str, default='')
+parser.add_argument('--edge_instance_id', type=str, default='')
+parser.add_argument('--private_subnet_id', type=str, default='')
+args = parser.parse_args()
+
+if __name__ == "__main__":
+ rt_id = create_nat_rt(args.vpc_id, args.infra_tag_value, args.edge_instance_id, args.private_subnet_id)
+
diff --git a/infrastructure-provisioning/src/general/scripts/aws/jupyter_dataengine-service_create_configs.py b/infrastructure-provisioning/src/general/scripts/aws/jupyter_dataengine-service_create_configs.py
index 5f17c07..1bb09b3 100644
--- a/infrastructure-provisioning/src/general/scripts/aws/jupyter_dataengine-service_create_configs.py
+++ b/infrastructure-provisioning/src/general/scripts/aws/jupyter_dataengine-service_create_configs.py
@@ -52,6 +52,8 @@
parser.add_argument('--pip_mirror', type=str, default='')
parser.add_argument('--numpy_version', type=str, default='')
parser.add_argument('--application', type=str, default='')
+parser.add_argument('--master_ip', type=str, default='')
+parser.add_argument('--python_version', type=str, default='')
args = parser.parse_args()
emr_dir = '/opt/' + args.emr_version + '/jars/'
@@ -106,8 +108,8 @@
else:
local('mkdir -p ' + kernels_dir + 'toree_' + args.cluster_name + '/')
local('tar zxvf /tmp/toree_kernel.tar.gz -C ' + kernels_dir + 'toree_' + args.cluster_name + '/')
- local('sudo mv {0}toree_{1}/toree-0.2.0-incubating/* {0}toree_{1}/'.format(kernels_dir, args.cluster_name))
- local('sudo rm -r {0}toree_{1}/toree-0.2.0-incubating'.format(kernels_dir, args.cluster_name))
+ local('sudo mv {0}toree_{1}/toree-0.3.0-incubating/* {0}toree_{1}/'.format(kernels_dir, args.cluster_name))
+ local('sudo rm -r {0}toree_{1}/toree-0.3.0-incubating'.format(kernels_dir, args.cluster_name))
kernel_path = kernels_dir + "toree_" + args.cluster_name + "/kernel.json"
template_file = "/tmp/toree_dataengine-service_templatev2.json"
with open(template_file, 'r') as f:
@@ -162,22 +164,57 @@
local(""" sudo bash -c "sed -i '/spark.driver.extraClassPath/s/$/:\/opt\/""" + args.emr_version +
"""\/jars\/usr\/other\/*/' """ + spark_defaults_path + """" """)
+def install_sparkamagic_kernels(args):
+ try:
+ local('sudo jupyter nbextension enable --py --sys-prefix widgetsnbextension')
+ sparkmagic_dir = local("sudo pip3 show sparkmagic | grep 'Location: ' | awk '{print $2}'", capture=True)
+ local('sudo jupyter-kernelspec install {}/sparkmagic/kernels/sparkkernel --user'.format(sparkmagic_dir))
+ local('sudo jupyter-kernelspec install {}/sparkmagic/kernels/pysparkkernel --user'.format(sparkmagic_dir))
+ local('sudo jupyter-kernelspec install {}/sparkmagic/kernels/sparkrkernel --user'.format(sparkmagic_dir))
+ pyspark_kernel_name = 'PySpark (Python-{0} / Spark-{1} ) [{2}]'.format(args.python_version, args.spark_version,
+ args.cluster_name)
+ local('sed -i \'s|PySpark|{0}|g\' /home/{1}/.local/share/jupyter/kernels/pysparkkernel/kernel.json'.format(
+ pyspark_kernel_name, args.os_user))
+ spark_kernel_name = 'Spark (Scala-{0} / Spark-{1} ) [{2}]'.format(args.scala_version, args.spark_version,
+ args.cluster_name)
+ local('sed -i \'s|Spark|{0}|g\' /home/{1}/.local/share/jupyter/kernels/sparkkernel/kernel.json'.format(
+ spark_kernel_name, args.os_user))
+ sparkr_kernel_name = 'SparkR (R-{0} / Spark-{1} ) [{2}]'.format(args.r_version, args.spark_version,
+ args.cluster_name)
+ local('sed -i \'s|SparkR|{0}|g\' /home/{1}/.local/share/jupyter/kernels/sparkrkernel/kernel.json'.format(
+ sparkr_kernel_name, args.os_user))
+ local('sudo mv -f /home/{0}/.local/share/jupyter/kernels/pysparkkernel '
+ '/home/{0}/.local/share/jupyter/kernels/pysparkkernel_{1}'.format(args.os_user, args.cluster_name))
+ local('sudo mv -f /home/{0}/.local/share/jupyter/kernels/sparkkernel '
+ '/home/{0}/.local/share/jupyter/kernels/sparkkernel_{1}'.format(args.os_user, args.cluster_name))
+ local('sudo mv -f /home/{0}/.local/share/jupyter/kernels/sparkrkernel '
+ '/home/{0}/.local/share/jupyter/kernels/sparkrkernel_{1}'.format(args.os_user, args.cluster_name))
+ local('mkdir -p /home/' + args.os_user + '/.sparkmagic')
+ local('cp -f /tmp/sparkmagic_config_template.json /home/' + args.os_user + '/.sparkmagic/config.json')
+ local('sed -i \'s|LIVY_HOST|{0}|g\' /home/{1}/.sparkmagic/config.json'.format(
+ args.master_ip, args.os_user))
+ local('sudo chown -R {0}:{0} /home/{0}/.sparkmagic/'.format(args.os_user))
+ except:
+ sys.exit(1)
+
+
if __name__ == "__main__":
if args.dry_run == 'true':
parser.print_help()
else:
- result = prepare(emr_dir, yarn_dir)
- if result == False :
- jars(args, emr_dir)
- yarn(args, yarn_dir)
- install_emr_spark(args)
- pyspark_kernel(kernels_dir, args.emr_version, args.cluster_name, args.spark_version, args.bucket,
- args.project_name, args.region, args.os_user, args.application, args.pip_mirror, args.numpy_version)
- toree_kernel(args)
- if args.r_version != 'false':
- print('R version: {}'.format(args.r_version))
- r_kernel(args)
- spark_defaults(args)
- configuring_notebook(args.emr_version)
- add_breeze_library_emr(args)
+ install_sparkamagic_kernels(args)
+ #result = prepare(emr_dir, yarn_dir)
+ #if result == False :
+ # jars(args, emr_dir)
+ #yarn(args, yarn_dir)
+ #install_emr_spark(args)
+ #pyspark_kernel(kernels_dir, args.emr_version, args.cluster_name, args.spark_version, args.bucket,
+ # args.project_name, args.region, args.os_user, args.application, args.pip_mirror, args.numpy_version)
+ #toree_kernel(args)
+ #if args.r_version != 'false':
+ # print('R version: {}'.format(args.r_version))
+ # r_kernel(args)
+ #spark_defaults(args)
+ #configuring_notebook(args.emr_version)
+ #add_breeze_library_emr(args)
diff --git a/infrastructure-provisioning/src/general/scripts/aws/jupyter_install_dataengine-service_kernels.py b/infrastructure-provisioning/src/general/scripts/aws/jupyter_install_dataengine-service_kernels.py
index fb29f0a..37d102a 100644
--- a/infrastructure-provisioning/src/general/scripts/aws/jupyter_install_dataengine-service_kernels.py
+++ b/infrastructure-provisioning/src/general/scripts/aws/jupyter_install_dataengine-service_kernels.py
@@ -50,14 +50,15 @@
templates_dir = '/root/templates/'
files_dir = '/root/files/'
scripts_dir = '/root/scripts/'
- put(templates_dir + 'pyspark_dataengine-service_template.json', '/tmp/pyspark_dataengine-service_template.json')
- put(templates_dir + 'r_dataengine-service_template.json', '/tmp/r_dataengine-service_template.json')
- put(templates_dir + 'toree_dataengine-service_template.json','/tmp/toree_dataengine-service_template.json')
+ put(templates_dir + 'sparkmagic_config_template.json', '/tmp/sparkmagic_config_template.json')
+ #put(templates_dir + 'pyspark_dataengine-service_template.json', '/tmp/pyspark_dataengine-service_template.json')
+ #put(templates_dir + 'r_dataengine-service_template.json', '/tmp/r_dataengine-service_template.json')
+ #put(templates_dir + 'toree_dataengine-service_template.json','/tmp/toree_dataengine-service_template.json')
put(scripts_dir + '{}_dataengine-service_create_configs.py'.format(args.application),
'/tmp/jupyter_dataengine-service_create_configs.py')
- put(files_dir + 'toree_kernel.tar.gz', '/tmp/toree_kernel.tar.gz')
- put(templates_dir + 'toree_dataengine-service_templatev2.json', '/tmp/toree_dataengine-service_templatev2.json')
- put(templates_dir + 'run_template.sh', '/tmp/run_template.sh')
+ #put(files_dir + 'toree_kernel.tar.gz', '/tmp/toree_kernel.tar.gz')
+ #put(templates_dir + 'toree_dataengine-service_templatev2.json', '/tmp/toree_dataengine-service_templatev2.json')
+ #put(templates_dir + 'run_template.sh', '/tmp/run_template.sh')
sudo('\cp /tmp/jupyter_dataengine-service_create_configs.py /usr/local/bin/jupyter_dataengine-service_create_configs.py')
sudo('chmod 755 /usr/local/bin/jupyter_dataengine-service_create_configs.py')
sudo('mkdir -p /usr/lib/python2.7/dlab/')
@@ -82,9 +83,14 @@
s3_client = boto3.client('s3', config=Config(signature_version='s3v4'), region_name=args.region)
s3_client.download_file(args.bucket, args.project_name + '/' + args.cluster_name + '/scala_version',
'/tmp/scala_version')
+ s3_client.download_file(args.bucket, args.project_name + '/' + args.cluster_name + '/python_version',
+ '/tmp/python_version')
with file('/tmp/scala_version') as f:
scala_version = str(f.read()).rstrip()
print(scala_version)
+ with file('/tmp/python_version') as f:
+ python_version = str(f.read()).rstrip()
+ print(python_version)
if r_enabled == 'true':
s3_client.download_file(args.bucket, args.project_name + '/' + args.cluster_name + '/r_version', '/tmp/r_version')
with file('/tmp/r_version') as g:
@@ -92,9 +98,13 @@
print(r_version)
else:
r_version = 'false'
+ cluster_id = get_emr_id_by_name(args.cluster_name)
+ master_instances = get_emr_instances_list(cluster_id, 'MASTER')
+ master_ip = master_instances[0].get('PrivateIpAddress')
sudo("/usr/bin/python /usr/local/bin/jupyter_dataengine-service_create_configs.py --bucket " + args.bucket
+ " --cluster_name " + args.cluster_name + " --emr_version " + args.emr_version + " --spark_version "
+ spark_version + " --scala_version " + scala_version + " --r_version " + r_version + " --hadoop_version "
+ hadoop_version + " --region " + args.region + " --excluded_lines '" + args.emr_excluded_spark_properties
+ "' --project_name " + args.project_name + " --os_user " + args.os_user + " --pip_mirror "
- + args.pip_mirror + " --numpy_version " + numpy_version + " --application " + args.application)
+ + args.pip_mirror + " --numpy_version " + numpy_version + " --application "
+ + args.application + " --master_ip " + master_ip + " --python_version " + python_version)
diff --git a/infrastructure-provisioning/src/general/scripts/aws/project_prepare.py b/infrastructure-provisioning/src/general/scripts/aws/project_prepare.py
index 9d44ba5..9986ab2 100644
--- a/infrastructure-provisioning/src/general/scripts/aws/project_prepare.py
+++ b/infrastructure-provisioning/src/general/scripts/aws/project_prepare.py
@@ -60,6 +60,7 @@
os.environ['conf_os_family'])])
project_conf['instance_size'] = os.environ['aws_edge_instance_size']
project_conf['sg_ids'] = os.environ['aws_security_groups_ids']
+ project_conf['instance_class'] = 'edge'
project_conf['edge_instance_name'] = '{}-{}-{}-edge'.format(project_conf['service_base_name'],
project_conf['project_name'],
project_conf['endpoint_name'])
@@ -400,6 +401,12 @@
"FromPort": 389,
"IpRanges": [{"CidrIp": project_conf['all_ip_cidr']}],
"ToPort": 389, "IpProtocol": "tcp", "UserIdGroupPairs": []
+ },
+ {
+ "PrefixListIds": [],
+ "FromPort": -1,
+ "IpRanges": [{"CidrIp": project_conf['all_ip_cidr']}],
+ "ToPort": -1, "IpProtocol": "icmp", "UserIdGroupPairs": []
}
])
params = "--name {} --vpc_id {} --security_group_rules '{}' --infra_tag_name {} --infra_tag_value {} \
@@ -622,6 +629,12 @@
local("~/scripts/{}.py {}".format('common_create_instance', params))
edge_instance = dlab.meta_lib.get_instance_by_name(project_conf['tag_name'],
project_conf['edge_instance_name'])
+ if os.environ['edge_is_nat']:
+ try:
+ dlab.actions_lib.modify_instance_sourcedescheck(edge_instance)
+ except:
+ traceback.print_exc()
+ raise Exception
except:
traceback.print_exc()
raise Exception
@@ -670,3 +683,34 @@
dlab.actions_lib.remove_sgroups(project_conf['edge_instance_name'])
dlab.actions_lib.remove_s3('edge', project_conf['project_name'])
sys.exit(1)
+
+ if os.environ['edge_is_nat'] == 'true':
+ try:
+ print('[CONFIGURING ROUTE TABLE FOR NAT]')
+ project_conf['nat_rt_name'] = '{0}-{1}-{2}-nat-rt'.format(project_conf['service_base_name'],
+ project_conf['project_name'],
+ project_conf['endpoint_name'])
+ params = "--vpc_id {} --infra_tag_value {} --edge_instance_id {} --private_subnet_id {}".format(
+ project_conf['vpc2_id'], project_conf['nat_rt_name'], edge_instance, subnet_id)
+ try:
+ local("~/scripts/{}.py {}".format('edge_configure_route_table', params))
+ except:
+ traceback.print_exc()
+ raise Exception
+ except Exception as err:
+ dlab.fab.append_result("Failed to configure route table.", str(err))
+ try:
+ project_conf['edge_public_ip'] = dlab.meta_lib.get_instance_ip_address(
+ project_conf['tag_name'], project_conf['edge_instance_name']).get('Public')
+ project_conf['allocation_id'] = dlab.meta_lib.get_allocation_id_by_elastic_ip(
+ project_conf['edge_public_ip'])
+ except:
+ print("No Elastic IPs to release!")
+ dlab.actions_lib.remove_ec2(project_conf['tag_name'], project_conf['edge_instance_name'])
+ dlab.actions_lib.remove_all_iam_resources('notebook', project_conf['project_name'])
+ dlab.actions_lib.remove_all_iam_resources('edge', project_conf['project_name'])
+ dlab.actions_lib.remove_sgroups(project_conf['dataengine_instances_name'])
+ dlab.actions_lib.remove_sgroups(project_conf['notebook_instance_name'])
+ dlab.actions_lib.remove_sgroups(project_conf['edge_instance_name'])
+ dlab.actions_lib.remove_s3('edge', project_conf['project_name'])
+ sys.exit(1)
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/scripts/gcp/common_create_nat_route.py b/infrastructure-provisioning/src/general/scripts/gcp/common_create_nat_route.py
new file mode 100644
index 0000000..8f03ea8
--- /dev/null
+++ b/infrastructure-provisioning/src/general/scripts/gcp/common_create_nat_route.py
@@ -0,0 +1,58 @@
+#!/usr/bin/python
+
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
+import json
+import argparse
+from dlab.actions_lib import *
+from dlab.meta_lib import *
+import sys
+from botocore.exceptions import ClientError
+
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--nat_route_name', type=str)
+parser.add_argument('--vpc', type=str)
+parser.add_argument('--tag', type=str)
+parser.add_argument('--edge_instance', type=str)
+args = parser.parse_args()
+
+
+if __name__ == "__main__":
+ if GCPMeta().get_route(args.nat_route_name):
+ print("REQUESTED ROUTE {} ALREADY EXISTS".format(args.nat_route_name))
+ else:
+ print("Creating NAT ROUTE {}".format(args.nat_route_name))
+ params = {
+ "destRange": "0.0.0.0/0",
+ "name": args.nat_route_name,
+ "network": args.vpc,
+ "priority": 0,
+ "tags": [
+ args.tag
+ ],
+ "nextHopInstance": args.edge_instance
+ }
+ GCPActions().create_nat_route(params)
+else:
+ parser.print_help()
+ sys.exit(2)
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/scripts/gcp/common_prepare_notebook.py b/infrastructure-provisioning/src/general/scripts/gcp/common_prepare_notebook.py
index 5f7931f..dcba179 100644
--- a/infrastructure-provisioning/src/general/scripts/gcp/common_prepare_notebook.py
+++ b/infrastructure-provisioning/src/general/scripts/gcp/common_prepare_notebook.py
@@ -96,7 +96,7 @@
notebook_config['project_name'],
notebook_config['endpoint_name'],
notebook_config['exploratory_name'])
- notebook_config['primary_disk_size'] = (lambda x: '30' if x == 'deeplearning' else '12')(
+ notebook_config['primary_disk_size'] = (lambda x: '30' if x == 'deeplearning' else '16')(
os.environ['application'])
notebook_config['secondary_disk_size'] = os.environ['notebook_disk_size']
diff --git a/infrastructure-provisioning/src/general/scripts/gcp/dataengine-service_jars_parser.py b/infrastructure-provisioning/src/general/scripts/gcp/dataengine-service_jars_parser.py
index c07e515..04870f2 100644
--- a/infrastructure-provisioning/src/general/scripts/gcp/dataengine-service_jars_parser.py
+++ b/infrastructure-provisioning/src/general/scripts/gcp/dataengine-service_jars_parser.py
@@ -44,7 +44,7 @@
outfile.write(r_ver)
os.system('touch /tmp/python_version')
- for v in range(4, 7):
+ for v in range(4, 8):
python_ver_checker = "python3.{} -V 2>/dev/null".format(v) + " | awk '{print $2}'"
python_ver = subprocess.check_output(python_ver_checker, shell=True).decode('UTF-8')
if python_ver != '':
diff --git a/infrastructure-provisioning/src/general/scripts/gcp/dataengine-service_prepare.py b/infrastructure-provisioning/src/general/scripts/gcp/dataengine-service_prepare.py
index 993b8e7..91d16e2 100644
--- a/infrastructure-provisioning/src/general/scripts/gcp/dataengine-service_prepare.py
+++ b/infrastructure-provisioning/src/general/scripts/gcp/dataengine-service_prepare.py
@@ -152,6 +152,8 @@
dataproc_cluster['config']['workerConfig']['machineTypeUri'] = os.environ['dataproc_slave_instance_type']
dataproc_cluster['config']['masterConfig']['numInstances'] = int(os.environ['dataproc_master_count'])
dataproc_cluster['config']['workerConfig']['numInstances'] = int(os.environ['dataproc_slave_count'])
+ livy_init = 'gs://goog-dataproc-initialization-actions-{}/livy/livy.sh'.format(dataproc_conf['region'])
+ dataproc_cluster['config']['initializationActions'][0]['executableFile'] = livy_init
if int(os.environ['dataproc_preemptible_count']) != 0:
dataproc_cluster['config']['secondaryWorkerConfig']['numInstances'] = int(
os.environ['dataproc_preemptible_count'])
diff --git a/infrastructure-provisioning/src/general/scripts/gcp/edge_configure.py b/infrastructure-provisioning/src/general/scripts/gcp/edge_configure.py
index 110efb9..7b2286d 100644
--- a/infrastructure-provisioning/src/general/scripts/gcp/edge_configure.py
+++ b/infrastructure-provisioning/src/general/scripts/gcp/edge_configure.py
@@ -267,6 +267,25 @@
sys.exit(1)
try:
+ print('[CONFIGRING EDGE AS NAT]')
+ if os.environ['edge_is_nat'] == 'true':
+ print('Installing nftables')
+ additional_config = {"exploratory_subnet": edge_conf['private_subnet_cidr'],
+ "edge_ip": edge_conf['private_ip']}
+ params = "--hostname {} --keyfile {} --additional_config '{}' --user {}".format(
+ edge_conf['instance_hostname'], edge_conf['ssh_key_path'], json.dumps(additional_config),
+ edge_conf['dlab_ssh_user'])
+ try:
+ local("~/scripts/{}.py {}".format('configure_nftables', params))
+ except:
+ traceback.print_exc()
+ raise Exception
+ except Exception as err:
+ dlab.fab.append_result("Failed to configure NAT." + str(err))
+ clear_resources()
+ sys.exit(1)
+
+ try:
print('[SUMMARY]')
logging.info('[SUMMARY]')
print("Instance name: {}".format(edge_conf['instance_name']))
diff --git a/infrastructure-provisioning/src/general/scripts/gcp/jupyter_dataengine-service_create_configs.py b/infrastructure-provisioning/src/general/scripts/gcp/jupyter_dataengine-service_create_configs.py
index 9bc8e37..2e7929c 100644
--- a/infrastructure-provisioning/src/general/scripts/gcp/jupyter_dataengine-service_create_configs.py
+++ b/infrastructure-provisioning/src/general/scripts/gcp/jupyter_dataengine-service_create_configs.py
@@ -51,6 +51,8 @@
parser.add_argument('--r_version', type=str, default='')
parser.add_argument('--r_enabled', type=str, default='')
parser.add_argument('--scala_version', type=str, default='')
+parser.add_argument('--python_version', type=str, default='')
+parser.add_argument('--master_ip', type=str, default='')
args = parser.parse_args()
dataproc_dir = '/opt/{}/jars/'.format(args.dataproc_version)
@@ -82,8 +84,8 @@
spark_path = '/opt/{0}/{1}/spark/'.format(args.dataproc_version, args.cluster_name)
local('mkdir -p {0}toree_{1}/'.format(kernels_dir, args.cluster_name))
local('tar zxvf /tmp/toree_kernel.tar.gz -C {0}toree_{1}/'.format(kernels_dir, args.cluster_name))
- local('sudo mv {0}toree_{1}/toree-0.2.0-incubating/* {0}toree_{1}/'.format(kernels_dir, args.cluster_name))
- local('sudo rm -r {0}toree_{1}/toree-0.2.0-incubating'.format(kernels_dir, args.cluster_name))
+ local('sudo mv {0}toree_{1}/toree-0.3.0-incubating/* {0}toree_{1}/'.format(kernels_dir, args.cluster_name))
+ local('sudo rm -r {0}toree_{1}/toree-0.3.0-incubating'.format(kernels_dir, args.cluster_name))
kernel_path = '{0}toree_{1}/kernel.json'.format(kernels_dir, args.cluster_name)
template_file = "/tmp/toree_dataengine-service_templatev2.json"
with open(template_file, 'r') as f:
@@ -111,20 +113,47 @@
with open(run_sh_path, 'w') as f:
f.write(text)
+def install_sparkamagic_kernels(args):
+ try:
+ local('sudo jupyter nbextension enable --py --sys-prefix widgetsnbextension')
+ sparkmagic_dir = local("sudo pip3 show sparkmagic | grep 'Location: ' | awk '{print $2}'", capture=True)
+ local('sudo jupyter-kernelspec install {}/sparkmagic/kernels/sparkkernel --user'.format(sparkmagic_dir))
+ local('sudo jupyter-kernelspec install {}/sparkmagic/kernels/pysparkkernel --user'.format(sparkmagic_dir))
+ local('sudo jupyter-kernelspec install {}/sparkmagic/kernels/sparkrkernel --user'.format(sparkmagic_dir))
+ pyspark_kernel_name = 'PySpark (Python-{0} / Spark-{1} ) [{2}]'.format(args.python_version, args.spark_version,
+ args.cluster_name)
+ local('sed -i \'s|PySpark|{0}|g\' /home/{1}/.local/share/jupyter/kernels/pysparkkernel/kernel.json'.format(
+ pyspark_kernel_name, args.os_user))
+ spark_kernel_name = 'Spark (Scala-{0} / Spark-{1} ) [{2}]'.format(args.scala_version, args.spark_version,
+ args.cluster_name)
+ local('sed -i \'s|Spark|{0}|g\' /home/{1}/.local/share/jupyter/kernels/sparkkernel/kernel.json'.format(
+ spark_kernel_name, args.os_user))
+ sparkr_kernel_name = 'SparkR (R-{0} / Spark-{1} ) [{2}]'.format(args.r_version, args.spark_version,
+ args.cluster_name)
+ local('sed -i \'s|SparkR|{0}|g\' /home/{1}/.local/share/jupyter/kernels/sparkrkernel/kernel.json'.format(
+ sparkr_kernel_name, args.os_user))
+ local('mkdir -p /home/' + args.os_user + '/.sparkmagic')
+ local('cp -f /tmp/sparkmagic_config_template.json /home/' + args.os_user + '/.sparkmagic/config.json')
+ local('sed -i \'s|LIVY_HOST|{0}|g\' /home/{1}/.sparkmagic/config.json'.format(
+ args.master_ip, args.os_user))
+ local('sudo chown -R {0}:{0} /home/{0}/.sparkmagic/'.format(args.os_user))
+ except:
+ sys.exit(1)
if __name__ == "__main__":
if args.dry_run == 'true':
parser.print_help()
else:
- result = prepare(dataproc_dir, yarn_dir)
- if result == False :
- actions_lib.GCPActions().jars(args, dataproc_dir)
- actions_lib.GCPActions().yarn(args, yarn_dir)
- actions_lib.GCPActions().install_dataproc_spark(args)
- pyspark_kernel(kernels_dir, args.dataproc_version, args.cluster_name, args.spark_version, args.bucket,
- args.user_name, args.region, args.os_user, args.application, args.pip_mirror)
- toree_kernel(args)
- if args.r_enabled == 'true':
- r_kernel(args)
- actions_lib.GCPActions().spark_defaults(args)
- configuring_notebook(args.dataproc_version)
+ install_sparkamagic_kernels(args)
+ #result = prepare(dataproc_dir, yarn_dir)
+ #if result == False :
+ # actions_lib.GCPActions().jars(args, dataproc_dir)
+ #actions_lib.GCPActions().yarn(args, yarn_dir)
+ #actions_lib.GCPActions().install_dataproc_spark(args)
+ #pyspark_kernel(kernels_dir, args.dataproc_version, args.cluster_name, args.spark_version, args.bucket,
+ # args.user_name, args.region, args.os_user, args.application, args.pip_mirror)
+ #toree_kernel(args)
+ #if args.r_enabled == 'true':
+ # r_kernel(args)
+ #actions_lib.GCPActions().spark_defaults(args)
+ #configuring_notebook(args.dataproc_version)
diff --git a/infrastructure-provisioning/src/general/scripts/gcp/jupyter_install_dataengine-service_kernels.py b/infrastructure-provisioning/src/general/scripts/gcp/jupyter_install_dataengine-service_kernels.py
index cb17668..24586af 100644
--- a/infrastructure-provisioning/src/general/scripts/gcp/jupyter_install_dataengine-service_kernels.py
+++ b/infrastructure-provisioning/src/general/scripts/gcp/jupyter_install_dataengine-service_kernels.py
@@ -51,13 +51,14 @@
templates_dir = '/root/templates/'
files_dir = '/root/files/'
scripts_dir = '/root/scripts/'
- put(templates_dir + 'pyspark_dataengine-service_template.json', '/tmp/pyspark_dataengine-service_template.json')
- put(templates_dir + 'r_dataengine-service_template.json', '/tmp/r_dataengine-service_template.json')
- put(templates_dir + 'toree_dataengine-service_template.json','/tmp/toree_dataengine-service_template.json')
+ put(templates_dir + 'sparkmagic_config_template.json', '/tmp/sparkmagic_config_template.json')
+ #put(templates_dir + 'pyspark_dataengine-service_template.json', '/tmp/pyspark_dataengine-service_template.json')
+ #put(templates_dir + 'r_dataengine-service_template.json', '/tmp/r_dataengine-service_template.json')
+ #put(templates_dir + 'toree_dataengine-service_template.json','/tmp/toree_dataengine-service_template.json')
put(scripts_dir + '{}_dataengine-service_create_configs.py'.format(args.application), '/tmp/create_configs.py')
- put(files_dir + 'toree_kernel.tar.gz', '/tmp/toree_kernel.tar.gz')
- put(templates_dir + 'toree_dataengine-service_templatev2.json', '/tmp/toree_dataengine-service_templatev2.json')
- put(templates_dir + 'run_template.sh', '/tmp/run_template.sh')
+ #put(files_dir + 'toree_kernel.tar.gz', '/tmp/toree_kernel.tar.gz')
+ #put(templates_dir + 'toree_dataengine-service_templatev2.json', '/tmp/toree_dataengine-service_templatev2.json')
+ #put(templates_dir + 'run_template.sh', '/tmp/run_template.sh')
sudo('\cp /tmp/create_configs.py /usr/local/bin/create_configs.py')
sudo('chmod 755 /usr/local/bin/create_configs.py')
sudo('mkdir -p /usr/lib/python2.7/dlab/')
@@ -81,14 +82,21 @@
configure_notebook(args)
spark_version = actions_lib.GCPActions().get_cluster_app_version(args.bucket, args.project_name,
args.cluster_name, 'spark')
+ python_version = actions_lib.GCPActions().get_cluster_app_version(args.bucket, args.project_name,
+ args.cluster_name, 'python')
hadoop_version = actions_lib.GCPActions().get_cluster_app_version(args.bucket, args.project_name,
args.cluster_name, 'hadoop')
r_version = actions_lib.GCPActions().get_cluster_app_version(args.bucket, args.project_name,
args.cluster_name, 'r')
r_enabled = os.environ['notebook_r_enabled']
+ master_host = '{}-m'.format(args.cluster_name)
+ master_ip = get_instance_private_ip_address(os.environ['gcp_zone'], master_host)
sudo('echo "[global]" > /etc/pip.conf; echo "proxy = $(cat /etc/profile | grep proxy | head -n1 | cut -f2 -d=)" >> /etc/pip.conf')
sudo('echo "use_proxy=yes" > ~/.wgetrc; proxy=$(cat /etc/profile | grep proxy | head -n1 | cut -f2 -d=); echo "http_proxy=$proxy" >> ~/.wgetrc; echo "https_proxy=$proxy" >> ~/.wgetrc')
- sudo('unset http_proxy https_proxy; export gcp_project_id="{0}"; export conf_resource="{1}"; /usr/bin/python /usr/local/bin/create_configs.py --bucket {2} --cluster_name {3} --dataproc_version {4} --spark_version {5} --hadoop_version {6} --region {7} --user_name {8} --os_user {9} --pip_mirror {10} --application {11} --r_version {12} --r_enabled {13} --scala_version {14}'
+ sudo('unset http_proxy https_proxy; export gcp_project_id="{0}"; export conf_resource="{1}"; '
+ '/usr/bin/python /usr/local/bin/create_configs.py --bucket {2} --cluster_name {3} --dataproc_version {4}'
+ ' --spark_version {5} --hadoop_version {6} --region {7} --user_name {8} --os_user {9} --pip_mirror {10} '
+ '--application {11} --r_version {12} --r_enabled {13} --python_version {14} --master_ip {15} --scala_version {16}'
.format(os.environ['gcp_project_id'], os.environ['conf_resource'], args.bucket, args.cluster_name,
args.dataproc_version, spark_version, hadoop_version, args.region, args.project_name, args.os_user,
- args.pip_mirror, args.application, r_version, r_enabled, scala_version))
+ args.pip_mirror, args.application, r_version, r_enabled, python_version, master_ip, scala_version))
diff --git a/infrastructure-provisioning/src/general/scripts/gcp/project_prepare.py b/infrastructure-provisioning/src/general/scripts/gcp/project_prepare.py
index f9822a0..d42ffdf 100644
--- a/infrastructure-provisioning/src/general/scripts/gcp/project_prepare.py
+++ b/infrastructure-provisioning/src/general/scripts/gcp/project_prepare.py
@@ -539,3 +539,41 @@
GCPActions.remove_role(project_conf['edge_role_name'])
GCPActions.remove_subnet(project_conf['private_subnet_name'], project_conf['region'])
sys.exit(1)
+
+ if os.environ['edge_is_nat'] == 'true':
+ try:
+ logging.info('[CREATE NAT ROUTE]')
+ print('[REATE NAT ROUTE]')
+ nat_route_name = '{0}-{1}-{2}-nat-route'.format(project_conf['service_base_name'],
+ project_conf['project_name'],
+ project_conf['endpoint_name'])
+ edge_instance = GCPMeta.get_instance(project_conf['instance_name'])['selfLink']
+ params = "--nat_route_name {} --vpc {} --tag {} --edge_instance {}".format(nat_route_name,
+ project_conf['vpc_selflink'],
+ project_conf['ps_firewall_target'],
+ edge_instance)
+ try:
+ local("~/scripts/{}.py {}".format('common_create_nat_route', params))
+ except:
+ traceback.print_exc()
+ raise Exception
+ except Exception as err:
+ dlab.fab.append_result("Failed to create nat route.", str(err))
+ GCPActions.remove_instance(project_conf['instance_name'], project_conf['zone'])
+ GCPActions.remove_static_address(project_conf['static_address_name'], project_conf['region'])
+ GCPActions.remove_bucket(project_conf['bucket_name'])
+ GCPActions.remove_firewall(project_conf['fw_edge_ingress_public'])
+ GCPActions.remove_firewall(project_conf['fw_edge_ingress_internal'])
+ GCPActions.remove_firewall(project_conf['fw_edge_egress_public'])
+ GCPActions.remove_firewall(project_conf['fw_edge_egress_internal'])
+ GCPActions.remove_firewall(project_conf['fw_ps_ingress'])
+ GCPActions.remove_firewall(project_conf['fw_ps_egress_private'])
+ GCPActions.remove_firewall(project_conf['fw_ps_egress_public'])
+ GCPActions.remove_service_account(project_conf['ps_service_account_name'],
+ project_conf['service_base_name'])
+ GCPActions.remove_role(project_conf['ps_role_name'])
+ GCPActions.remove_service_account(project_conf['edge_service_account_name'],
+ project_conf['service_base_name'])
+ GCPActions.remove_role(project_conf['edge_role_name'])
+ GCPActions.remove_subnet(project_conf['private_subnet_name'], project_conf['region'])
+ sys.exit(1)
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/scripts/os/common_clean_instance.py b/infrastructure-provisioning/src/general/scripts/os/common_clean_instance.py
index ef8f4f8..f3dd262 100644
--- a/infrastructure-provisioning/src/general/scripts/os/common_clean_instance.py
+++ b/infrastructure-provisioning/src/general/scripts/os/common_clean_instance.py
@@ -56,7 +56,7 @@
try:
sudo('systemctl stop jupyter-notebook')
sudo('pip2 uninstall -y notebook jupyter')
- sudo('pip3.5 uninstall -y notebook jupyter')
+ sudo('pip3 uninstall -y notebook jupyter')
sudo('rm -rf /usr/local/share/jupyter/')
sudo('rm -rf /home/{}/.jupyter/'.format(args.os_user))
sudo('rm -rf /home/{}/.ipython/'.format(args.os_user))
diff --git a/infrastructure-provisioning/src/general/scripts/os/common_configure_reverse_proxy.py b/infrastructure-provisioning/src/general/scripts/os/common_configure_reverse_proxy.py
index 41454d2..53cba79 100644
--- a/infrastructure-provisioning/src/general/scripts/os/common_configure_reverse_proxy.py
+++ b/infrastructure-provisioning/src/general/scripts/os/common_configure_reverse_proxy.py
@@ -106,8 +106,8 @@
env['connection_attempts'] = 100
env.key_filename = [args.keyfile]
env.host_string = args.os_user + '@' + args.edge_hostname
- put('/tmp/{}.conf'.format(conf_file_name), '/etc/nginx/locations', use_sudo=True)
- sudo('service nginx reload')
+ put('/tmp/{}.conf'.format(conf_file_name), '/usr/local/openresty/nginx/conf/locations', use_sudo=True)
+ sudo('service openresty reload')
diff --git a/infrastructure-provisioning/src/general/scripts/os/deeplearning_dataengine_create_configs.py b/infrastructure-provisioning/src/general/scripts/os/deeplearning_dataengine_create_configs.py
index cc65bc5..924489d 100644
--- a/infrastructure-provisioning/src/general/scripts/os/deeplearning_dataengine_create_configs.py
+++ b/infrastructure-provisioning/src/general/scripts/os/deeplearning_dataengine_create_configs.py
@@ -88,9 +88,9 @@
text = text.replace('SPARK_VERSION', 'Spark-' + spark_version)
text = text.replace('SPARK_PATH', spark_path)
text = text.replace('MASTER', args.spark_master)
- text = text.replace('PYTHON_SHORT_VERSION', '3.5')
- text = text.replace('PYTHON_FULL_VERSION', '3.5')
- text = text.replace('PYTHON_PATH', '/usr/bin/python3.5')
+ text = text.replace('PYTHON_SHORT_VERSION', '3.6')
+ text = text.replace('PYTHON_FULL_VERSION', '3.6')
+ text = text.replace('PYTHON_PATH', '/usr/bin/python3.6')
with open(kernel_path, 'w') as f:
f.write(text)
local('touch /tmp/{}/kernel_var.json'.format(args.cluster_name))
diff --git a/infrastructure-provisioning/src/general/scripts/os/get_list_available_pkgs.py b/infrastructure-provisioning/src/general/scripts/os/get_list_available_pkgs.py
index 48d22a1..3d2b4b6 100644
--- a/infrastructure-provisioning/src/general/scripts/os/get_list_available_pkgs.py
+++ b/infrastructure-provisioning/src/general/scripts/os/get_list_available_pkgs.py
@@ -84,7 +84,7 @@
if os.environ['application'] in ('jupyter', 'jupyterlab', 'zeppelin', 'deeplearning', 'tensor', 'tensor-rstudio', 'rstudio'):
all_pkgs['pip2'] = get_available_pip_pkgs("2.7")
- all_pkgs['pip3'] = get_available_pip_pkgs("3.5")
+ all_pkgs['pip3'] = get_available_pip_pkgs("3.6")
all_pkgs['others'] = get_uncategorised_pip_pkgs(all_pkgs['pip2'], all_pkgs['pip3'])
if (os.environ['application'] in ('jupyter', 'jupyterlab', 'zeppelin')
diff --git a/infrastructure-provisioning/src/general/scripts/os/install_additional_libs.py b/infrastructure-provisioning/src/general/scripts/os/install_additional_libs.py
index d2ce331..c57b2c9 100644
--- a/infrastructure-provisioning/src/general/scripts/os/install_additional_libs.py
+++ b/infrastructure-provisioning/src/general/scripts/os/install_additional_libs.py
@@ -97,12 +97,16 @@
try:
print('Installing other packages: {}'.format(pkgs['libraries']['others']))
for pkg in pkgs['libraries']['others']:
- status_pip2 = install_pip_pkg([pkg], 'pip2', 'others')
- status_pip3 = install_pip_pkg([pkg], 'pip3', 'others')
- if status_pip2[0]['status'] == 'installed':
- general_status = general_status + status_pip2
- else:
+ if os.environ['conf_resource'] in ('dataengine-service'):#, 'dataengine'):
+ status_pip3 = install_pip_pkg([pkg], 'pip3', 'others')
general_status = general_status + status_pip3
+ else:
+ status_pip2 = install_pip_pkg([pkg], 'pip2', 'others')
+ status_pip3 = install_pip_pkg([pkg], 'pip3', 'others')
+ if status_pip2[0]['status'] == 'installed':
+ general_status = general_status + status_pip2
+ else:
+ general_status = general_status + status_pip3
except KeyError:
pass
@@ -111,6 +115,13 @@
or os.environ['application'] in ('rstudio', 'tensor-rstudio'):
try:
print('Installing R packages: {}'.format(pkgs['libraries']['r_pkg']))
+ if os.environ['conf_resource'] in ('dataengine-service') :
+ if os.environ['conf_cloud_provider'] in ('aws'):
+ manage_pkg('-y install', 'remote', 'libcurl libcurl-devel')
+ elif os.environ['conf_cloud_provider'] in ('gcp'):
+ manage_pkg('-y build-dep', 'remote', 'libcurl4-gnutls-dev libxml2-dev')
+ manage_pkg('-y install', 'remote', 'libcurl4-gnutls-dev libxml2-dev')
+ sudo('R -e "install.packages(\'devtools\', repos = \'https://cloud.r-project.org\')"')
status = install_r_pkg(pkgs['libraries']['r_pkg'])
general_status = general_status + status
except KeyError:
diff --git a/infrastructure-provisioning/src/general/scripts/os/jupyter_dataengine_create_configs.py b/infrastructure-provisioning/src/general/scripts/os/jupyter_dataengine_create_configs.py
index 60a3246..cf0639c 100644
--- a/infrastructure-provisioning/src/general/scripts/os/jupyter_dataengine_create_configs.py
+++ b/infrastructure-provisioning/src/general/scripts/os/jupyter_dataengine_create_configs.py
@@ -82,8 +82,8 @@
scala_version = local('spark-submit --version 2>&1 | grep -o -P "Scala version \K.{0,7}"', capture=True)
local('mkdir -p ' + kernels_dir + 'toree_' + args.cluster_name + '/')
local('tar zxvf /tmp/{}/toree_kernel.tar.gz -C '.format(args.cluster_name) + kernels_dir + 'toree_' + args.cluster_name + '/')
- local('sudo mv {0}toree_{1}/toree-0.2.0-incubating/* {0}toree_{1}/'.format(kernels_dir, args.cluster_name))
- local('sudo rm -r {0}toree_{1}/toree-0.2.0-incubating'.format(kernels_dir, args.cluster_name))
+ local('sudo mv {0}toree_{1}/toree-0.3.0-incubating/* {0}toree_{1}/'.format(kernels_dir, args.cluster_name))
+ local('sudo rm -r {0}toree_{1}/toree-0.3.0-incubating'.format(kernels_dir, args.cluster_name))
kernel_path = kernels_dir + "toree_" + args.cluster_name + "/kernel.json"
template_file = "/tmp/{}/toree_dataengine_template.json".format(args.cluster_name)
with open(template_file, 'r') as f:
@@ -143,9 +143,9 @@
text = text.replace('SPARK_VERSION', 'Spark-' + spark_version)
text = text.replace('SPARK_PATH', spark_path)
text = text.replace('MASTER', args.spark_master)
- text = text.replace('PYTHON_SHORT_VERSION', '3.5')
- text = text.replace('PYTHON_FULL_VERSION', '3.5')
- text = text.replace('PYTHON_PATH', '/usr/bin/python3.5')
+ text = text.replace('PYTHON_SHORT_VERSION', '3.6')
+ text = text.replace('PYTHON_FULL_VERSION', '3.6')
+ text = text.replace('PYTHON_PATH', '/usr/bin/python3.6')
with open(kernel_path, 'w') as f:
f.write(text)
local('touch /tmp/{}/kernel_var.json'.format(args.cluster_name))
@@ -154,17 +154,54 @@
format(args.cluster_name, kernel_path, args.os_user))
local('sudo mv /tmp/{}/kernel_var.json '.format(args.cluster_name) + kernel_path)
+def install_sparkamagic_kernels(args):
+ try:
+ local('sudo jupyter nbextension enable --py --sys-prefix widgetsnbextension')
+ sparkmagic_dir = local("sudo pip3 show sparkmagic | grep 'Location: ' | awk '{print $2}'", capture=True)
+ local('sudo jupyter-kernelspec install {}/sparkmagic/kernels/sparkkernel --user'.format(sparkmagic_dir))
+ local('sudo jupyter-kernelspec install {}/sparkmagic/kernels/pysparkkernel --user'.format(sparkmagic_dir))
+ local('sudo jupyter-kernelspec install {}/sparkmagic/kernels/sparkrkernel --user'.format(sparkmagic_dir))
+ pyspark_kernel_name = 'PySpark (Python-3.6 / Spark-{0} ) [{1}]'.format(args.spark_version,
+ args.cluster_name)
+ local('sed -i \'s|PySpark|{0}|g\' /home/{1}/.local/share/jupyter/kernels/pysparkkernel/kernel.json'.format(
+ pyspark_kernel_name, args.os_user))
+ scala_version = local('spark-submit --version 2>&1 | grep -o -P "Scala version \K.{0,7}"', capture=True)
+ spark_kernel_name = 'Spark (Scala-{0} / Spark-{1} ) [{2}]'.format(scala_version, args.spark_version,
+ args.cluster_name)
+ local('sed -i \'s|Spark|{0}|g\' /home/{1}/.local/share/jupyter/kernels/sparkkernel/kernel.json'.format(
+ spark_kernel_name, args.os_user))
+ r_version = local("R --version | awk '/version / {print $3}'", capture=True)
+ sparkr_kernel_name = 'SparkR (R-{0} / Spark-{1} ) [{2}]'.format(str(r_version), args.spark_version,
+ args.cluster_name)
+ local('sed -i \'s|SparkR|{0}|g\' /home/{1}/.local/share/jupyter/kernels/sparkrkernel/kernel.json'.format(
+ sparkr_kernel_name, args.os_user))
+ local('sudo mv -f /home/{0}/.local/share/jupyter/kernels/pysparkkernel '
+ '/home/{0}/.local/share/jupyter/kernels/pysparkkernel_{1}'.format(args.os_user, args.cluster_name))
+ local('sudo mv -f /home/{0}/.local/share/jupyter/kernels/sparkkernel '
+ '/home/{0}/.local/share/jupyter/kernels/sparkkernel_{1}'.format(args.os_user, args.cluster_name))
+ local('sudo mv -f /home/{0}/.local/share/jupyter/kernels/sparkrkernel '
+ '/home/{0}/.local/share/jupyter/kernels/sparkrkernel_{1}'.format(args.os_user, args.cluster_name))
+ local('mkdir -p /home/' + args.os_user + '/.sparkmagic')
+ local('cp -f /tmp/sparkmagic_config_template.json /home/' + args.os_user + '/.sparkmagic/config.json')
+ spark_master_ip = args.spark_master.split('//')[1].split(':')[0]
+ local('sed -i \'s|LIVY_HOST|{0}|g\' /home/{1}/.sparkmagic/config.json'.format(
+ spark_master_ip, args.os_user))
+ local('sudo chown -R {0}:{0} /home/{0}/.sparkmagic/'.format(args.os_user))
+ except:
+ sys.exit(1)
+
if __name__ == "__main__":
if args.dry_run == 'true':
parser.print_help()
else:
- dataengine_dir_prepare('/opt/{}/'.format(args.cluster_name))
- install_dataengine_spark(args.cluster_name, spark_link, spark_version, hadoop_version, cluster_dir, args.os_user,
- args.datalake_enabled)
- configure_dataengine_spark(args.cluster_name, local_jars_dir, cluster_dir, args.datalake_enabled,
- args.spark_configurations)
- pyspark_kernel(args)
- toree_kernel(args)
- if args.r_enabled == 'true':
- r_kernel(args)
+ install_sparkamagic_kernels(args)
+ #dataengine_dir_prepare('/opt/{}/'.format(args.cluster_name))
+ #install_dataengine_spark(args.cluster_name, spark_link, spark_version, hadoop_version, cluster_dir, args.os_user,
+ # args.datalake_enabled)
+ #configure_dataengine_spark(args.cluster_name, local_jars_dir, cluster_dir, args.datalake_enabled,
+ # args.spark_configurations)
+ #pyspark_kernel(args)
+ #toree_kernel(args)
+ #if args.r_enabled == 'true':
+ # r_kernel(args)
diff --git a/infrastructure-provisioning/src/general/scripts/os/jupyter_install_dataengine_kernels.py b/infrastructure-provisioning/src/general/scripts/os/jupyter_install_dataengine_kernels.py
index 9b984af..01afe7b 100644
--- a/infrastructure-provisioning/src/general/scripts/os/jupyter_install_dataengine_kernels.py
+++ b/infrastructure-provisioning/src/general/scripts/os/jupyter_install_dataengine_kernels.py
@@ -46,12 +46,13 @@
files_dir = '/root/files/'
scripts_dir = '/root/scripts/'
run('mkdir -p /tmp/{}/'.format(args.cluster_name))
- put(templates_dir + 'pyspark_dataengine_template.json', '/tmp/{}/pyspark_dataengine_template.json'.format(args.cluster_name))
- put(templates_dir + 'r_dataengine_template.json', '/tmp/{}/r_dataengine_template.json'.format(args.cluster_name))
- put(templates_dir + 'toree_dataengine_template.json','/tmp/{}/toree_dataengine_template.json'.format(args.cluster_name))
- put(files_dir + 'toree_kernel.tar.gz', '/tmp/{}/toree_kernel.tar.gz'.format(args.cluster_name))
- put(templates_dir + 'toree_dataengine_template.json', '/tmp/{}/toree_dataengine_template.json'.format(args.cluster_name))
- put(templates_dir + 'run_template.sh', '/tmp/{}/run_template.sh'.format(args.cluster_name))
+ put(templates_dir + 'sparkmagic_config_template.json', '/tmp/sparkmagic_config_template.json')
+ #put(templates_dir + 'pyspark_dataengine_template.json', '/tmp/{}/pyspark_dataengine_template.json'.format(args.cluster_name))
+ #put(templates_dir + 'r_dataengine_template.json', '/tmp/{}/r_dataengine_template.json'.format(args.cluster_name))
+ #put(templates_dir + 'toree_dataengine_template.json','/tmp/{}/toree_dataengine_template.json'.format(args.cluster_name))
+ #put(files_dir + 'toree_kernel.tar.gz', '/tmp/{}/toree_kernel.tar.gz'.format(args.cluster_name))
+ #put(templates_dir + 'toree_dataengine_template.json', '/tmp/{}/toree_dataengine_template.json'.format(args.cluster_name))
+ #put(templates_dir + 'run_template.sh', '/tmp/{}/run_template.sh'.format(args.cluster_name))
put(templates_dir + 'notebook_spark-defaults_local.conf', '/tmp/{}/notebook_spark-defaults_local.conf'.format(args.cluster_name))
spark_master_ip = args.spark_master.split('//')[1].split(':')[0]
spark_memory = get_spark_memory(True, args.os_user, spark_master_ip, keyfile)
@@ -86,7 +87,7 @@
create_inactivity_log(args.spark_master_ip, env.host_string)
sudo('/usr/bin/python /usr/local/bin/jupyter_dataengine_create_configs.py '
'--cluster_name {} --spark_version {} --hadoop_version {} --os_user {} \
- --spark_master {} --region {} --datalake_enabled {} --r_enabled {} --spark_configurations "{}"'.
+ --spark_master {} --datalake_enabled {} --r_enabled {} --spark_configurations "{}"'.
format(args.cluster_name, args.spark_version, args.hadoop_version, args.os_user, args.spark_master,
- region, args.datalake_enabled, r_enabled, os.environ['spark_configurations']))
+ args.datalake_enabled, r_enabled, os.environ['spark_configurations']))
diff --git a/infrastructure-provisioning/src/general/scripts/os/jupyterlab_container_start.py b/infrastructure-provisioning/src/general/scripts/os/jupyterlab_container_start.py
index c4ff97b..77b00a4 100644
--- a/infrastructure-provisioning/src/general/scripts/os/jupyterlab_container_start.py
+++ b/infrastructure-provisioning/src/general/scripts/os/jupyterlab_container_start.py
@@ -38,7 +38,7 @@
def start_jupyterlab_container(jupyterlab_dir):
try:
with cd('{}'.format(jupyterlab_dir)):
- run('docker build --file Dockerfile_jupyterlab -t jupyter-lab .'.format(args.os_user))
+ run('docker build --network=host --file Dockerfile_jupyterlab -t jupyter-lab .'.format(args.os_user))
container_id = run('docker ps | awk \'NR==2{print $1}\'')
if container_id != '':
run('docker stop ' + container_id)
diff --git a/infrastructure-provisioning/src/general/scripts/os/tensor_dataengine_create_configs.py b/infrastructure-provisioning/src/general/scripts/os/tensor_dataengine_create_configs.py
index b26a713..2190879 100644
--- a/infrastructure-provisioning/src/general/scripts/os/tensor_dataengine_create_configs.py
+++ b/infrastructure-provisioning/src/general/scripts/os/tensor_dataengine_create_configs.py
@@ -88,9 +88,9 @@
text = text.replace('SPARK_VERSION', 'Spark-' + spark_version)
text = text.replace('SPARK_PATH', spark_path)
text = text.replace('MASTER', args.spark_master)
- text = text.replace('PYTHON_SHORT_VERSION', '3.5')
- text = text.replace('PYTHON_FULL_VERSION', '3.5')
- text = text.replace('PYTHON_PATH', '/usr/bin/python3.5')
+ text = text.replace('PYTHON_SHORT_VERSION', '3.6')
+ text = text.replace('PYTHON_FULL_VERSION', '3.6')
+ text = text.replace('PYTHON_PATH', '/usr/bin/python3.6')
with open(kernel_path, 'w') as f:
f.write(text)
local('touch /tmp/{}/kernel_var.json'.format(args.cluster_name))
diff --git a/infrastructure-provisioning/src/general/scripts/os/zeppelin_dataengine_create_configs.py b/infrastructure-provisioning/src/general/scripts/os/zeppelin_dataengine_create_configs.py
index 7e7cfc2..78b591d 100644
--- a/infrastructure-provisioning/src/general/scripts/os/zeppelin_dataengine_create_configs.py
+++ b/infrastructure-provisioning/src/general/scripts/os/zeppelin_dataengine_create_configs.py
@@ -96,7 +96,7 @@
if os.path.exists(livy_path + 'conf/spark-blacklist.conf'):
local('sudo sed -i "s/^/#/g" ' + livy_path + 'conf/spark-blacklist.conf')
local(''' sudo echo "export SPARK_HOME=''' + cluster_dir + '''spark/" >> ''' + livy_path + '''conf/livy-env.sh''')
- local(''' sudo echo "export PYSPARK3_PYTHON=python3.5" >> ''' +
+ local(''' sudo echo "export PYSPARK3_PYTHON=python3.6" >> ''' +
livy_path + '''conf/livy-env.sh''')
template_file = "/tmp/{}/dataengine_interpreter.json".format(args.cluster_name)
fr = open(template_file, 'r+')
@@ -127,7 +127,7 @@
local('sudo systemctl start livy-server-' + str(livy_port))
else:
template_file = "/tmp/{}/dataengine_interpreter.json".format(args.cluster_name)
- p_versions = ["2", "3.5"]
+ p_versions = ["2", "3.6"]
for p_version in p_versions:
fr = open(template_file, 'r+')
text = fr.read()
diff --git a/infrastructure-provisioning/src/general/templates/gcp/dataengine-service_cluster.json b/infrastructure-provisioning/src/general/templates/gcp/dataengine-service_cluster.json
index 9f8367d..e6ec49b 100644
--- a/infrastructure-provisioning/src/general/templates/gcp/dataengine-service_cluster.json
+++ b/infrastructure-provisioning/src/general/templates/gcp/dataengine-service_cluster.json
@@ -14,7 +14,10 @@
},
"tags": [
"CLUSTER_TAG"
- ]
+ ],
+ "metadata": {
+ "livy-version": "0.6.0"
+ }
},
"masterConfig": {
"numInstances": "NUM_MASTERS",
@@ -38,6 +41,11 @@
},
"softwareConfig": {
"imageVersion": "IMAGE_VERSION"
- }
+ },
+ "initializationActions": [
+ {
+ "executableFile": "LIVY"
+ }
+ ]
}
}
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/templates/os/debian/livy.service b/infrastructure-provisioning/src/general/templates/os/debian/livy.service
new file mode 100644
index 0000000..a37f1f8
--- /dev/null
+++ b/infrastructure-provisioning/src/general/templates/os/debian/livy.service
@@ -0,0 +1,35 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
+[Unit]
+Description=Apache Livy service
+After=network.target
+
+[Service]
+Group=OS_USER
+User=OS_USER
+Type=forking
+ExecStart=/opt/livy/bin/livy-server start
+ExecStop=/opt/livy/bin/livy-server stop
+Restart=on-failure
+
+[Install]
+WantedBy=multi-user.target
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/templates/os/livy-env.sh b/infrastructure-provisioning/src/general/templates/os/livy-env.sh
new file mode 100644
index 0000000..e9a5738
--- /dev/null
+++ b/infrastructure-provisioning/src/general/templates/os/livy-env.sh
@@ -0,0 +1,22 @@
+#!/usr/bin/env bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# LIVY ENVIRONMENT VARIABLES
+#
+export SPARK_HOME=/opt/spark
+export SPARK_CONF_DIR=/opt/spark/conf
+export LIVY_LOG_DIR=/var/log/livy
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/templates/os/py3spark_local_template.json b/infrastructure-provisioning/src/general/templates/os/py3spark_local_template.json
index 969228e..e03c629 100644
--- a/infrastructure-provisioning/src/general/templates/os/py3spark_local_template.json
+++ b/infrastructure-provisioning/src/general/templates/os/py3spark_local_template.json
@@ -1,15 +1,15 @@
{
"argv": [
- "/usr/bin/python3.5",
+ "/usr/bin/python3",
"-m",
"ipykernel",
"-f",
"{connection_file}"
],
"language": "python",
- "display_name": "Local PySpark (Python-3.5 / Spark-SP_VER )",
+ "display_name": "Local PySpark (Python-3.6 / Spark-SP_VER )",
"env": {
- "PYSPARK_PYTHON": "python3.5",
+ "PYSPARK_PYTHON": "python3.6",
"SPARK_HOME": "/opt/spark/",
"PYTHONPATH": "PY4J:/opt/spark/python/:",
"PYTHONSTARTUP": "/opt/spark/python/pyspark/shell.py",
diff --git a/infrastructure-provisioning/src/general/templates/os/sparkmagic_config_template.json b/infrastructure-provisioning/src/general/templates/os/sparkmagic_config_template.json
new file mode 100644
index 0000000..e6fa8ef
--- /dev/null
+++ b/infrastructure-provisioning/src/general/templates/os/sparkmagic_config_template.json
@@ -0,0 +1,20 @@
+{
+ "kernel_python_credentials" : {
+ "username": "",
+ "password": "",
+ "url": "http://LIVY_HOST:8998",
+ "auth": "None"
+ },
+ "kernel_scala_credentials" : {
+ "username": "",
+ "password": "",
+ "url": "http://LIVY_HOST:8998",
+ "auth": "None"
+ },
+ "kernel_r_credentials": {
+ "username": "",
+ "password": "",
+ "url": "http://LIVY_HOST:8998",
+ "auth": "None"
+ }
+}
\ No newline at end of file
diff --git a/infrastructure-provisioning/src/general/templates/os/tensorboard.service b/infrastructure-provisioning/src/general/templates/os/tensorboard.service
index a4a1d68..f7dee8b 100644
--- a/infrastructure-provisioning/src/general/templates/os/tensorboard.service
+++ b/infrastructure-provisioning/src/general/templates/os/tensorboard.service
@@ -25,7 +25,7 @@
[Service]
Type=simple
PIDFile=/var/run/tensorboard.pid
-ExecStart=/bin/bash -c "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/cudnn/lib64:/usr/local/cuda/lib64; tensorboard --logdir=/var/log/tensorboard --port 6006"
+ExecStart=/bin/bash -c "export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/cudnn/lib64:/usr/local/cuda/lib64; tensorboard --logdir=/var/log/tensorboard --host 0.0.0.0 --port 6006"
ExecStop=/bin/bash -c "for i in $(ps aux | grep 'tensorboard' | grep -v grep | awk '{print $2}'); do kill -9 $i; done"
User=OS_USR
Group=OS_USR
diff --git a/infrastructure-provisioning/src/jupyter/scripts/configure_jupyter_node.py b/infrastructure-provisioning/src/jupyter/scripts/configure_jupyter_node.py
index 94ad123..11b42cd 100644
--- a/infrastructure-provisioning/src/jupyter/scripts/configure_jupyter_node.py
+++ b/infrastructure-provisioning/src/jupyter/scripts/configure_jupyter_node.py
@@ -63,7 +63,7 @@
templates_dir = '/root/templates/'
files_dir = '/root/files/'
local_spark_path = '/opt/spark/'
-toree_link = 'http://archive.apache.org/dist/incubator/toree/0.2.0-incubating/toree-pip/toree-0.2.0.tar.gz'
+toree_link = 'http://archive.apache.org/dist/incubator/toree/0.3.0-incubating/toree-pip/toree-0.3.0.tar.gz'
r_libs = ['R6', 'pbdZMQ', 'RCurl', 'devtools', 'reshape2', 'caTools', 'rJava', 'ggplot2']
gitlab_certfile = os.environ['conf_gitlab_certfile']
diff --git a/infrastructure-provisioning/src/jupyterlab/scripts/configure_jupyterlab_node.py b/infrastructure-provisioning/src/jupyterlab/scripts/configure_jupyterlab_node.py
index 1486ff3..f50de32 100644
--- a/infrastructure-provisioning/src/jupyterlab/scripts/configure_jupyterlab_node.py
+++ b/infrastructure-provisioning/src/jupyterlab/scripts/configure_jupyterlab_node.py
@@ -71,7 +71,7 @@
templates_dir = '/root/templates/'
files_dir = '/root/files/'
local_spark_path = '/opt/spark/'
-toree_link = 'http://archive.apache.org/dist/incubator/toree/0.2.0-incubating/toree-pip/toree-0.2.0.tar.gz'
+toree_link = 'http://archive.apache.org/dist/incubator/toree/0.3.0-incubating/toree-pip/toree-0.3.0.tar.gz'
r_libs = ['R6', 'pbdZMQ', 'RCurl', 'devtools', 'reshape2', 'caTools', 'rJava', 'ggplot2']
gitlab_certfile = os.environ['conf_gitlab_certfile']
diff --git a/infrastructure-provisioning/src/project/scripts/configure_nftables.py b/infrastructure-provisioning/src/project/scripts/configure_nftables.py
new file mode 100644
index 0000000..de4dc12
--- /dev/null
+++ b/infrastructure-provisioning/src/project/scripts/configure_nftables.py
@@ -0,0 +1,52 @@
+#!/usr/bin/python
+
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
+from fabric.api import *
+from fabric.contrib.files import exists
+from dlab.edge_lib import configure_nftables
+import argparse
+import json
+import sys
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--hostname', type=str, default='')
+parser.add_argument('--keyfile', type=str, default='')
+parser.add_argument('--user', type=str, default='')
+parser.add_argument('--additional_config', type=str, default='{"empty":"string"}')
+args = parser.parse_args()
+
+##############
+# Run script #
+##############
+if __name__ == "__main__":
+ print("Configure connections")
+ try:
+ env['connection_attempts'] = 100
+ env.key_filename = [args.keyfile]
+ env.host_string = '{}@{}'.format(args.user, args.hostname)
+ deeper_config = json.loads(args.additional_config)
+ except:
+ sys.exit(2)
+
+ print("Configuring nftables on edge node.")
+ configure_nftables(deeper_config)
diff --git a/infrastructure-provisioning/src/project/templates/nftables.conf b/infrastructure-provisioning/src/project/templates/nftables.conf
new file mode 100644
index 0000000..f5d4404
--- /dev/null
+++ b/infrastructure-provisioning/src/project/templates/nftables.conf
@@ -0,0 +1,22 @@
+#!/usr/sbin/nft -f
+
+flush ruleset
+
+table inet filter {
+ chain input {
+ type filter hook input priority 0;
+ }
+ chain forward {
+ type filter hook forward priority 0;
+ }
+ chain output {
+ type filter hook output priority 0;
+ }
+}
+
+table ip nat {
+ chain postrouting {
+ type nat hook postrouting priority 100; policy accept;
+ ip saddr SUBNET_CIDR oif "INTERFACE" snat to EDGE_IP
+ }
+}
diff --git a/infrastructure-provisioning/src/project/templates/nginx.conf b/infrastructure-provisioning/src/project/templates/nginx.conf
index d012375..698e25d 100644
--- a/infrastructure-provisioning/src/project/templates/nginx.conf
+++ b/infrastructure-provisioning/src/project/templates/nginx.conf
@@ -19,25 +19,29 @@
#
# ******************************************************************************
user nginx;
-worker_processes 1;
-error_log /var/log/nginx/error.log;
-pid /run/nginx.pid;
+worker_processes 1;
-load_module /etc/nginx/modules/ndk_http_module.so;
-load_module /etc/nginx/modules/ngx_http_lua_module.so;
+error_log logs/error.log;
+error_log logs/error.log notice;
+error_log logs/error.log info;
-include /usr/share/nginx/modules/*.conf;
+pid logs/nginx.pid;
+
events {
- worker_connections 1024;
+ worker_connections 1024;
}
+
http {
+ include mime.types;
+ default_type application/octet-stream;
+
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
- access_log /var/log/nginx/access.log main;
+ access_log logs/access.log main;
sendfile on;
tcp_nopush on;
@@ -50,11 +54,6 @@
resolver 8.8.8.8;
resolver_timeout 10s;
- include /etc/nginx/mime.types;
- default_type application/octet-stream;
-
- lua_shared_dict discovery 1m;
- lua_shared_dict jwks 1m;
-
- include /etc/nginx/conf.d/*.conf;
+ include /usr/local/openresty/nginx/conf/conf.d/*.conf;
}
+
diff --git a/infrastructure-provisioning/src/ssn/scripts/configure_docker.py b/infrastructure-provisioning/src/ssn/scripts/configure_docker.py
index 727f97e..f0dd69a 100644
--- a/infrastructure-provisioning/src/ssn/scripts/configure_docker.py
+++ b/infrastructure-provisioning/src/ssn/scripts/configure_docker.py
@@ -58,13 +58,13 @@
def download_toree():
toree_path = '/opt/dlab/sources/infrastructure-provisioning/src/general/files/os/'
- tarball_link = 'https://archive.apache.org/dist/incubator/toree/0.2.0-incubating/toree/toree-0.2.0-incubating-bin.tar.gz'
- jar_link = 'https://repo1.maven.org/maven2/org/apache/toree/toree-assembly/0.2.0-incubating/toree-assembly-0.2.0-incubating.jar'
+ tarball_link = 'https://archive.apache.org/dist/incubator/toree/0.3.0-incubating/toree/toree-0.3.0-incubating-bin.tar.gz'
+ jar_link = 'https://repo1.maven.org/maven2/org/apache/toree/toree-assembly/0.3.0-incubating/toree-assembly-0.3.0-incubating.jar'
try:
run('wget {}'.format(tarball_link))
run('wget {}'.format(jar_link))
- run('mv toree-0.2.0-incubating-bin.tar.gz {}toree_kernel.tar.gz'.format(toree_path))
- run('mv toree-assembly-0.2.0-incubating.jar {}toree-assembly-0.2.0.jar'.format(toree_path))
+ run('mv toree-0.3.0-incubating-bin.tar.gz {}toree_kernel.tar.gz'.format(toree_path))
+ run('mv toree-assembly-0.3.0-incubating.jar {}toree-assembly-0.3.0.jar'.format(toree_path))
except Exception as err:
traceback.print_exc()
print('Failed to download toree: ', str(err))
diff --git a/infrastructure-provisioning/src/ssn/scripts/configure_ssn_node.py b/infrastructure-provisioning/src/ssn/scripts/configure_ssn_node.py
index 9993a70..53614d2 100644
--- a/infrastructure-provisioning/src/ssn/scripts/configure_ssn_node.py
+++ b/infrastructure-provisioning/src/ssn/scripts/configure_ssn_node.py
@@ -50,6 +50,13 @@
print('Failed to set hostname: ', str(err))
sys.exit(1)
+def set_resolve():
+ try:
+ sudo('ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf')
+ except Exception as err:
+ traceback.print_exc()
+ print('Failed to set resolve: ', str(err))
+ sys.exit(1)
def cp_key(keyfile, host_string, os_user):
try:
@@ -222,6 +229,9 @@
else:
custom_ssl_cert = False
+ print('Setting resolve DNS configuration')
+ set_resolve()
+
print("Creating service directories.")
creating_service_directories(args.dlab_path, args.os_user)
diff --git a/infrastructure-provisioning/src/zeppelin/scripts/configure_zeppelin_node.py b/infrastructure-provisioning/src/zeppelin/scripts/configure_zeppelin_node.py
index fda8b1f..1afef2b 100644
--- a/infrastructure-provisioning/src/zeppelin/scripts/configure_zeppelin_node.py
+++ b/infrastructure-provisioning/src/zeppelin/scripts/configure_zeppelin_node.py
@@ -85,6 +85,8 @@
sudo('tar -zxvf /tmp/zeppelin-' + zeppelin_version + '-bin-netinst.tgz -C /opt/')
sudo('ln -s /opt/zeppelin-' + zeppelin_version + '-bin-netinst /opt/zeppelin')
sudo('cp /opt/zeppelin/conf/zeppelin-env.sh.template /opt/zeppelin/conf/zeppelin-env.sh')
+ java_home = run("update-alternatives --query java | grep -o \'/.*/java-8.*/jre\'").splitlines()[0]
+ sudo("echo 'export JAVA_HOME=\'{}\'' >> /opt/zeppelin/conf/zeppelin-env.sh".format(java_home))
sudo('cp /opt/zeppelin/conf/zeppelin-site.xml.template /opt/zeppelin/conf/zeppelin-site.xml')
sudo('sed -i \"/# export ZEPPELIN_PID_DIR/c\export ZEPPELIN_PID_DIR=/var/run/zeppelin\" /opt/zeppelin/conf/zeppelin-env.sh')
sudo('sed -i \"/# export ZEPPELIN_IDENT_STRING/c\export ZEPPELIN_IDENT_STRING=notebook\" /opt/zeppelin/conf/zeppelin-env.sh')
@@ -106,6 +108,12 @@
try:
put(templates_dir + 'zeppelin-notebook.service', '/tmp/zeppelin-notebook.service')
sudo("sed -i 's|OS_USR|" + os_user + "|' /tmp/zeppelin-notebook.service")
+ http_proxy = run('echo $http_proxy')
+ https_proxy = run('echo $https_proxy')
+ sudo('sed -i \'/\[Service\]/ a\Environment=\"HTTP_PROXY={}\"\' /tmp/zeppelin-notebook.service'.format(
+ http_proxy))
+ sudo('sed -i \'/\[Service\]/ a\Environment=\"HTTPS_PROXY={}\"\' /tmp/zeppelin-notebook.service'.format(
+ https_proxy))
sudo("chmod 644 /tmp/zeppelin-notebook.service")
sudo('cp /tmp/zeppelin-notebook.service /etc/systemd/system/zeppelin-notebook.service')
sudo('chown ' + os_user + ':' + os_user + ' -R /opt/zeppelin/')
diff --git a/infrastructure-provisioning/terraform/aws/computational_resources/main/main.tf b/infrastructure-provisioning/terraform/aws/computational_resources/main/main.tf
index 1fb08e5..ccb9781 100644
--- a/infrastructure-provisioning/terraform/aws/computational_resources/main/main.tf
+++ b/infrastructure-provisioning/terraform/aws/computational_resources/main/main.tf
@@ -1,12 +1,33 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
provider "aws" {
access_key = var.access_key_id
secret_key = var.secret_access_key
- region = var.region
+ region = var.region
}
module "common" {
- source = "../modules/common"
- sbn = var.service_base_name
+ source = "../modules/common"
+ sbn = var.service_base_name
project_name = var.project_name
project_tag = var.project_tag
endpoint_tag = var.endpoint_tag
diff --git a/infrastructure-provisioning/terraform/aws/computational_resources/main/variables.tf b/infrastructure-provisioning/terraform/aws/computational_resources/main/variables.tf
index 13f0d25..a2587e3 100644
--- a/infrastructure-provisioning/terraform/aws/computational_resources/main/variables.tf
+++ b/infrastructure-provisioning/terraform/aws/computational_resources/main/variables.tf
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
variable "access_key_id" {}
variable "secret_access_key" {}
diff --git a/infrastructure-provisioning/terraform/aws/endpoint/main/bucket.tf b/infrastructure-provisioning/terraform/aws/endpoint/main/bucket.tf
index 8a930e0..86f70f0 100644
--- a/infrastructure-provisioning/terraform/aws/endpoint/main/bucket.tf
+++ b/infrastructure-provisioning/terraform/aws/endpoint/main/bucket.tf
@@ -1,33 +1,33 @@
# *****************************************************************************
- #
- # Licensed to the Apache Software Foundation (ASF) under one
- # or more contributor license agreements. See the NOTICE file
- # distributed with this work for additional information
- # regarding copyright ownership. The ASF licenses this file
- # to you under the Apache License, Version 2.0 (the
- # "License"); you may not use this file except in compliance
- # with the License. You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing,
- # software distributed under the License is distributed on an
- # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- # KIND, either express or implied. See the License for the
- # specific language governing permissions and limitations
- # under the License.
- #
- # ******************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
- locals {
- shared_s3_name = "${var.service_base_name}-${var.endpoint_id}-shared-bucket"
- }
+locals {
+ shared_s3_name = "${var.service_base_name}-${var.endpoint_id}-shared-bucket"
+}
- resource "aws_s3_bucket" "shared_bucket" {
- bucket = local.shared_s3_name
- acl = "private"
- tags = {
- Name = local.shared_s3_name
+resource "aws_s3_bucket" "shared_bucket" {
+ bucket = local.shared_s3_name
+ acl = "private"
+ tags = {
+ Name = local.shared_s3_name
"${local.additional_tag[0]}" = local.additional_tag[1]
"${var.tag_resource_id}" = "${var.service_base_name}:${local.shared_s3_name}"
"${var.service_base_name}-tag" = local.shared_s3_name
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/.helmignore b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/.helmignore
index fbe01f8..e25078a 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/.helmignore
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/.helmignore
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/Chart.yaml b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/Chart.yaml
index 4b334aa..d133831 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/Chart.yaml
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/Chart.yaml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
apiVersion: v1
appVersion: 0.13.2
description: An online certificate authority and related tools for secure automated
@@ -6,7 +27,7 @@
home: https://smallstep.com
icon: https://raw.githubusercontent.com/smallstep/certificates/master/icon.png
keywords:
-- acme
+ - acme
- authority
- ca
- certificate
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/_helpers.tpl b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/_helpers.tpl
index e240bac..b65f748 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/_helpers.tpl
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/_helpers.tpl
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/bootstrap.yaml b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/bootstrap.yaml
index 4fa3240..3e67b22 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/bootstrap.yaml
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/bootstrap.yaml
@@ -1,11 +1,32 @@
-{{- if .Release.IsInstall -}}
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
+ {{- if .Release.IsInstall -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "step-certificates.fullname" . }}-config
namespace: {{.Release.Namespace}}
labels:
-{{ include "step-certificates.labels" . | indent 4 }}
+ {{ include "step-certificates.labels" . | indent 4 }}
---
apiVersion: batch/v1
kind: Job
@@ -24,16 +45,16 @@
serviceAccountName: {{ include "step-certificates.fullname" . }}-config
restartPolicy: Never
volumes:
- - name: bootstrap
- configMap:
- name: {{ include "step-certificates.fullname" . }}-bootstrap
+ - name: bootstrap
+ configMap:
+ name: {{ include "step-certificates.fullname" . }}-bootstrap
containers:
- - name: config
- image: "{{ .Values.bootstrapImage.repository }}:{{ .Values.bootstrapImage.tag }}"
- imagePullPolicy: {{ .Values.bootstrapImage.pullPolicy }}
- command: ["/bin/sh", "/home/step/bootstrap/bootstrap.sh"]
- volumeMounts:
- - name: bootstrap
- mountPath: /home/step/bootstrap
- readOnly: true
+ - name: config
+ image: "{{ .Values.bootstrapImage.repository }}:{{ .Values.bootstrapImage.tag }}"
+ imagePullPolicy: {{ .Values.bootstrapImage.pullPolicy }}
+ command: ["/bin/sh", "/home/step/bootstrap/bootstrap.sh"]
+ volumeMounts:
+ - name: bootstrap
+ mountPath: /home/step/bootstrap
+ readOnly: true
{{- end -}}
\ No newline at end of file
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/ca.yaml b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/ca.yaml
index 7c5929c..dde19cc 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/ca.yaml
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/ca.yaml
@@ -1,9 +1,30 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ include "step-certificates.fullname" . }}
labels:
-{{ include "step-certificates.labels" . | indent 4 }}
+ {{ include "step-certificates.labels" . | indent 4 }}
spec:
# Only one replica is supported at this moment
# Requested {{ .Values.replicaCount }}
@@ -20,99 +41,99 @@
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
{{- if .Release.IsInstall }}
- initContainers:
- - name: {{ .Chart.Name }}-init
- image: busybox:latest
- imagePullPolicy: {{ .Values.image.pullPolicy }}
- command: ["sleep", "20"]
+initContainers:
+ - name: {{ .Chart.Name }}-init
+ image: busybox:latest
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ command: ["sleep", "20"]
{{- end }}
- securityContext:
- {{- if .Values.ca.runAsRoot }}
- runAsUser: 0
- {{- else }}
- runAsUser: 1000
- runAsNonRoot: true
- runAsGroup: 1000
- fsGroup: 1000
- allowPrivilegeEscalation: false
- {{- end }}
- containers:
- - name: {{ .Chart.Name }}
- image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
- imagePullPolicy: {{ .Values.image.pullPolicy }}
- command: ["/usr/local/bin/step-ca",
- "--password-file", "/home/step/secrets/passwords/password",
- "/home/step/config/ca.json"]
- env:
- - name: NAMESPACE
- value: "{{ .Release.Namespace }}"
- ports:
- - name: https
- containerPort: {{ .Values.service.targetPort }}
- protocol: TCP
- livenessProbe:
- initialDelaySeconds: 5
- httpGet:
- path: /health
- port: {{ .Values.service.targetPort }}
- scheme: HTTPS
- readinessProbe:
- initialDelaySeconds: 5
- httpGet:
- path: /health
- port: {{ .Values.service.targetPort }}
- scheme: HTTPS
- resources:
- {{- toYaml .Values.resources | nindent 12 }}
- volumeMounts:
- - name: certs
- mountPath: /home/step/certs
- readOnly: true
- - name: config
- mountPath: /home/step/config
- readOnly: true
- - name: secrets
- mountPath: /home/step/secrets
- readOnly: true
- - name: ca-password
- mountPath: /home/step/secrets/passwords
- readOnly: true
- {{- if .Values.ca.db.enabled }}
- - name: database
- mountPath: /home/step/db
- readOnly: false
- {{- end }}
- volumes:
+securityContext:
+ {{- if .Values.ca.runAsRoot }}
+ runAsUser: 0
+ {{- else }}
+ runAsUser: 1000
+ runAsNonRoot: true
+ runAsGroup: 1000
+ fsGroup: 1000
+ allowPrivilegeEscalation: false
+ {{- end }}
+containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ command: ["/usr/local/bin/step-ca",
+ "--password-file", "/home/step/secrets/passwords/password",
+ "/home/step/config/ca.json"]
+ env:
+ - name: NAMESPACE
+ value: "{{ .Release.Namespace }}"
+ ports:
+ - name: https
+ containerPort: {{ .Values.service.targetPort }}
+ protocol: TCP
+ livenessProbe:
+ initialDelaySeconds: 5
+ httpGet:
+ path: /health
+ port: {{ .Values.service.targetPort }}
+ scheme: HTTPS
+ readinessProbe:
+ initialDelaySeconds: 5
+ httpGet:
+ path: /health
+ port: {{ .Values.service.targetPort }}
+ scheme: HTTPS
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ volumeMounts:
- name: certs
- configMap:
- name: {{ include "step-certificates.fullname" . }}-certs
+ mountPath: /home/step/certs
+ readOnly: true
- name: config
- configMap:
- name: {{ include "step-certificates.fullname" . }}-config
+ mountPath: /home/step/config
+ readOnly: true
- name: secrets
- configMap:
- name: {{ include "step-certificates.fullname" . }}-secrets
+ mountPath: /home/step/secrets
+ readOnly: true
- name: ca-password
- secret:
- secretName: {{ include "step-certificates.fullname" . }}-ca-password
- {{- if and .Values.ca.db.enabled (not .Values.ca.db.persistent) }}
- - name: database
- emptyDir: {}
- {{- end }}
- {{- with .Values.nodeSelector }}
- nodeSelector:
- {{- toYaml . | nindent 8 }}
- {{- end }}
- {{- with .Values.affinity }}
- affinity:
- {{- toYaml . | nindent 8 }}
- {{- end }}
- {{- with .Values.tolerations }}
- tolerations:
- {{- toYaml . | nindent 8 }}
- {{- end }}
+ mountPath: /home/step/secrets/passwords
+ readOnly: true
+ {{- if .Values.ca.db.enabled }}
+ - name: database
+ mountPath: /home/step/db
+ readOnly: false
+ {{- end }}
+volumes:
+ - name: certs
+ configMap:
+ name: {{ include "step-certificates.fullname" . }}-certs
+ - name: config
+configMap:
+ name: {{ include "step-certificates.fullname" . }}-config
+ - name: secrets
+configMap:
+ name: {{ include "step-certificates.fullname" . }}-secrets
+ - name: ca-password
+secret:
+ secretName: {{ include "step-certificates.fullname" . }}-ca-password
+ {{- if and .Values.ca.db.enabled (not .Values.ca.db.persistent) }}
+ - name: database
+emptyDir: {}
+ {{- end }}
+ {{- with .Values.nodeSelector }}
+nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
{{- if and .Values.ca.db.enabled .Values.ca.db.persistent }}
- volumeClaimTemplates:
+volumeClaimTemplates:
- metadata:
name: database
labels:
@@ -122,16 +143,16 @@
spec:
accessModes:
{{- range .Values.ca.db.accessModes }}
- - {{ . | quote }}
+ - {{ . | quote }}
{{- end }}
resources:
requests:
storage: {{ .Values.ca.db.size | quote }}
{{- if .Values.ca.db.storageClass }}
{{- if (eq "-" .Values.ca.db.storageClass) }}
- storageClassName: ""
+ storageClassName: ""
{{- else }}
- storageClassName: {{ .Values.ca.db.storageClass | quote }}
+ storageClassName: {{ .Values.ca.db.storageClass | quote }}
{{- end }}
{{- end }}
{{- end }}
\ No newline at end of file
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/configmaps.yaml b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/configmaps.yaml
index 28ad488..dc15383 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/configmaps.yaml
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/configmaps.yaml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
# ConfigMaps that will be updated by the configuration job:
# 1. Step CA config directory.
# 2. Step CA certs direcotry.
@@ -71,76 +92,76 @@
permission_error "create secrets"
fi
{{ if .Values.autocert.enabled }}
- echo -n "Checking for permission to create mutatingwebhookconfiguration in {{.Release.Namespace}} namespace: "
+echo -n "Checking for permission to create mutatingwebhookconfiguration in {{.Release.Namespace}} namespace: "
kubectl auth can-i create mutatingwebhookconfiguration --namespace {{.Release.Namespace}}
if [ $? -ne 0 ]; then
permission_error "create mutatingwebhookconfiguration"
- fi
+ fi
{{- end }}
- # Setting this here on purpose, after the above section which explicitly checks
- # for and handles exit errors.
- set -e
+# Setting this here on purpose, after the above section which explicitly checks
+# for and handles exit errors.
+ set -e
- echo -e "\n\e[1mInitializating the CA...\e[0m"
+ echo -e "\n\e[1mInitializating the CA...\e[0m"
- # CA password
+# CA password
{{- if .Values.ca.password }}
- CA_PASSWORD={{ quote .Values.ca.password }}
+ CA_PASSWORD={{ quote .Values.ca.password }}
{{- else }}
- CA_PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo '')
+ CA_PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo '')
{{- end }}
- # Provisioner password
+# Provisioner password
{{- if .Values.ca.provisioner.password }}
- CA_PROVISIONER_PASSWORD={{ quote .Values.ca.provisioner.password }}
+ CA_PROVISIONER_PASSWORD={{ quote .Values.ca.provisioner.password }}
{{- else }}
- CA_PROVISIONER_PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo '')
+ CA_PROVISIONER_PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo '')
{{- end }}
- TMP_CA_PASSWORD=$(mktemp /tmp/autocert.XXXXXX)
- TMP_CA_PROVISIONER_PASSWORD=$(mktemp /tmp/autocert.XXXXXX)
+ TMP_CA_PASSWORD=$(mktemp /tmp/autocert.XXXXXX)
+ TMP_CA_PROVISIONER_PASSWORD=$(mktemp /tmp/autocert.XXXXXX)
- echo $CA_PASSWORD > $TMP_CA_PASSWORD
- echo $CA_PROVISIONER_PASSWORD > $TMP_CA_PROVISIONER_PASSWORD
+ echo $CA_PASSWORD > $TMP_CA_PASSWORD
+ echo $CA_PROVISIONER_PASSWORD > $TMP_CA_PROVISIONER_PASSWORD
- step ca init \
- --name "{{.Values.ca.name}}" \
- --dns "{{include "step-certificates.dns" .}}" \
- --address "{{.Values.ca.address}}" \
- --provisioner "{{.Values.ca.provisioner.name}}" \
- --with-ca-url "{{include "step-certificates.url" .}}" \
- --password-file "$TMP_CA_PASSWORD" \
- --provisioner-password-file "$TMP_CA_PROVISIONER_PASSWORD" {{ if not .Values.ca.db.enabled }}--no-db{{ end }}
+ step ca init \
+ --name "{{.Values.ca.name}}" \
+ --dns "{{include "step-certificates.dns" .}}" \
+ --address "{{.Values.ca.address}}" \
+ --provisioner "{{.Values.ca.provisioner.name}}" \
+ --with-ca-url "{{include "step-certificates.url" .}}" \
+ --password-file "$TMP_CA_PASSWORD" \
+ --provisioner-password-file "$TMP_CA_PROVISIONER_PASSWORD" {{ if not .Values.ca.db.enabled }}--no-db{{ end }}
- rm -f $TMP_CA_PASSWORD $TMP_CA_PROVISIONER_PASSWORD
+ rm -f $TMP_CA_PASSWORD $TMP_CA_PROVISIONER_PASSWORD
- echo -e "\n\e[1mCreating configmaps and secrets in {{.Release.Namespace}} namespace ...\e[0m"
+ echo -e "\n\e[1mCreating configmaps and secrets in {{.Release.Namespace}} namespace ...\e[0m"
- # Replace secrets created on helm install
- # It allows to properly remove them on helm delete
- kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-config --from-file $(step path)/config
- kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-certs --from-file $(step path)/certs
- kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-secrets --from-file $(step path)/secrets
+ # Replace secrets created on helm install
+ # It allows to properly remove them on helm delete
+ kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-config --from-file $(step path)/config
+ kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-certs --from-file $(step path)/certs
+ kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-secrets --from-file $(step path)/secrets
- kbreplace -n {{.Release.Namespace}} create secret generic {{ include "step-certificates.fullname" . }}-ca-password --from-literal "password=${CA_PASSWORD}"
- kbreplace -n {{.Release.Namespace}} create secret generic {{ include "step-certificates.fullname" . }}-provisioner-password --from-literal "password=${CA_PROVISIONER_PASSWORD}"
+ kbreplace -n {{.Release.Namespace}} create secret generic {{ include "step-certificates.fullname" . }}-ca-password --from-literal "password=${CA_PASSWORD}"
+ kbreplace -n {{.Release.Namespace}} create secret generic {{ include "step-certificates.fullname" . }}-provisioner-password --from-literal "password=${CA_PROVISIONER_PASSWORD}"
- # Label all configmaps and secrets
- kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-config {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
- kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-certs {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
- kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-secrets {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
- kubectl -n {{.Release.Namespace}} label secret {{ include "step-certificates.fullname" . }}-ca-password {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
- kubectl -n {{.Release.Namespace}} label secret {{ include "step-certificates.fullname" . }}-provisioner-password {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
+# Label all configmaps and secrets
+kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-config {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
+kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-certs {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
+kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-secrets {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
+kubectl -n {{.Release.Namespace}} label secret {{ include "step-certificates.fullname" . }}-ca-password {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
+kubectl -n {{.Release.Namespace}} label secret {{ include "step-certificates.fullname" . }}-provisioner-password {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
- # Patch webhook if autocert is enabled
+# Patch webhook if autocert is enabled
{{ if .Values.autocert.enabled }}
- CA_BUNDLE=$(cat $(step path)/certs/root_ca.crt | base64 | tr -d '\n')
- kubectl patch mutatingwebhookconfigurations {{ .Release.Name }}-autocert-webhook-config \
- --type json -p="[{\"op\":\"replace\",\"path\":\"/webhooks/0/clientConfig/caBundle\",\"value\":\"$CA_BUNDLE\"}]"
+ CA_BUNDLE=$(cat $(step path)/certs/root_ca.crt | base64 | tr -d '\n')
+ kubectl patch mutatingwebhookconfigurations {{ .Release.Name }}-autocert-webhook-config \
+ --type json -p="[{\"op\":\"replace\",\"path\":\"/webhooks/0/clientConfig/caBundle\",\"value\":\"$CA_BUNDLE\"}]"
{{- end }}
- echo -e "\n\e[1mStep Certificates installed!\e[0m"
- echo
- echo "CA URL: {{include "step-certificates.url" .}}"
- echo "CA Fingerprint: $(step certificate fingerprint $(step path)/certs/root_ca.crt)"
- echo
\ No newline at end of file
+ echo -e "\n\e[1mStep Certificates installed!\e[0m"
+ echo
+echo "CA URL: {{include "step-certificates.url" .}}"
+echo "CA Fingerprint: $(step certificate fingerprint $(step path)/certs/root_ca.crt)"
+ echo
\ No newline at end of file
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/ingress.yaml b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/ingress.yaml
index 53264f1..3404ae7 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/ingress.yaml
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/ingress.yaml
@@ -1,36 +1,57 @@
-{{- if .Values.ingress.enabled -}}
-{{- $fullName := include "step-certificates.fullname" . -}}
+# *****************************************************************************
+#
+ # Licensed to the Apache Software Foundation (ASF) under one
+ # or more contributor license agreements. See the NOTICE file
+ # distributed with this work for additional information
+ # regarding copyright ownership. The ASF licenses this file
+ # to you under the Apache License, Version 2.0 (the
+ # "License"); you may not use this file except in compliance
+ # with the License. You may obtain a copy of the License at
+ #
+ # http://www.apache.org/licenses/LICENSE-2.0
+ #
+ # Unless required by applicable law or agreed to in writing,
+ # software distributed under the License is distributed on an
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ # KIND, either express or implied. See the License for the
+ # specific language governing permissions and limitations
+ # under the License.
+ #
+ # ******************************************************************************
+
+ {{- if .Values.ingress.enabled -}}
+ {{- $fullName := include "step-certificates.fullname" . -}}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
-{{ include "step-certificates.labels" . | indent 4 }}
+ {{ include "step-certificates.labels" . | indent 4 }}
{{- with .Values.ingress.annotations }}
- annotations:
- {{- toYaml . | nindent 4 }}
+annotations:
+ {{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.tls }}
- tls:
+tls:
{{- range .Values.ingress.tls }}
- - hosts:
- {{- range .hosts }}
- - {{ . | quote }}
- {{- end }}
- secretName: {{ .secretName }}
+- hosts:
+ {{- range .hosts }}
+ - {{ . | quote }}
+ {{- end }}
+ secretName: {{ .secretName }}
{{- end }}
{{- end }}
- rules:
+rules:
{{- range .Values.ingress.hosts }}
- - host: {{ .host | quote }}
- http:
- paths:
- {{- range .paths }}
- - path: {{ . }}
- backend:
- serviceName: {{ $fullName }}
- servicePort: http
- {{- end }}
+- host: {{ .host | quote }}
+ http:
+ paths:
+ {{- range .paths }}
+ - path: {{ . }}
+ backend:
+ serviceName: {{ $fullName }}
+ servicePort: http
+ {{- end }}
{{- end }}
{{- end }}
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/rbac.yaml b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/rbac.yaml
index 6f4e137..ebab8c4 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/rbac.yaml
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/rbac.yaml
@@ -1,4 +1,25 @@
-{{- if .Release.IsInstall -}}
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
+ {{- if .Release.IsInstall -}}
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/secrets.yaml b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/secrets.yaml
index 567a989..64f8b9b 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/secrets.yaml
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/secrets.yaml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
# Secrets that will be updated by the configuration job:
# 1. CA keys password.
# 2. Provisioner password.
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/service.yaml b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/service.yaml
index 4ec0783..fb17ab1 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/service.yaml
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/service.yaml
@@ -1,19 +1,40 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
apiVersion: v1
kind: Service
metadata:
name: {{ include "step-certificates.fullname" . }}
labels:
-{{ include "step-certificates.labels" . | indent 4 }}
+ {{ include "step-certificates.labels" . | indent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: {{ .Values.service.targetPort }}
{{- if .Values.service.nodePort }}
- nodePort: {{ .Values.service.nodePort }}
+nodePort: {{ .Values.service.nodePort }}
{{- end }}
- protocol: TCP
- name: https
- selector:
- app.kubernetes.io/name: {{ include "step-certificates.name" . }}
- app.kubernetes.io/instance: {{ .Release.Name }}
\ No newline at end of file
+protocol: TCP
+name: https
+selector:
+ app.kubernetes.io/name: {{ include "step-certificates.name" . }}
+ app.kubernetes.io/instance: {{ .Release.Name }}
\ No newline at end of file
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/tests/test-connection.yaml b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/tests/test-connection.yaml
index 5ae87c6..19375d9 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/tests/test-connection.yaml
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/templates/tests/test-connection.yaml
@@ -1,11 +1,32 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "step-certificates.fullname" . }}-test-connection"
labels:
-{{ include "step-certificates.labels" . | indent 4 }}
- annotations:
- "helm.sh/hook": test-success
+ {{ include "step-certificates.labels" . | indent 4 }}
+annotations:
+ "helm.sh/hook": test-success
spec:
containers:
- name: wget
diff --git a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/values.yaml b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/values.yaml
index a8141d6..ec99d9d 100644
--- a/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/values.yaml
+++ b/infrastructure-provisioning/terraform/aws/ssn-helm-charts/main/step-ca-chart/values.yaml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
# Default values for step-certificates.
# replicaCount is the number of replicas of step-certificates.
@@ -62,7 +83,7 @@
storageClass: ${storage_class_name}
# accessModes defines the Persistent Volume Access Mode.
accessModes:
- - ReadWriteOnce
+ - ReadWriteOnce
# size is the Persistent Volume size.
size: 10Gi
# runAsRoot runs the ca as root instead of the step user. This is required in
@@ -91,7 +112,7 @@
# memory: 128Mi
# requests:
# cpu: 100m
- # memory: 128Mi
+# memory: 128Mi
# nodeSelector contains the node labels for pod assignment.
nodeSelector: {}
diff --git a/infrastructure-provisioning/terraform/bin/deploy/billing_app_aws.yml b/infrastructure-provisioning/terraform/bin/deploy/billing_app_aws.yml
index 4fe0b75..dd33a9e 100644
--- a/infrastructure-provisioning/terraform/bin/deploy/billing_app_aws.yml
+++ b/infrastructure-provisioning/terraform/bin/deploy/billing_app_aws.yml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
spring:
main:
allow-bean-definition-overriding: true
diff --git a/infrastructure-provisioning/terraform/bin/deploy/billing_azure.yml b/infrastructure-provisioning/terraform/bin/deploy/billing_azure.yml
index 66f5418..6953d49 100644
--- a/infrastructure-provisioning/terraform/bin/deploy/billing_azure.yml
+++ b/infrastructure-provisioning/terraform/bin/deploy/billing_azure.yml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
spring:
main:
allow-bean-definition-overriding: true
diff --git a/infrastructure-provisioning/terraform/bin/deploy/billing_gcp.yml b/infrastructure-provisioning/terraform/bin/deploy/billing_gcp.yml
index e315979..af793ba 100644
--- a/infrastructure-provisioning/terraform/bin/deploy/billing_gcp.yml
+++ b/infrastructure-provisioning/terraform/bin/deploy/billing_gcp.yml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
spring:
main:
allow-bean-definition-overriding: true
diff --git a/infrastructure-provisioning/terraform/bin/deploy/endpoint_fab.py b/infrastructure-provisioning/terraform/bin/deploy/endpoint_fab.py
index fb05691..7a324d2 100644
--- a/infrastructure-provisioning/terraform/bin/deploy/endpoint_fab.py
+++ b/infrastructure-provisioning/terraform/bin/deploy/endpoint_fab.py
@@ -1,12 +1,29 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+import argparse
+import logging
+import random
+import string
+import sys
+import time
+import traceback
from fabric import Connection
from patchwork.files import exists
-import logging
-import argparse
-import sys
-import traceback
-import time
-import string
-import random
conn = None
args = None
diff --git a/infrastructure-provisioning/terraform/bin/dlab.py b/infrastructure-provisioning/terraform/bin/dlab.py
index 60af3b3..b1e7cff 100644
--- a/infrastructure-provisioning/terraform/bin/dlab.py
+++ b/infrastructure-provisioning/terraform/bin/dlab.py
@@ -1,3 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
import argparse
import itertools
import json
@@ -9,10 +26,9 @@
import sys
import time
from abc import abstractmethod
-
+from deploy.endpoint_fab import start_deploy
from fabric import Connection
from patchwork.transfers import rsync
-from deploy.endpoint_fab import start_deploy
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
logging.basicConfig(level=logging.INFO, format='%(levelname)s-%(message)s')
diff --git a/infrastructure-provisioning/terraform/bin/terraform-cli.py b/infrastructure-provisioning/terraform/bin/terraform-cli.py
index 8e1bd60..3503b58 100755
--- a/infrastructure-provisioning/terraform/bin/terraform-cli.py
+++ b/infrastructure-provisioning/terraform/bin/terraform-cli.py
@@ -1,17 +1,34 @@
#!/usr/bin/env python
-import itertools
-import json
-import os
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
import abc
import argparse
-
-import time
-from fabric import Connection
-from patchwork.transfers import rsync
+import itertools
+import json
import logging
+import os
import os.path
import sys
+import time
from deploy.endpoint_fab import start_deploy
+from fabric import Connection
+from patchwork.transfers import rsync
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
logging.basicConfig(level=logging.INFO,
diff --git a/infrastructure-provisioning/terraform/gcp/endpoint/provisioning.py b/infrastructure-provisioning/terraform/gcp/endpoint/provisioning.py
index 33e08f7..a050d02 100644
--- a/infrastructure-provisioning/terraform/gcp/endpoint/provisioning.py
+++ b/infrastructure-provisioning/terraform/gcp/endpoint/provisioning.py
@@ -1,10 +1,27 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+import argparse
+import logging
+import sys
+import time
+import traceback
from fabric import Connection
from patchwork.files import exists
-import logging
-import argparse
-import sys
-import traceback
-import time
conn = None
args = None
diff --git a/infrastructure-provisioning/terraform/gcp/main/main.tf b/infrastructure-provisioning/terraform/gcp/main/main.tf
index 3cbca78..620fbea 100644
--- a/infrastructure-provisioning/terraform/gcp/main/main.tf
+++ b/infrastructure-provisioning/terraform/gcp/main/main.tf
@@ -1,12 +1,33 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
provider "google" {
credentials = "${var.credentials}"
- project = "${var.project_name}"
- region = "${var.region_var}"
- zone = "${var.zone_var}"
+ project = "${var.project_name}"
+ region = "${var.region_var}"
+ zone = "${var.zone_var}"
}
module "common" {
- source = "../modules/common"
+ source = "../modules/common"
project_tag = "${var.project_tag}"
endpoint_tag = "${var.endpoint_tag}"
user_tag = "${var.user_tag}"
diff --git a/infrastructure-provisioning/terraform/gcp/main/variables.tf b/infrastructure-provisioning/terraform/gcp/main/variables.tf
index 2b328ee..12e7647 100644
--- a/infrastructure-provisioning/terraform/gcp/main/variables.tf
+++ b/infrastructure-provisioning/terraform/gcp/main/variables.tf
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
variable "credentials" {}
variable "project_name" {}
diff --git a/infrastructure-provisioning/terraform/gcp/modules/common/iam.tf b/infrastructure-provisioning/terraform/gcp/modules/common/iam.tf
index 6931f60..d409a34 100644
--- a/infrastructure-provisioning/terraform/gcp/modules/common/iam.tf
+++ b/infrastructure-provisioning/terraform/gcp/modules/common/iam.tf
@@ -1,11 +1,32 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
locals {
service_name = "${var.project_tag}-ps-sa"
- role_name = "${var.project_tag}-ps-role"
+ role_name = "${var.project_tag}-ps-role"
}
resource "google_service_account" "ps_sa" {
#Create service account for notebooks and computational resources
- account_id = "${var.project_tag}-ps-sa"
+ account_id = "${var.project_tag}-ps-sa"
display_name = "${var.project_tag}-ps-sa"
}
diff --git a/infrastructure-provisioning/terraform/gcp/modules/common/network.tf b/infrastructure-provisioning/terraform/gcp/modules/common/network.tf
index 8d34249..828c987 100644
--- a/infrastructure-provisioning/terraform/gcp/modules/common/network.tf
+++ b/infrastructure-provisioning/terraform/gcp/modules/common/network.tf
@@ -1,12 +1,33 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
resource "google_compute_subnetwork" "subnet" {
- name = "${var.project_tag}-subnet"
+ name = "${var.project_tag}-subnet"
ip_cidr_range = "${var.cidr_range}"
- region = "${var.region}"
- network = "${var.vpc_name}"
+ region = "${var.region}"
+ network = "${var.vpc_name}"
}
resource "google_compute_firewall" "fw_ingress" {
- name = "${var.fw_ingress}"
+ name = "${var.fw_ingress}"
network = "${var.vpc_name}"
allow {
protocol = "all"
diff --git a/infrastructure-provisioning/terraform/gcp/modules/common/variables.tf b/infrastructure-provisioning/terraform/gcp/modules/common/variables.tf
index b4180ad..ec812d0 100644
--- a/infrastructure-provisioning/terraform/gcp/modules/common/variables.tf
+++ b/infrastructure-provisioning/terraform/gcp/modules/common/variables.tf
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
variable "project_tag" {}
variable "endpoint_tag" {}
diff --git a/infrastructure-provisioning/terraform/gcp/modules/data_engine/instance.tf b/infrastructure-provisioning/terraform/gcp/modules/data_engine/instance.tf
index fdb6250..9800a35 100644
--- a/infrastructure-provisioning/terraform/gcp/modules/data_engine/instance.tf
+++ b/infrastructure-provisioning/terraform/gcp/modules/data_engine/instance.tf
@@ -1,12 +1,34 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
locals {
notebook_name = "${var.project_tag}-nb-${var.notebook_name}"
- cluster_name = "${var.project_tag}-de-${var.notebook_name}-${var.cluster_name}"
+ cluster_name = "${var.project_tag}-de-${var.notebook_name}-${var.cluster_name}"
}
resource "google_compute_instance" "master" {
- name = "${local.cluster_name}-m"
+ name = "${local.cluster_name}-m"
machine_type = "${var.master_shape}"
- tags = ["${var.network_tag}"]
+ tags = [
+ "${var.network_tag}"]
zone = "${var.zone_var}"
boot_disk {
diff --git a/infrastructure-provisioning/terraform/gcp/modules/data_engine/variables.tf b/infrastructure-provisioning/terraform/gcp/modules/data_engine/variables.tf
index 12c4f92..934df8b 100644
--- a/infrastructure-provisioning/terraform/gcp/modules/data_engine/variables.tf
+++ b/infrastructure-provisioning/terraform/gcp/modules/data_engine/variables.tf
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
variable "project_tag" {}
variable "endpoint_tag" {}
diff --git a/infrastructure-provisioning/terraform/gcp/modules/dataproc/instance.tf b/infrastructure-provisioning/terraform/gcp/modules/dataproc/instance.tf
index 415479c..3f8ec4a 100644
--- a/infrastructure-provisioning/terraform/gcp/modules/dataproc/instance.tf
+++ b/infrastructure-provisioning/terraform/gcp/modules/dataproc/instance.tf
@@ -1,42 +1,63 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
locals {
dataproc_name = "${var.project_tag}-des-${var.notebook_name}-${var.cluster_name}"
}
resource "google_dataproc_cluster" "dataproc" {
- name = "${local.dataproc_name}"
- region = "${var.region}"
- labels = {
- computational_name = "${var.cluster_name}"
- name = "${local.dataproc_name}"
- sbn = "${var.project_tag}"
- user = "${var.user_tag}"
+ name = "${local.dataproc_name}"
+ region = "${var.region}"
+ labels = {
+ computational_name = "${var.cluster_name}"
+ name = "${local.dataproc_name}"
+ sbn = "${var.project_tag}"
+ user = "${var.user_tag}"
+ }
+
+ cluster_config {
+
+ master_config {
+ num_instances = 1
+ machine_type = "${var.master_shape}"
+ disk_config {
+ boot_disk_size_gb = 30
+ }
}
- cluster_config {
-
- master_config {
- num_instances = 1
- machine_type = "${var.master_shape}"
- disk_config {
- boot_disk_size_gb = 30
- }
- }
-
- worker_config {
- num_instances = "${var.total_count - 1}"
- machine_type = "${var.slave_shape}"
- disk_config {
- boot_disk_size_gb = 30
- }
- }
-
- gce_cluster_config {
- subnetwork = "${var.subnet_name}"
- tags = ["${var.network_tag}"]
- }
-
- preemptible_worker_config {
- num_instances = "${var.preemptible_count}"
- }
+ worker_config {
+ num_instances = "${var.total_count - 1}"
+ machine_type = "${var.slave_shape}"
+ disk_config {
+ boot_disk_size_gb = 30
+ }
}
- }
\ No newline at end of file
+
+ gce_cluster_config {
+ subnetwork = "${var.subnet_name}"
+ tags = ["${var.network_tag}"]
+ }
+
+ preemptible_worker_config {
+ num_instances = "${var.preemptible_count}"
+ }
+ }
+}
\ No newline at end of file
diff --git a/infrastructure-provisioning/terraform/gcp/modules/dataproc/variables.tf b/infrastructure-provisioning/terraform/gcp/modules/dataproc/variables.tf
index d3dcf15..5b850ee 100644
--- a/infrastructure-provisioning/terraform/gcp/modules/dataproc/variables.tf
+++ b/infrastructure-provisioning/terraform/gcp/modules/dataproc/variables.tf
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
variable "region" {}
variable "project_tag" {}
diff --git a/infrastructure-provisioning/terraform/gcp/modules/notebook/instance.tf b/infrastructure-provisioning/terraform/gcp/modules/notebook/instance.tf
index 0943e51..725fab6 100644
--- a/infrastructure-provisioning/terraform/gcp/modules/notebook/instance.tf
+++ b/infrastructure-provisioning/terraform/gcp/modules/notebook/instance.tf
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
locals {
name = "${var.project_tag}-nb-${var.notebook_name}"
}
@@ -6,7 +27,7 @@
name = "${local.name}-secondary"
zone = "${var.zone_var}"
labels = {
- name = "${local.name}"
+ name = "${local.name}"
product = "${var.product}"
project = "${var.project_tag}"
user = "${var.user_tag}"
diff --git a/infrastructure-provisioning/terraform/gcp/modules/notebook/variables.tf b/infrastructure-provisioning/terraform/gcp/modules/notebook/variables.tf
index 6217480..56635ac 100644
--- a/infrastructure-provisioning/terraform/gcp/modules/notebook/variables.tf
+++ b/infrastructure-provisioning/terraform/gcp/modules/notebook/variables.tf
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
variable "project_tag" {}
variable "endpoint_tag" {}
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/files/get_configmap_values.sh b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/files/get_configmap_values.sh
index 4f27a1b..3085eb7 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/files/get_configmap_values.sh
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/files/get_configmap_values.sh
@@ -1,5 +1,26 @@
#!/bin/bash
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
creds_file_path=$1
gke_name=$2
region=$3
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/.helmignore b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/.helmignore
index fbe01f8..e25078a 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/.helmignore
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/.helmignore
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/Chart.yaml b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/Chart.yaml
index 4b334aa..d133831 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/Chart.yaml
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/Chart.yaml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
apiVersion: v1
appVersion: 0.13.2
description: An online certificate authority and related tools for secure automated
@@ -6,7 +27,7 @@
home: https://smallstep.com
icon: https://raw.githubusercontent.com/smallstep/certificates/master/icon.png
keywords:
-- acme
+ - acme
- authority
- ca
- certificate
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/_helpers.tpl b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/_helpers.tpl
index e240bac..b65f748 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/_helpers.tpl
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/_helpers.tpl
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/bootstrap.yaml b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/bootstrap.yaml
index 4fa3240..3e67b22 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/bootstrap.yaml
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/bootstrap.yaml
@@ -1,11 +1,32 @@
-{{- if .Release.IsInstall -}}
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
+ {{- if .Release.IsInstall -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "step-certificates.fullname" . }}-config
namespace: {{.Release.Namespace}}
labels:
-{{ include "step-certificates.labels" . | indent 4 }}
+ {{ include "step-certificates.labels" . | indent 4 }}
---
apiVersion: batch/v1
kind: Job
@@ -24,16 +45,16 @@
serviceAccountName: {{ include "step-certificates.fullname" . }}-config
restartPolicy: Never
volumes:
- - name: bootstrap
- configMap:
- name: {{ include "step-certificates.fullname" . }}-bootstrap
+ - name: bootstrap
+ configMap:
+ name: {{ include "step-certificates.fullname" . }}-bootstrap
containers:
- - name: config
- image: "{{ .Values.bootstrapImage.repository }}:{{ .Values.bootstrapImage.tag }}"
- imagePullPolicy: {{ .Values.bootstrapImage.pullPolicy }}
- command: ["/bin/sh", "/home/step/bootstrap/bootstrap.sh"]
- volumeMounts:
- - name: bootstrap
- mountPath: /home/step/bootstrap
- readOnly: true
+ - name: config
+ image: "{{ .Values.bootstrapImage.repository }}:{{ .Values.bootstrapImage.tag }}"
+ imagePullPolicy: {{ .Values.bootstrapImage.pullPolicy }}
+ command: ["/bin/sh", "/home/step/bootstrap/bootstrap.sh"]
+ volumeMounts:
+ - name: bootstrap
+ mountPath: /home/step/bootstrap
+ readOnly: true
{{- end -}}
\ No newline at end of file
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/ca.yaml b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/ca.yaml
index 1113f2b..14e5f75 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/ca.yaml
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/ca.yaml
@@ -1,9 +1,30 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ include "step-certificates.fullname" . }}
labels:
-{{ include "step-certificates.labels" . | indent 4 }}
+ {{ include "step-certificates.labels" . | indent 4 }}
spec:
# Only one replica is supported at this moment
# Requested {{ .Values.replicaCount }}
@@ -21,99 +42,99 @@
app: {{ include "step-certificates.fullname" . }}
spec:
{{- if .Release.IsInstall }}
- initContainers:
- - name: {{ .Chart.Name }}-init
- image: busybox:latest
- imagePullPolicy: {{ .Values.image.pullPolicy }}
- command: ["sleep", "20"]
+initContainers:
+ - name: {{ .Chart.Name }}-init
+ image: busybox:latest
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ command: ["sleep", "20"]
{{- end }}
- securityContext:
- {{- if .Values.ca.runAsRoot }}
- runAsUser: 0
- {{- else }}
- runAsUser: 1000
- runAsNonRoot: true
- runAsGroup: 1000
- fsGroup: 1000
- allowPrivilegeEscalation: false
- {{- end }}
- containers:
- - name: {{ .Chart.Name }}
- image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
- imagePullPolicy: {{ .Values.image.pullPolicy }}
- command: ["/usr/local/bin/step-ca",
- "--password-file", "/home/step/secrets/passwords/password",
- "/home/step/config/ca.json"]
- env:
- - name: NAMESPACE
- value: "{{ .Release.Namespace }}"
- ports:
- - name: https
- containerPort: {{ .Values.service.targetPort }}
- protocol: TCP
- livenessProbe:
- initialDelaySeconds: 5
- httpGet:
- path: /health
- port: {{ .Values.service.targetPort }}
- scheme: HTTPS
- readinessProbe:
- initialDelaySeconds: 5
- httpGet:
- path: /health
- port: {{ .Values.service.targetPort }}
- scheme: HTTPS
- resources:
- {{- toYaml .Values.resources | nindent 12 }}
- volumeMounts:
- - name: certs
- mountPath: /home/step/certs
- readOnly: true
- - name: config
- mountPath: /home/step/config
- readOnly: true
- - name: secrets
- mountPath: /home/step/secrets
- readOnly: true
- - name: ca-password
- mountPath: /home/step/secrets/passwords
- readOnly: true
- {{- if .Values.ca.db.enabled }}
- - name: database
- mountPath: /home/step/db
- readOnly: false
- {{- end }}
- volumes:
+securityContext:
+ {{- if .Values.ca.runAsRoot }}
+ runAsUser: 0
+ {{- else }}
+ runAsUser: 1000
+ runAsNonRoot: true
+ runAsGroup: 1000
+ fsGroup: 1000
+ allowPrivilegeEscalation: false
+ {{- end }}
+containers:
+ - name: {{ .Chart.Name }}
+ image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
+ imagePullPolicy: {{ .Values.image.pullPolicy }}
+ command: ["/usr/local/bin/step-ca",
+ "--password-file", "/home/step/secrets/passwords/password",
+ "/home/step/config/ca.json"]
+ env:
+ - name: NAMESPACE
+ value: "{{ .Release.Namespace }}"
+ ports:
+ - name: https
+ containerPort: {{ .Values.service.targetPort }}
+ protocol: TCP
+ livenessProbe:
+ initialDelaySeconds: 5
+ httpGet:
+ path: /health
+ port: {{ .Values.service.targetPort }}
+ scheme: HTTPS
+ readinessProbe:
+ initialDelaySeconds: 5
+ httpGet:
+ path: /health
+ port: {{ .Values.service.targetPort }}
+ scheme: HTTPS
+ resources:
+ {{- toYaml .Values.resources | nindent 12 }}
+ volumeMounts:
- name: certs
- configMap:
- name: {{ include "step-certificates.fullname" . }}-certs
+ mountPath: /home/step/certs
+ readOnly: true
- name: config
- configMap:
- name: {{ include "step-certificates.fullname" . }}-config
+ mountPath: /home/step/config
+ readOnly: true
- name: secrets
- configMap:
- name: {{ include "step-certificates.fullname" . }}-secrets
+ mountPath: /home/step/secrets
+ readOnly: true
- name: ca-password
- secret:
- secretName: {{ include "step-certificates.fullname" . }}-ca-password
- {{- if and .Values.ca.db.enabled (not .Values.ca.db.persistent) }}
- - name: database
- emptyDir: {}
- {{- end }}
- {{- with .Values.nodeSelector }}
- nodeSelector:
- {{- toYaml . | nindent 8 }}
- {{- end }}
- {{- with .Values.affinity }}
- affinity:
- {{- toYaml . | nindent 8 }}
- {{- end }}
- {{- with .Values.tolerations }}
- tolerations:
- {{- toYaml . | nindent 8 }}
- {{- end }}
+ mountPath: /home/step/secrets/passwords
+ readOnly: true
+ {{- if .Values.ca.db.enabled }}
+ - name: database
+ mountPath: /home/step/db
+ readOnly: false
+ {{- end }}
+volumes:
+ - name: certs
+ configMap:
+ name: {{ include "step-certificates.fullname" . }}-certs
+ - name: config
+configMap:
+ name: {{ include "step-certificates.fullname" . }}-config
+ - name: secrets
+configMap:
+ name: {{ include "step-certificates.fullname" . }}-secrets
+ - name: ca-password
+secret:
+ secretName: {{ include "step-certificates.fullname" . }}-ca-password
+ {{- if and .Values.ca.db.enabled (not .Values.ca.db.persistent) }}
+ - name: database
+emptyDir: {}
+ {{- end }}
+ {{- with .Values.nodeSelector }}
+nodeSelector:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.affinity }}
+affinity:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
+ {{- with .Values.tolerations }}
+tolerations:
+ {{- toYaml . | nindent 8 }}
+ {{- end }}
{{- if and .Values.ca.db.enabled .Values.ca.db.persistent }}
- volumeClaimTemplates:
+volumeClaimTemplates:
- metadata:
name: database
labels:
@@ -123,16 +144,16 @@
spec:
accessModes:
{{- range .Values.ca.db.accessModes }}
- - {{ . | quote }}
+ - {{ . | quote }}
{{- end }}
resources:
requests:
storage: {{ .Values.ca.db.size | quote }}
{{- if .Values.ca.db.storageClass }}
{{- if (eq "-" .Values.ca.db.storageClass) }}
- storageClassName: ""
+ storageClassName: ""
{{- else }}
- storageClassName: {{ .Values.ca.db.storageClass | quote }}
+ storageClassName: {{ .Values.ca.db.storageClass | quote }}
{{- end }}
{{- end }}
{{- end }}
\ No newline at end of file
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/configmaps.yaml b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/configmaps.yaml
index 28ad488..dc15383 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/configmaps.yaml
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/configmaps.yaml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
# ConfigMaps that will be updated by the configuration job:
# 1. Step CA config directory.
# 2. Step CA certs direcotry.
@@ -71,76 +92,76 @@
permission_error "create secrets"
fi
{{ if .Values.autocert.enabled }}
- echo -n "Checking for permission to create mutatingwebhookconfiguration in {{.Release.Namespace}} namespace: "
+echo -n "Checking for permission to create mutatingwebhookconfiguration in {{.Release.Namespace}} namespace: "
kubectl auth can-i create mutatingwebhookconfiguration --namespace {{.Release.Namespace}}
if [ $? -ne 0 ]; then
permission_error "create mutatingwebhookconfiguration"
- fi
+ fi
{{- end }}
- # Setting this here on purpose, after the above section which explicitly checks
- # for and handles exit errors.
- set -e
+# Setting this here on purpose, after the above section which explicitly checks
+# for and handles exit errors.
+ set -e
- echo -e "\n\e[1mInitializating the CA...\e[0m"
+ echo -e "\n\e[1mInitializating the CA...\e[0m"
- # CA password
+# CA password
{{- if .Values.ca.password }}
- CA_PASSWORD={{ quote .Values.ca.password }}
+ CA_PASSWORD={{ quote .Values.ca.password }}
{{- else }}
- CA_PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo '')
+ CA_PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo '')
{{- end }}
- # Provisioner password
+# Provisioner password
{{- if .Values.ca.provisioner.password }}
- CA_PROVISIONER_PASSWORD={{ quote .Values.ca.provisioner.password }}
+ CA_PROVISIONER_PASSWORD={{ quote .Values.ca.provisioner.password }}
{{- else }}
- CA_PROVISIONER_PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo '')
+ CA_PROVISIONER_PASSWORD=$(head /dev/urandom | tr -dc A-Za-z0-9 | head -c 32 ; echo '')
{{- end }}
- TMP_CA_PASSWORD=$(mktemp /tmp/autocert.XXXXXX)
- TMP_CA_PROVISIONER_PASSWORD=$(mktemp /tmp/autocert.XXXXXX)
+ TMP_CA_PASSWORD=$(mktemp /tmp/autocert.XXXXXX)
+ TMP_CA_PROVISIONER_PASSWORD=$(mktemp /tmp/autocert.XXXXXX)
- echo $CA_PASSWORD > $TMP_CA_PASSWORD
- echo $CA_PROVISIONER_PASSWORD > $TMP_CA_PROVISIONER_PASSWORD
+ echo $CA_PASSWORD > $TMP_CA_PASSWORD
+ echo $CA_PROVISIONER_PASSWORD > $TMP_CA_PROVISIONER_PASSWORD
- step ca init \
- --name "{{.Values.ca.name}}" \
- --dns "{{include "step-certificates.dns" .}}" \
- --address "{{.Values.ca.address}}" \
- --provisioner "{{.Values.ca.provisioner.name}}" \
- --with-ca-url "{{include "step-certificates.url" .}}" \
- --password-file "$TMP_CA_PASSWORD" \
- --provisioner-password-file "$TMP_CA_PROVISIONER_PASSWORD" {{ if not .Values.ca.db.enabled }}--no-db{{ end }}
+ step ca init \
+ --name "{{.Values.ca.name}}" \
+ --dns "{{include "step-certificates.dns" .}}" \
+ --address "{{.Values.ca.address}}" \
+ --provisioner "{{.Values.ca.provisioner.name}}" \
+ --with-ca-url "{{include "step-certificates.url" .}}" \
+ --password-file "$TMP_CA_PASSWORD" \
+ --provisioner-password-file "$TMP_CA_PROVISIONER_PASSWORD" {{ if not .Values.ca.db.enabled }}--no-db{{ end }}
- rm -f $TMP_CA_PASSWORD $TMP_CA_PROVISIONER_PASSWORD
+ rm -f $TMP_CA_PASSWORD $TMP_CA_PROVISIONER_PASSWORD
- echo -e "\n\e[1mCreating configmaps and secrets in {{.Release.Namespace}} namespace ...\e[0m"
+ echo -e "\n\e[1mCreating configmaps and secrets in {{.Release.Namespace}} namespace ...\e[0m"
- # Replace secrets created on helm install
- # It allows to properly remove them on helm delete
- kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-config --from-file $(step path)/config
- kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-certs --from-file $(step path)/certs
- kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-secrets --from-file $(step path)/secrets
+ # Replace secrets created on helm install
+ # It allows to properly remove them on helm delete
+ kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-config --from-file $(step path)/config
+ kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-certs --from-file $(step path)/certs
+ kbreplace -n {{.Release.Namespace}} create configmap {{ include "step-certificates.fullname" . }}-secrets --from-file $(step path)/secrets
- kbreplace -n {{.Release.Namespace}} create secret generic {{ include "step-certificates.fullname" . }}-ca-password --from-literal "password=${CA_PASSWORD}"
- kbreplace -n {{.Release.Namespace}} create secret generic {{ include "step-certificates.fullname" . }}-provisioner-password --from-literal "password=${CA_PROVISIONER_PASSWORD}"
+ kbreplace -n {{.Release.Namespace}} create secret generic {{ include "step-certificates.fullname" . }}-ca-password --from-literal "password=${CA_PASSWORD}"
+ kbreplace -n {{.Release.Namespace}} create secret generic {{ include "step-certificates.fullname" . }}-provisioner-password --from-literal "password=${CA_PROVISIONER_PASSWORD}"
- # Label all configmaps and secrets
- kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-config {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
- kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-certs {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
- kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-secrets {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
- kubectl -n {{.Release.Namespace}} label secret {{ include "step-certificates.fullname" . }}-ca-password {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
- kubectl -n {{.Release.Namespace}} label secret {{ include "step-certificates.fullname" . }}-provisioner-password {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
+# Label all configmaps and secrets
+kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-config {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
+kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-certs {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
+kubectl -n {{.Release.Namespace}} label configmap {{ include "step-certificates.fullname" . }}-secrets {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
+kubectl -n {{.Release.Namespace}} label secret {{ include "step-certificates.fullname" . }}-ca-password {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
+kubectl -n {{.Release.Namespace}} label secret {{ include "step-certificates.fullname" . }}-provisioner-password {{ include "step-certificates.labels" . | replace ": " "=" | replace "\n" " " }}
- # Patch webhook if autocert is enabled
+# Patch webhook if autocert is enabled
{{ if .Values.autocert.enabled }}
- CA_BUNDLE=$(cat $(step path)/certs/root_ca.crt | base64 | tr -d '\n')
- kubectl patch mutatingwebhookconfigurations {{ .Release.Name }}-autocert-webhook-config \
- --type json -p="[{\"op\":\"replace\",\"path\":\"/webhooks/0/clientConfig/caBundle\",\"value\":\"$CA_BUNDLE\"}]"
+ CA_BUNDLE=$(cat $(step path)/certs/root_ca.crt | base64 | tr -d '\n')
+ kubectl patch mutatingwebhookconfigurations {{ .Release.Name }}-autocert-webhook-config \
+ --type json -p="[{\"op\":\"replace\",\"path\":\"/webhooks/0/clientConfig/caBundle\",\"value\":\"$CA_BUNDLE\"}]"
{{- end }}
- echo -e "\n\e[1mStep Certificates installed!\e[0m"
- echo
- echo "CA URL: {{include "step-certificates.url" .}}"
- echo "CA Fingerprint: $(step certificate fingerprint $(step path)/certs/root_ca.crt)"
- echo
\ No newline at end of file
+ echo -e "\n\e[1mStep Certificates installed!\e[0m"
+ echo
+echo "CA URL: {{include "step-certificates.url" .}}"
+echo "CA Fingerprint: $(step certificate fingerprint $(step path)/certs/root_ca.crt)"
+ echo
\ No newline at end of file
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/ingress.yaml b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/ingress.yaml
index 53264f1..7f5403a 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/ingress.yaml
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/ingress.yaml
@@ -1,36 +1,56 @@
-{{- if .Values.ingress.enabled -}}
-{{- $fullName := include "step-certificates.fullname" . -}}
+# *****************************************************************************
+#
+ # Licensed to the Apache Software Foundation (ASF) under one
+ # or more contributor license agreements. See the NOTICE file
+ # distributed with this work for additional information
+ # regarding copyright ownership. The ASF licenses this file
+ # to you under the Apache License, Version 2.0 (the
+ # "License"); you may not use this file except in compliance
+ # with the License. You may obtain a copy of the License at
+ #
+ # http://www.apache.org/licenses/LICENSE-2.0
+ #
+ # Unless required by applicable law or agreed to in writing,
+ # software distributed under the License is distributed on an
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ # KIND, either express or implied. See the License for the
+ # specific language governing permissions and limitations
+ # under the License.
+ #
+ # ******************************************************************************
+ {{- if .Values.ingress.enabled -}}
+ {{- $fullName := include "step-certificates.fullname" . -}}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
-{{ include "step-certificates.labels" . | indent 4 }}
+ {{ include "step-certificates.labels" . | indent 4 }}
{{- with .Values.ingress.annotations }}
- annotations:
- {{- toYaml . | nindent 4 }}
+annotations:
+ {{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.tls }}
- tls:
+tls:
{{- range .Values.ingress.tls }}
- - hosts:
- {{- range .hosts }}
- - {{ . | quote }}
- {{- end }}
- secretName: {{ .secretName }}
+- hosts:
+ {{- range .hosts }}
+ - {{ . | quote }}
+ {{- end }}
+ secretName: {{ .secretName }}
{{- end }}
{{- end }}
- rules:
+rules:
{{- range .Values.ingress.hosts }}
- - host: {{ .host | quote }}
- http:
- paths:
- {{- range .paths }}
- - path: {{ . }}
- backend:
- serviceName: {{ $fullName }}
- servicePort: http
- {{- end }}
+- host: {{ .host | quote }}
+ http:
+ paths:
+ {{- range .paths }}
+ - path: {{ . }}
+ backend:
+ serviceName: {{ $fullName }}
+ servicePort: http
+ {{- end }}
{{- end }}
{{- end }}
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/rbac.yaml b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/rbac.yaml
index 6f4e137..ebab8c4 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/rbac.yaml
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/rbac.yaml
@@ -1,4 +1,25 @@
-{{- if .Release.IsInstall -}}
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
+ {{- if .Release.IsInstall -}}
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/secrets.yaml b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/secrets.yaml
index 567a989..64f8b9b 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/secrets.yaml
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/secrets.yaml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
# Secrets that will be updated by the configuration job:
# 1. CA keys password.
# 2. Provisioner password.
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/service.yaml b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/service.yaml
index 4ec0783..fb17ab1 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/service.yaml
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/service.yaml
@@ -1,19 +1,40 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
apiVersion: v1
kind: Service
metadata:
name: {{ include "step-certificates.fullname" . }}
labels:
-{{ include "step-certificates.labels" . | indent 4 }}
+ {{ include "step-certificates.labels" . | indent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: {{ .Values.service.targetPort }}
{{- if .Values.service.nodePort }}
- nodePort: {{ .Values.service.nodePort }}
+nodePort: {{ .Values.service.nodePort }}
{{- end }}
- protocol: TCP
- name: https
- selector:
- app.kubernetes.io/name: {{ include "step-certificates.name" . }}
- app.kubernetes.io/instance: {{ .Release.Name }}
\ No newline at end of file
+protocol: TCP
+name: https
+selector:
+ app.kubernetes.io/name: {{ include "step-certificates.name" . }}
+ app.kubernetes.io/instance: {{ .Release.Name }}
\ No newline at end of file
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/tests/test-connection.yaml b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/tests/test-connection.yaml
index 5ae87c6..19375d9 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/tests/test-connection.yaml
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/templates/tests/test-connection.yaml
@@ -1,11 +1,32 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "step-certificates.fullname" . }}-test-connection"
labels:
-{{ include "step-certificates.labels" . | indent 4 }}
- annotations:
- "helm.sh/hook": test-success
+ {{ include "step-certificates.labels" . | indent 4 }}
+annotations:
+ "helm.sh/hook": test-success
spec:
containers:
- name: wget
diff --git a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/values.yaml b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/values.yaml
index 45350b6..fdc7b9a 100644
--- a/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/values.yaml
+++ b/infrastructure-provisioning/terraform/gcp/ssn-gke/main/modules/helm_charts/step-ca-chart/values.yaml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
# Default values for step-certificates.
# replicaCount is the number of replicas of step-certificates.
@@ -63,7 +84,7 @@
storageClass: standard
# accessModes defines the Persistent Volume Access Mode.
accessModes:
- - ReadWriteOnce
+ - ReadWriteOnce
# size is the Persistent Volume size.
size: 10Gi
# runAsRoot runs the ca as root instead of the step user. This is required in
@@ -92,7 +113,7 @@
# memory: 128Mi
# requests:
# cpu: 100m
- # memory: 128Mi
+# memory: 128Mi
# nodeSelector contains the node labels for pod assignment.
nodeSelector: {}
diff --git a/infrastructure-provisioning/terraform/keycloak-theme/dlab/login/resources/css/login.css b/infrastructure-provisioning/terraform/keycloak-theme/dlab/login/resources/css/login.css
index b31310a..1f5d717 100644
--- a/infrastructure-provisioning/terraform/keycloak-theme/dlab/login/resources/css/login.css
+++ b/infrastructure-provisioning/terraform/keycloak-theme/dlab/login/resources/css/login.css
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
.login-pf body {
background: url("../img/login-background.png") no-repeat center center fixed;
background-size: cover;
diff --git a/infrastructure-provisioning/terraform/keycloak-theme/dlab/login/theme.properties b/infrastructure-provisioning/terraform/keycloak-theme/dlab/login/theme.properties
index ed1c3c1..5ff84ad 100644
--- a/infrastructure-provisioning/terraform/keycloak-theme/dlab/login/theme.properties
+++ b/infrastructure-provisioning/terraform/keycloak-theme/dlab/login/theme.properties
@@ -1,25 +1,36 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
parent=base
import=common/keycloak
-
styles=node_modules/patternfly/dist/css/patternfly.css node_modules/patternfly/dist/css/patternfly-additions.css lib/zocial/zocial.css css/login.css
meta=viewport==width=device-width,initial-scale=1
-
kcHtmlClass=login-pf
kcLoginClass=login-pf-page
-
kcLogoLink=http://www.keycloak.org
-
kcLogoClass=login-pf-brand
-
kcContainerClass=container-fluid
kcContentClass=col-sm-8 col-sm-offset-2 col-md-6 col-md-offset-3 col-lg-6 col-lg-offset-3
kcContentWrapperClass=row
-
kcHeaderClass=login-pf-page-header
kcFeedbackAreaClass=col-md-12
kcLocaleClass=col-xs-12 col-sm-1
kcAlertIconClasserror=pficon pficon-error-circle-o
-
kcFormAreaClass=col-sm-10 col-sm-offset-1 col-md-8 col-md-offset-2 col-lg-8 col-lg-offset-2
kcFormCardClass=card-pf
kcFormCardAccountClass=login-pf-accounts
@@ -29,13 +40,10 @@
kcFormSocialAccountDoubleListClass=login-pf-social-double-col
kcFormSocialAccountListLinkClass=login-pf-social-link
kcFormHeaderClass=login-pf-header
-
kcFeedbackErrorIcon=pficon pficon-error-circle-o
kcFeedbackWarningIcon=pficon pficon-warning-triangle-o
kcFeedbackSuccessIcon=pficon pficon-ok
kcFeedbackInfoIcon=pficon pficon-info
-
-
kcFormClass=form-horizontal
kcFormGroupClass=form-group
kcFormGroupErrorClass=has-error
@@ -48,10 +56,7 @@
kcFormSettingClass=login-pf-settings
kcTextareaClass=form-control
kcSignUpClass=login-pf-signup
-
-
kcInfoAreaClass=col-xs-12 col-sm-4 col-md-4 col-lg-5 details
-
##### css classes for form buttons
# main class used for all buttons
kcButtonClass=btn
@@ -61,9 +66,7 @@
# classes defining size of the button
kcButtonLargeClass=btn-lg
kcButtonBlockClass=btn-block
-
##### css classes for input
kcInputLargeClass=input-lg
-
##### css classes for form accessability
kcSrOnlyClass=sr-only
diff --git a/integration-tests-cucumber/pom.xml b/integration-tests-cucumber/pom.xml
index d96a492..d862bcb 100644
--- a/integration-tests-cucumber/pom.xml
+++ b/integration-tests-cucumber/pom.xml
@@ -1,4 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
diff --git a/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/EndpointDTO.java b/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/EndpointDTO.java
index a06a4d7..7cfdad2 100644
--- a/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/EndpointDTO.java
+++ b/integration-tests-cucumber/src/main/java/org/apache/dlab/dto/EndpointDTO.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package org.apache.dlab.dto;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
diff --git a/integration-tests-cucumber/src/main/java/org/apache/dlab/mongo/MongoDBHelper.java b/integration-tests-cucumber/src/main/java/org/apache/dlab/mongo/MongoDBHelper.java
index 11e4dea..4903fd4 100644
--- a/integration-tests-cucumber/src/main/java/org/apache/dlab/mongo/MongoDBHelper.java
+++ b/integration-tests-cucumber/src/main/java/org/apache/dlab/mongo/MongoDBHelper.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package org.apache.dlab.mongo;
import com.mongodb.client.MongoClient;
diff --git a/integration-tests-cucumber/src/main/java/org/apache/dlab/util/JacksonMapper.java b/integration-tests-cucumber/src/main/java/org/apache/dlab/util/JacksonMapper.java
index a18d4d9..ae4d5ce 100644
--- a/integration-tests-cucumber/src/main/java/org/apache/dlab/util/JacksonMapper.java
+++ b/integration-tests-cucumber/src/main/java/org/apache/dlab/util/JacksonMapper.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package org.apache.dlab.util;
import com.fasterxml.jackson.core.JsonProcessingException;
diff --git a/integration-tests-cucumber/src/main/java/org/apache/dlab/util/PropertyHelper.java b/integration-tests-cucumber/src/main/java/org/apache/dlab/util/PropertyHelper.java
index 48d7cca..71688e2 100644
--- a/integration-tests-cucumber/src/main/java/org/apache/dlab/util/PropertyHelper.java
+++ b/integration-tests-cucumber/src/main/java/org/apache/dlab/util/PropertyHelper.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package org.apache.dlab.util;
import java.io.FileInputStream;
diff --git a/integration-tests-cucumber/src/test/java/dlab/Constants.java b/integration-tests-cucumber/src/test/java/dlab/Constants.java
index 4e30e99..8e1b6b9 100644
--- a/integration-tests-cucumber/src/test/java/dlab/Constants.java
+++ b/integration-tests-cucumber/src/test/java/dlab/Constants.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package dlab;
public interface Constants {
diff --git a/integration-tests-cucumber/src/test/java/dlab/RunCucumberTest.java b/integration-tests-cucumber/src/test/java/dlab/RunCucumberTest.java
index fdc8a4c..fb03b55 100644
--- a/integration-tests-cucumber/src/test/java/dlab/RunCucumberTest.java
+++ b/integration-tests-cucumber/src/test/java/dlab/RunCucumberTest.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package dlab;
import cucumber.api.CucumberOptions;
diff --git a/integration-tests-cucumber/src/test/java/dlab/endpoint/EndpointSteps.java b/integration-tests-cucumber/src/test/java/dlab/endpoint/EndpointSteps.java
index e66fc33..1c1d43a 100644
--- a/integration-tests-cucumber/src/test/java/dlab/endpoint/EndpointSteps.java
+++ b/integration-tests-cucumber/src/test/java/dlab/endpoint/EndpointSteps.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package dlab.endpoint;
import com.jayway.restassured.http.ContentType;
diff --git a/integration-tests-cucumber/src/test/java/dlab/login/LoginSteps.java b/integration-tests-cucumber/src/test/java/dlab/login/LoginSteps.java
index 32b29cb..fd533e0 100644
--- a/integration-tests-cucumber/src/test/java/dlab/login/LoginSteps.java
+++ b/integration-tests-cucumber/src/test/java/dlab/login/LoginSteps.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package dlab.login;
import com.jayway.restassured.http.ContentType;
diff --git a/integration-tests-cucumber/src/test/resources/config.properties b/integration-tests-cucumber/src/test/resources/config.properties
index 5cfad3c..d0cfc24 100644
--- a/integration-tests-cucumber/src/test/resources/config.properties
+++ b/integration-tests-cucumber/src/test/resources/config.properties
@@ -1,2 +1,20 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
mongo.connection.string=mongodb://localhost:27017/DLAB
mongo.db.name=DLAB
\ No newline at end of file
diff --git a/integration-tests-cucumber/src/test/resources/dlab/endpoint.feature b/integration-tests-cucumber/src/test/resources/dlab/endpoint.feature
index 7281a24..1f7fe14 100644
--- a/integration-tests-cucumber/src/test/resources/dlab/endpoint.feature
+++ b/integration-tests-cucumber/src/test/resources/dlab/endpoint.feature
@@ -1,3 +1,21 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
Feature: Endpoint management in DLab
Such feature allowed to manage endpoint inside DLab
diff --git a/integration-tests-cucumber/src/test/resources/dlab/login.feature b/integration-tests-cucumber/src/test/resources/dlab/login.feature
index 493a51e..1675aad 100644
--- a/integration-tests-cucumber/src/test/resources/dlab/login.feature
+++ b/integration-tests-cucumber/src/test/resources/dlab/login.feature
@@ -1,3 +1,21 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
Feature: DLab login API
Used to check DLab login flow
diff --git a/integration-tests/examples/scenario_deeplearning/deeplearning_tests.py b/integration-tests/examples/scenario_deeplearning/deeplearning_tests.py
index edc981e..92a9596 100644
--- a/integration-tests/examples/scenario_deeplearning/deeplearning_tests.py
+++ b/integration-tests/examples/scenario_deeplearning/deeplearning_tests.py
@@ -115,11 +115,11 @@
prepare_ipynb(i, '/home/{}/test_templates/template_theano.ipynb'.format(args.os_user), 'test_theano')
run_ipynb('test_theano')
-def run_torch():
- interpreters = ['itorch']
- for i in interpreters:
- prepare_ipynb(i, '/home/{}/test_templates/template_torch.ipynb'.format(args.os_user), 'test_torch')
- run_ipynb('test_torch')
+#def run_torch():
+# interpreters = ['itorch']
+# for i in interpreters:
+# prepare_ipynb(i, '/home/{}/test_templates/template_torch.ipynb'.format(args.os_user), 'test_torch')
+# run_ipynb('test_torch')
if __name__ == "__main__":
@@ -132,7 +132,7 @@
run_keras()
run_mxnet()
run_theano()
- run_torch()
+ #run_torch()
except Exception as err:
print('Error!', str(err))
sys.exit(1)
diff --git a/integration-tests/examples/test_templates/rstudio/template_preparation.r b/integration-tests/examples/test_templates/rstudio/template_preparation.r
index 773a049..0c4377e 100644
--- a/integration-tests/examples/test_templates/rstudio/template_preparation.r
+++ b/integration-tests/examples/test_templates/rstudio/template_preparation.r
@@ -1,3 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
sc <- sparkR.session(MASTER)
working_storage <- "WORKING_STORAGE"
diff --git a/integration-tests/examples/test_templates/rstudio/template_visualization.r b/integration-tests/examples/test_templates/rstudio/template_visualization.r
index 6b38ec8..e79f460 100644
--- a/integration-tests/examples/test_templates/rstudio/template_visualization.r
+++ b/integration-tests/examples/test_templates/rstudio/template_visualization.r
@@ -1,3 +1,20 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
sc <- sparkR.session(MASTER)
full_path <- function(file_path) {
diff --git a/pom.xml b/pom.xml
index e24bfd9..47645ff 100644
--- a/pom.xml
+++ b/pom.xml
@@ -52,6 +52,41 @@
<module>services/billing-gcp</module>
</modules>
</profile>
+ <profile>
+ <id>sonar</id>
+ <activation>
+ <activeByDefault>false</activeByDefault>
+ </activation>
+ <properties>
+ <sonar.host.url>
+ http://localhost:9000/sonar
+ </sonar.host.url>
+ <sonar.coverage.exclusions>
+ **/*Exception.java,
+ **/*DAO.java,
+ **/*DAOImpl.java,
+ **/*Configuration.java,
+ **/*ApplicationConfiguration.java,
+ src/main/java/com/epam/dlab/dto/**,
+ src/main/java/com/epam/dlab/backendapi/interceptor/**,
+ src/main/java/com/epam/dlab/backendapi/auth/**,
+ src/main/java/com/epam/dlab/backendapi/conf/**,
+ src/main/java/com/epam/dlab/backendapi/domain/**,
+ src/main/java/com/epam/dlab/backendapi/dropwizard/**,
+ src/main/java/com/epam/dlab/backendapi/healthcheck/**,
+ src/main/java/com/epam/dlab/backendapi/modules/**,
+ src/main/java/com/epam/dlab/backendapi/resources/dto/**,
+ src/main/java/com/epam/dlab/backendapi/roles/**,
+ src/main/java/com/epam/dlab/backendapi/servlet/guacamole/**,
+ src/main/java/com/epam/dlab/backendapi/util/**,
+ src/main/java/com/epam/dlab/backendapi/validation/**,
+ src/main/java/com/epam/dlab/process/**,
+ src/main/java/com/epam/dlab/backendapi/modules/**,
+ src/main/java/com/epam/dlab/backendapi/validation/**,
+ src/main/java/com/epam/dlab/backendapi/schedulers/**
+ </sonar.coverage.exclusions>
+ </properties>
+ </profile>
</profiles>
<modules>
@@ -88,6 +123,7 @@
<logback.version>1.2.3</logback.version>
<commons-fileupload.version>1.3.3</commons-fileupload.version>
</properties>
+
<dependencyManagement>
<dependencies>
<dependency>
@@ -130,8 +166,6 @@
<artifactId>dropwizard-util</artifactId>
<version>${io.dropwizard.version}</version>
</dependency>
-
-
</dependencies>
</dependencyManagement>
@@ -174,6 +208,11 @@
</execution>
</executions>
</plugin>
+ <plugin>
+ <groupId>org.sonarsource.scanner.maven</groupId>
+ <artifactId>sonar-maven-plugin</artifactId>
+ <version>3.7.0.1746</version>
+ </plugin>
</plugins>
</pluginManagement>
<plugins>
@@ -230,7 +269,7 @@
<plugin>
<groupId>org.apache.rat</groupId>
<artifactId>apache-rat-plugin</artifactId>
- <version>0.7</version>
+ <version>0.13</version>
<configuration>
<excludes>
<exclude>.git/**</exclude>
@@ -241,6 +280,7 @@
<exclude>**/*.ipynb</exclude>
<exclude>**/*.iml</exclude>
<exclude>**/*.json</exclude>
+ <exclude>**/*.json.tpl</exclude>
<exclude>**/*.r</exclude>
<exclude>**/__init__.py</exclude>
<exclude>**/*.conf</exclude>
diff --git a/services/billing-aws/src/main/java/com/epam/dlab/BillingService.java b/services/billing-aws/src/main/java/com/epam/dlab/BillingService.java
index 9b4d6db..15dcc32 100644
--- a/services/billing-aws/src/main/java/com/epam/dlab/BillingService.java
+++ b/services/billing-aws/src/main/java/com/epam/dlab/BillingService.java
@@ -23,6 +23,7 @@
import java.util.List;
+@FunctionalInterface
public interface BillingService {
List<BillingData> getBillingData();
}
diff --git a/services/billing-aws/src/main/resources/application.yml b/services/billing-aws/src/main/resources/application.yml
index ece61aa..8b1b641 100644
--- a/services/billing-aws/src/main/resources/application.yml
+++ b/services/billing-aws/src/main/resources/application.yml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
spring:
main:
allow-bean-definition-overriding: true
diff --git a/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/AzureInvoiceCalculationService.java b/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/AzureInvoiceCalculationService.java
index b3eec4f..441475e 100644
--- a/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/AzureInvoiceCalculationService.java
+++ b/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/AzureInvoiceCalculationService.java
@@ -22,7 +22,6 @@
import com.epam.dlab.billing.BillingCalculationUtils;
import com.epam.dlab.billing.azure.config.BillingConfigurationAzure;
import com.epam.dlab.billing.azure.model.AzureDailyResourceInvoice;
-import com.epam.dlab.billing.azure.model.AzureDlabBillableResource;
import com.epam.dlab.billing.azure.rate.AzureRateCardClient;
import com.epam.dlab.billing.azure.rate.Meter;
import com.epam.dlab.billing.azure.rate.RateCardResponse;
@@ -58,7 +57,6 @@
private static final long MAX_AUTH_TOKEN_TTL_MILLIS = 9L * 60L * 1000L;
private BillingConfigurationAzure billingConfigurationAzure;
- private Map<String, AzureDlabBillableResource> billableResources;
/**
* Constructs service class
diff --git a/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/CalculateBillingService.java b/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/CalculateBillingService.java
index d432337..2f265c0 100644
--- a/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/CalculateBillingService.java
+++ b/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/CalculateBillingService.java
@@ -23,6 +23,7 @@
import java.util.List;
+@FunctionalInterface
public interface CalculateBillingService {
List<BillingData> getBillingData();
}
diff --git a/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/config/SecurityConfig.java b/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/config/SecurityConfig.java
index 35e341c..9ee3d0a 100644
--- a/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/config/SecurityConfig.java
+++ b/services/billing-azure/src/main/java/com/epam/dlab/billing/azure/config/SecurityConfig.java
@@ -44,7 +44,7 @@
}
@Bean
- public KeycloakConfigResolver KeycloakConfigResolver() {
+ public KeycloakConfigResolver keycloakConfigResolver() {
return new KeycloakSpringBootConfigResolver();
}
diff --git a/services/billing-azure/src/main/resources/application.yml b/services/billing-azure/src/main/resources/application.yml
index eba7073..f029e30 100644
--- a/services/billing-azure/src/main/resources/application.yml
+++ b/services/billing-azure/src/main/resources/application.yml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
spring:
main:
allow-bean-definition-overriding: true
diff --git a/services/billing-gcp/billing.yml b/services/billing-gcp/billing.yml
index 87313c2..621c9b4 100644
--- a/services/billing-gcp/billing.yml
+++ b/services/billing-gcp/billing.yml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
spring:
main:
allow-bean-definition-overriding: true
diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/conf/SecurityConfig.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/conf/SecurityConfig.java
index ad960b0..5666283 100644
--- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/conf/SecurityConfig.java
+++ b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/conf/SecurityConfig.java
@@ -44,8 +44,8 @@
}
@Bean
- public KeycloakConfigResolver KeycloakConfigResolver() {
- return new KeycloakSpringBootConfigResolver();
+ public KeycloakConfigResolver keycloakConfigResolver() {
+ return new KeycloakSpringBootConfigResolver();
}
@Bean
diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/BillingDAO.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/BillingDAO.java
index 7c791df..31a636b 100644
--- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/BillingDAO.java
+++ b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/BillingDAO.java
@@ -23,6 +23,7 @@
import java.util.List;
+@FunctionalInterface
public interface BillingDAO {
- List<BillingData> getBillingData() throws InterruptedException;
+ List<BillingData> getBillingData() throws InterruptedException;
}
diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/impl/BigQueryBillingDAO.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/impl/BigQueryBillingDAO.java
index 061283d..3a93429 100644
--- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/impl/BigQueryBillingDAO.java
+++ b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/dao/impl/BigQueryBillingDAO.java
@@ -24,6 +24,7 @@
import com.epam.dlab.billing.gcp.model.BillingHistory;
import com.epam.dlab.billing.gcp.repository.BillingHistoryRepository;
import com.epam.dlab.dto.billing.BillingData;
+import com.epam.dlab.exceptions.DlabException;
import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.FieldValueList;
import com.google.cloud.bigquery.QueryJobConfiguration;
@@ -32,7 +33,6 @@
import com.google.cloud.bigquery.TableInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Component;
import java.time.Instant;
@@ -53,7 +53,6 @@
private static final String DATASET_PARAM = "dataset";
private final BillingHistoryRepository billingHistoryRepo;
- private final MongoTemplate mongoTemplate;
private final BigQuery service;
private final String dataset;
private final String sbn;
@@ -69,11 +68,10 @@
@Autowired
public BigQueryBillingDAO(DlabConfiguration conf, BillingHistoryRepository billingHistoryRepo,
- BigQuery service, MongoTemplate mongoTemplate) {
+ BigQuery service) {
dataset = conf.getBigQueryDataset();
this.service = service;
this.billingHistoryRepo = billingHistoryRepo;
- this.mongoTemplate = mongoTemplate;
sbn = conf.getSbn();
}
@@ -107,8 +105,9 @@
.map(this::toGcpBillingData);
billingHistoryRepo.save(new BillingHistory(tableName, table.getLastModifiedTime()));
return gcpBillingDataStream;
- } catch (InterruptedException e) {
- throw new IllegalStateException("Can not get billing info from BigQuery due to: " + e.getMessage(), e);
+ } catch (Exception e) {
+ log.error("Can not get billing info from BigQuery due to {}", e.getMessage(), e);
+ throw new DlabException("Can not get billing info from BigQuery due to: " + e.getMessage(), e);
}
}
diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/model/BillingHistory.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/model/BillingHistory.java
index 6abb2d9..8fb80f1 100644
--- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/model/BillingHistory.java
+++ b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/model/BillingHistory.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.billing.gcp.model;
import lombok.AllArgsConstructor;
diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/repository/BillingHistoryRepository.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/repository/BillingHistoryRepository.java
index c375904..957ced7 100644
--- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/repository/BillingHistoryRepository.java
+++ b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/repository/BillingHistoryRepository.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.billing.gcp.repository;
import com.epam.dlab.billing.gcp.model.BillingHistory;
diff --git a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/service/BillingService.java b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/service/BillingService.java
index 7bb3246..ca4277f 100644
--- a/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/service/BillingService.java
+++ b/services/billing-gcp/src/main/java/com/epam/dlab/billing/gcp/service/BillingService.java
@@ -23,6 +23,7 @@
import java.util.List;
+@FunctionalInterface
public interface BillingService {
- List<BillingData> getBillingData();
+ List<BillingData> getBillingData();
}
diff --git a/services/billing-gcp/src/main/resources/application.yml b/services/billing-gcp/src/main/resources/application.yml
index b2fda5d..9e29b04 100644
--- a/services/billing-gcp/src/main/resources/application.yml
+++ b/services/billing-gcp/src/main/resources/application.yml
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
spring:
main:
allow-bean-definition-overriding: true
diff --git a/services/common/src/main/java/com/epam/dlab/auth/conf/AzureLoginConfiguration.java b/services/common/src/main/java/com/epam/dlab/auth/conf/AzureLoginConfiguration.java
deleted file mode 100644
index cf6331c..0000000
--- a/services/common/src/main/java/com/epam/dlab/auth/conf/AzureLoginConfiguration.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package com.epam.dlab.auth.conf;
-
-import lombok.Getter;
-
-@Getter
-public class AzureLoginConfiguration {
- private boolean useLdap;
- private boolean silent;
- private String tenant;
- private String authority;
- private String clientId;
- private String redirectUrl;
- private String responseMode;
- private String prompt;
- private String loginPage;
- private boolean validatePermissionScope;
- private String permissionScope;
- private String managementApiAuthFile;
- private long maxSessionDurabilityMilliseconds = 8L * 60L * 60L * 1000L;// 8 hours
-}
diff --git a/services/common/src/main/java/com/epam/dlab/auth/conf/GcpLoginConfiguration.java b/services/common/src/main/java/com/epam/dlab/auth/conf/GcpLoginConfiguration.java
deleted file mode 100644
index 6dbaf02..0000000
--- a/services/common/src/main/java/com/epam/dlab/auth/conf/GcpLoginConfiguration.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package com.epam.dlab.auth.conf;
-
-import lombok.Data;
-
-@Data
-public class GcpLoginConfiguration {
- private final boolean oauth2authenticationEnabled;
- private final String redirectedUri;
- private final String clientId;
- private final String clientSecret;
- private final String applicationName;
- private final int userStateCacheSize;
- private final long userStateCacheExpirationTime;
-}
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/MongoKeyWords.java b/services/dlab-model/src/main/java/com/epam/dlab/MongoKeyWords.java
index 6553f2a..1ba4eed 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/MongoKeyWords.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/MongoKeyWords.java
@@ -20,14 +20,6 @@
package com.epam.dlab;
public abstract class MongoKeyWords {
- public static final String EDGE_COLLECTION = "userCloudCredentials";
- public static final String SETTINGS_COLLECTION = "settings";
- public static final String NOTEBOOK_COLLECTION = "userInstances";
- public static final String SERVICE_BASE_NAME_KEY = "conf_service_base_name";
- public static final String SSN_STORAGE_ACCOUNT_TAG_KEY = "ssn_storage_account_tag_name";
- public static final String SHARED_STORAGE_ACCOUNT_TAG_KEY = "shared_storage_account_tag_name";
- public static final String DATA_LAKE_TAG_NAME = "datalake_tag_name";
- public static final String BILLING_DETAILS = "billing";
public static final String AZURE_BILLING_SCHEDULER = "billingScheduler";
public static final String AZURE_BILLING_SCHEDULER_HISTORY = "billingSchedulerHistory";
@@ -35,30 +27,8 @@
* Mongo DB keywords related to billing functionality
*/
public static final String MONGO_ID = "_id";
- public static final String DLAB_ID = "dlabId";
- public static final String DLAB_USER = "user";
- public static final String EXPLORATORY_ID = "exploratoryId";
- public static final String EXPLORATORY_ID_OLD = "exploratory_id";
- public static final String RESOURCE_TYPE = "resourceType";
- public static final String RESOURCE_NAME = "resourceName";
- public static final String COMPUTATIONAL_ID = "computationalId";
- public static final String METER_CATEGORY = "meterCategory";
- public static final String COST = "cost";
- public static final String COST_STRING = "costString";
- public static final String USAGE_DAY = "day";
- public static final String USAGE_FROM = "from";
- public static final String USAGE_TO = "to";
- public static final String CURRENCY_CODE = "currencyCode";
private MongoKeyWords() {
}
-
- public static String prepend$(String value) {
- return "$" + value;
- }
-
- public static String prependId(String value) {
- return MongoKeyWords.MONGO_ID + "." + value;
- }
}
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/dto/base/project/ProjectResult.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/base/project/ProjectResult.java
index 11a6db6..9134f4a 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/dto/base/project/ProjectResult.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/base/project/ProjectResult.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.dto.base.project;
import com.epam.dlab.dto.StatusBaseDTO;
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/dto/computational/UserComputationalResource.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/computational/UserComputationalResource.java
index 5f131a1..aa25af4 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/dto/computational/UserComputationalResource.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/computational/UserComputationalResource.java
@@ -67,6 +67,10 @@
private int dataengineInstanceCount;
@JsonProperty("instance_id")
private String instanceId;
+ @JsonProperty("dataproc_version")
+ private String gcpClusterVersion;
+ @JsonProperty("emr_version")
+ private String awsClusterVersion;
private int totalInstanceCount;
protected List<ClusterConfig> config;
private Map<String, String> tags;
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryCreateDTO.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryCreateDTO.java
index cb32efb..557be36 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryCreateDTO.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryCreateDTO.java
@@ -79,6 +79,7 @@
return self;
}
+ @Override
public T withEndpoint(String endpoint) {
this.endpoint = endpoint;
return self;
@@ -102,10 +103,12 @@
return self;
}
+ @Override
public String getEndpoint() {
return endpoint;
}
+ @Override
public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryGitCreds.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryGitCreds.java
index e547bde..0211ac5 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryGitCreds.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryGitCreds.java
@@ -168,7 +168,9 @@
@Override
public boolean equals(Object obj) {
- if (this == obj) return true;
+ if (this == obj) {
+ return true;
+ }
return (obj instanceof ExploratoryGitCreds && (this.compareTo((ExploratoryGitCreds) obj) == 0));
}
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryImageDTO.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryImageDTO.java
index b41f432..f4cffa3 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryImageDTO.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/ExploratoryImageDTO.java
@@ -48,6 +48,7 @@
return this;
}
+ @Override
public ExploratoryImageDTO withEndpoint(String endpoint) {
this.endpoint = endpoint;
return this;
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/LibInstallDTO.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/LibInstallDTO.java
index 78f6e89..1d670a9 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/LibInstallDTO.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/LibInstallDTO.java
@@ -77,4 +77,9 @@
setErrorMessage(errorMessage);
return this;
}
+
+ public LibInstallDTO withAddedPackages(List<String> addedPackages) {
+ setAddedPackages(addedPackages);
+ return this;
+ }
}
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/LibStatus.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/LibStatus.java
index c5d0016..7804b83 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/LibStatus.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/exploratory/LibStatus.java
@@ -26,7 +26,8 @@
public enum LibStatus {
INSTALLING,
INSTALLED,
- FAILED;
+ INVALID_VERSION,
+ INSTALLATION_ERROR;
@JsonCreator
public static LibStatus of(String status) {
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/dto/project/ProjectActionDTO.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/project/ProjectActionDTO.java
index 23039be..b8e4718 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/dto/project/ProjectActionDTO.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/project/ProjectActionDTO.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.dto.project;
import com.epam.dlab.dto.ResourceBaseDTO;
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/dto/project/ProjectCreateDTO.java b/services/dlab-model/src/main/java/com/epam/dlab/dto/project/ProjectCreateDTO.java
index c64c505..bae34a8 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/dto/project/ProjectCreateDTO.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/dto/project/ProjectCreateDTO.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.dto.project;
import com.epam.dlab.dto.ResourceBaseDTO;
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/model/StringList.java b/services/dlab-model/src/main/java/com/epam/dlab/model/StringList.java
index d02ad3c..be4ea8e 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/model/StringList.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/model/StringList.java
@@ -19,26 +19,29 @@
package com.epam.dlab.model;
+import lombok.extern.slf4j.Slf4j;
+
import javax.ws.rs.WebApplicationException;
import java.util.ArrayList;
+@Slf4j
public class StringList extends ArrayList<String> {
- public StringList(String s) {
- super();
+ public StringList(String s) {
+ super();
- for (String v : s.split(",")) {
- try {
- add(v.trim());
- } catch (Exception ex) {
- ex.printStackTrace();
- throw new WebApplicationException(400);
- }
- }
- if (isEmpty())
- throw new WebApplicationException(400);
- }
+ for (String v : s.split(",")) {
+ try {
+ add(v.trim());
+ } catch (Exception e) {
+ log.error("Something went wrong. Reason {}", e.getMessage(), e);
+ throw new WebApplicationException(400);
+ }
+ }
+ if (isEmpty())
+ throw new WebApplicationException(400);
+ }
- public static String valueOf(String s) {
- return s;
- }
+ public static String valueOf(String s) {
+ return s;
+ }
}
\ No newline at end of file
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/model/aws/ReportLine.java b/services/dlab-model/src/main/java/com/epam/dlab/model/aws/ReportLine.java
index 46c82f0..ede4e23 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/model/aws/ReportLine.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/model/aws/ReportLine.java
@@ -28,12 +28,18 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-/** The line of billing report.
+/**
+ * The line of billing report.
*/
public class ReportLine {
+ /** Patterns to calculate the type of resource in report line. */
+ private static final Pattern pInstancceId = Pattern.compile("^i-[a-z0-9]{17}$");
+ private static final Pattern pVolumeId = Pattern.compile("^vol-[a-z0-9]{17}$");
+ private static final Pattern pIpAddress = Pattern.compile("^[1-9][0-9]{0,2}\\.[1-9][0-9]{0,2}\\.[1-9][0-9]{0,2}\\.[1-9][0-9]{0,2}$");
+ private static final Pattern pClusterId = Pattern.compile("j-[A-Z0-9]{12,13}$");
+
public static final String FIELD_DLAB_ID = "dlab_id";
public static final String FIELD_USER_ID = "user";
- public static final String FIELD_PROJECT = "project";
public static final String FIELD_USAGE_DATE = "usage_date";
public static final String FIELD_PRODUCT = "product";
public static final String FIELD_USAGE_TYPE = "usage_type";
@@ -160,13 +166,6 @@
public void setTags(LinkedHashMap<String, String> tags) {
this.tags = tags;
}
-
-
- /** Patterns to calculate the type of resource in report line. */
- private static final Pattern pInstancceId = Pattern.compile("^i-[a-z0-9]{17}$");
- private static final Pattern pVolumeId = Pattern.compile("^vol-[a-z0-9]{17}$");
- private static final Pattern pIpAddress = Pattern.compile("^[1-9][0-9]{0,2}\\.[1-9][0-9]{0,2}\\.[1-9][0-9]{0,2}\\.[1-9][0-9]{0,2}$");
- private static final Pattern pClusterId = Pattern.compile("j-[A-Z0-9]{12,13}$");
/** Calculate and set the type of resource and resource id.
* @throws ParseException */
diff --git a/services/dlab-model/src/main/java/com/epam/dlab/model/library/Library.java b/services/dlab-model/src/main/java/com/epam/dlab/model/library/Library.java
index 0ca4562..f40521c 100644
--- a/services/dlab-model/src/main/java/com/epam/dlab/model/library/Library.java
+++ b/services/dlab-model/src/main/java/com/epam/dlab/model/library/Library.java
@@ -25,6 +25,8 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
+import java.util.List;
+
@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class Library {
@@ -34,6 +36,10 @@
private final LibStatus status;
@JsonProperty("error_message")
private final String errorMessage;
+ @JsonProperty("available_versions")
+ private List<String> availableVersions;
+ @JsonProperty("add_pkgs")
+ private List<String> addedPackages;
private String resourceName;
private ResourceType type;
diff --git a/services/dlab-utils/src/main/java/com/epam/dlab/util/FileUtils.java b/services/dlab-utils/src/main/java/com/epam/dlab/util/FileUtils.java
index f48a5af..251902c 100644
--- a/services/dlab-utils/src/main/java/com/epam/dlab/util/FileUtils.java
+++ b/services/dlab-utils/src/main/java/com/epam/dlab/util/FileUtils.java
@@ -55,7 +55,7 @@
try {
Files.deleteIfExists(Paths.get(absolutePath));
} catch (IOException e) {
- log.error("Problems occured with deleting file {} due to: {}", absolutePath, e.getLocalizedMessage());
+ log.error("Problems occured with deleting file {} due to: {}", absolutePath, e.getLocalizedMessage(), e);
}
}
}
diff --git a/services/dlab-utils/src/main/java/com/epam/dlab/util/ServiceUtils.java b/services/dlab-utils/src/main/java/com/epam/dlab/util/ServiceUtils.java
index 5a2beeb..d3a44b2 100644
--- a/services/dlab-utils/src/main/java/com/epam/dlab/util/ServiceUtils.java
+++ b/services/dlab-utils/src/main/java/com/epam/dlab/util/ServiceUtils.java
@@ -20,6 +20,7 @@
package com.epam.dlab.util;
import com.epam.dlab.exceptions.DlabException;
+import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.net.JarURLConnection;
@@ -30,31 +31,32 @@
import java.util.jar.JarFile;
import java.util.jar.Manifest;
+@Slf4j
public class ServiceUtils {
private static String includePath = null;
-
+
static {
- includePath = System.getenv("DLAB_CONF_DIR");
- if ( includePath == null || includePath.isEmpty() ) {
- includePath = getUserDir();
- }
+ includePath = System.getenv("DLAB_CONF_DIR");
+ if ( includePath == null || includePath.isEmpty() ) {
+ includePath = getUserDir();
+ }
}
-
+
/* Return working directory.
*/
public static String getUserDir() {
return System.getProperty("user.dir");
}
-
+
/** Return path to DLab configuration directory.
* @return
*/
public static String getConfPath() {
- return includePath;
+ return includePath;
}
-
-
+
+
/** Return manifest for given class or empty manifest if {@link JarFile#MANIFEST_NAME} not found.
* @param clazz class.
* @throws IOException
@@ -73,7 +75,7 @@
JarURLConnection jarConnection = (JarURLConnection) url.openConnection();
return jarConnection.getManifest();
}
-
+
/** Return manifest map for given class or empty map if manifest not found or cannot be read.
* @param clazz class.
*/
@@ -89,13 +91,13 @@
map.put(key.toString(), (String) attributes.get(key));
}
} catch (IOException e) {
- System.err.println("Cannot found or open manifest for class " + className);
+ log.error("Cannot found or open manifest for class {}", className, e);
throw new DlabException("Cannot read manifest file", e);
}
-
+
return map;
}
-
+
/** Print to standard output the manifest info about application. If parameter <b>args</b> is not
* <b>null</b> and one or more arguments have value -v or --version then print version and return <b>true<b/>
* otherwise <b>false</b>.
@@ -108,32 +110,32 @@
boolean result = false;
if (args != null) {
for (String arg : args) {
- if (arg.equals("-v") ||
- arg.equals("--version")) {
- result = true;
- }
- }
+ if ("-v".equals(arg) ||
+ "--version".equals(arg)) {
+ result = true;
+ }
+ }
if (!result) {
return result;
}
}
-
+
Map<String, String> manifest = getManifest(mainClass);
if (manifest.isEmpty()) {
return result;
}
-
- System.out.println("Title " + manifest.get("Implementation-Title"));
- System.out.println("Version " + manifest.get("Implementation-Version"));
- System.out.println("Created By " + manifest.get("Created-By"));
- System.out.println("Vendor " + manifest.get("Implementation-Vendor"));
- System.out.println("GIT-Branch " + manifest.get("GIT-Branch"));
- System.out.println("GIT-Commit " + manifest.get("GIT-Commit"));
- System.out.println("Build JDK " + manifest.get("Build-Jdk"));
- System.out.println("Build OS " + manifest.get("Build-OS"));
- System.out.println("Built Time " + manifest.get("Build-Time"));
- System.out.println("Built By " + manifest.get("Built-By"));
-
+
+ log.info("Title {}", manifest.get("Implementation-Title"));
+ log.info("Version {}", manifest.get("Implementation-Version"));
+ log.info("Created By {}", manifest.get("Created-By"));
+ log.info("Vendor {}", manifest.get("Implementation-Vendor"));
+ log.info("GIT-Branch {}", manifest.get("GIT-Branch"));
+ log.info("GIT-Commit {}", manifest.get("GIT-Commit"));
+ log.info("Build JDK {}", manifest.get("Build-Jdk"));
+ log.info("Build OS {}", manifest.get("Build-OS"));
+ log.info("Built Time {}", manifest.get("Build-Time"));
+ log.info("Built By {}", manifest.get("Built-By"));
+
return result;
}
}
diff --git a/services/dlab-utils/src/main/java/com/epam/dlab/util/UsernameUtils.java b/services/dlab-utils/src/main/java/com/epam/dlab/util/UsernameUtils.java
index 9622661..4d1092c 100644
--- a/services/dlab-utils/src/main/java/com/epam/dlab/util/UsernameUtils.java
+++ b/services/dlab-utils/src/main/java/com/epam/dlab/util/UsernameUtils.java
@@ -23,6 +23,9 @@
private static final String UNDERLINE = "_";
+ private UsernameUtils() {
+ }
+
public static String removeDomain(String username) {
return username != null ? username.replaceAll("@.*", "") : null;
}
@@ -30,7 +33,4 @@
public static String replaceWhitespaces(String username) {
return username.replaceAll("\\s", UNDERLINE);
}
-
- private UsernameUtils() {
- }
}
diff --git a/services/dlab-webapp-common/src/main/java/com/epam/dlab/ModuleBase.java b/services/dlab-webapp-common/src/main/java/com/epam/dlab/ModuleBase.java
index 8aa9eb2..ba2adca 100644
--- a/services/dlab-webapp-common/src/main/java/com/epam/dlab/ModuleBase.java
+++ b/services/dlab-webapp-common/src/main/java/com/epam/dlab/ModuleBase.java
@@ -20,22 +20,22 @@
package com.epam.dlab;
import com.google.inject.AbstractModule;
-
import io.dropwizard.setup.Environment;
-/** The base class for an application configuration of service.
+/**
+ * The base class for an application configuration of service.
*/
-abstract public class ModuleBase<T extends ServiceConfiguration> extends AbstractModule {
+public abstract class ModuleBase<T extends ServiceConfiguration> extends AbstractModule {
/** Application configuration of service. */
- protected T configuration;
- /** Environment of service. */
- protected Environment environment;
+ protected T configuration;
+ /** Environment of service. */
+ protected Environment environment;
- /** Instantiates an application configuration of service.
- * @param configuration application configuration of service.
- * @param environment environment of service.
- */
- public ModuleBase(T configuration, Environment environment) {
+ /** Instantiates an application configuration of service.
+ * @param configuration application configuration of service.
+ * @param environment environment of service.
+ */
+ public ModuleBase(T configuration, Environment environment) {
this.configuration = configuration;
this.environment = environment;
}
diff --git a/services/dlab-webapp-common/src/main/java/com/epam/dlab/auth/UserInfo.java b/services/dlab-webapp-common/src/main/java/com/epam/dlab/auth/UserInfo.java
index 5c6a74f..c4b0f53 100644
--- a/services/dlab-webapp-common/src/main/java/com/epam/dlab/auth/UserInfo.java
+++ b/services/dlab-webapp-common/src/main/java/com/epam/dlab/auth/UserInfo.java
@@ -25,7 +25,13 @@
import com.fasterxml.jackson.annotation.JsonSetter;
import java.security.Principal;
-import java.util.*;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
@JsonIgnoreProperties(ignoreUnknown = true)
public class UserInfo implements Principal {
@@ -154,21 +160,36 @@
@Override
public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
- UserInfo userInfo = (UserInfo) o;
+ UserInfo userInfo = (UserInfo) o;
- if (awsUser != userInfo.awsUser) return false;
- if (username != null ? !username.equals(userInfo.username) : userInfo.username != null) return false;
- if (accessToken != null ? !accessToken.equals(userInfo.accessToken) : userInfo.accessToken != null)
- return false;
- if (!roles.equals(userInfo.roles)) return false;
- if (!keys.equals(userInfo.keys)) return false;
- if (firstName != null ? !firstName.equals(userInfo.firstName) : userInfo.firstName != null) return false;
- if (lastName != null ? !lastName.equals(userInfo.lastName) : userInfo.lastName != null) return false;
- return remoteIp != null ? remoteIp.equals(userInfo.remoteIp) : userInfo.remoteIp == null;
-
+ if (awsUser != userInfo.awsUser) {
+ return false;
+ }
+ if (username != null ? !username.equals(userInfo.username) : userInfo.username != null) {
+ return false;
+ }
+ if (accessToken != null ? !accessToken.equals(userInfo.accessToken) : userInfo.accessToken != null)
+ return false;
+ if (!roles.equals(userInfo.roles)) {
+ return false;
+ }
+ if (!keys.equals(userInfo.keys)) {
+ return false;
+ }
+ if (firstName != null ? !firstName.equals(userInfo.firstName) : userInfo.firstName != null) {
+ return false;
+ }
+ if (lastName != null ? !lastName.equals(userInfo.lastName) : userInfo.lastName != null) {
+ return false;
+ }
+ return remoteIp != null ? remoteIp.equals(userInfo.remoteIp) : userInfo.remoteIp == null;
}
diff --git a/services/dlab-webapp-common/src/main/java/com/epam/dlab/rest/contracts/EdgeAPI.java b/services/dlab-webapp-common/src/main/java/com/epam/dlab/rest/contracts/EdgeAPI.java
deleted file mode 100644
index 2fce5cc..0000000
--- a/services/dlab-webapp-common/src/main/java/com/epam/dlab/rest/contracts/EdgeAPI.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package com.epam.dlab.rest.contracts;
-
-public interface EdgeAPI {
- String EDGE = "infrastructure/edge";
- String EDGE_CREATE = EDGE + "/create";
- String EDGE_START = EDGE + "/start";
- String EDGE_STOP = EDGE + "/stop";
- String EDGE_TERMINATE = EDGE + "/terminate";
-}
diff --git a/services/provisioning-service/pom.xml b/services/provisioning-service/pom.xml
index 1db7308..0b62c36 100644
--- a/services/provisioning-service/pom.xml
+++ b/services/provisioning-service/pom.xml
@@ -180,6 +180,20 @@
</execution>
</executions>
</plugin>
+ <plugin>
+ <groupId>org.jacoco</groupId>
+ <artifactId>jacoco-maven-plugin</artifactId>
+ <configuration>
+ <excludes>
+ <exclude>**/*Configuration.*</exclude>
+ <exclude>**/*Module.*</exclude>
+ <exclude>**/*Form.*</exclude>
+ <exclude>com/epam/dlab/process/**/*</exclude>
+ <exclude>com/epam/dlab/backendapi/modules/**/*</exclude>
+ <exclude>com/epam/dlab/backendapi/validation/**/*</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
</plugins>
</build>
</project>
\ No newline at end of file
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/DropwizardBearerTokenFilterImpl.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/DropwizardBearerTokenFilterImpl.java
index 9be4251..fc2659c 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/DropwizardBearerTokenFilterImpl.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/DropwizardBearerTokenFilterImpl.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi;
import org.keycloak.adapters.AdapterDeploymentContext;
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/ProvisioningServiceApplicationConfiguration.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/ProvisioningServiceApplicationConfiguration.java
index 1025ad6..4edc8af 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/ProvisioningServiceApplicationConfiguration.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/ProvisioningServiceApplicationConfiguration.java
@@ -20,6 +20,7 @@
package com.epam.dlab.backendapi;
import com.epam.dlab.ServiceConfiguration;
+import com.epam.dlab.backendapi.conf.CloudConfiguration;
import com.epam.dlab.backendapi.core.Directories;
import com.epam.dlab.backendapi.validation.ProvisioningServiceCloudConfigurationSequenceProvider;
import com.epam.dlab.validation.AwsValidation;
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/CloudConfiguration.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/conf/CloudConfiguration.java
similarity index 98%
rename from services/provisioning-service/src/main/java/com/epam/dlab/backendapi/CloudConfiguration.java
rename to services/provisioning-service/src/main/java/com/epam/dlab/backendapi/conf/CloudConfiguration.java
index 9d61210..c25624c 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/CloudConfiguration.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/conf/CloudConfiguration.java
@@ -17,7 +17,7 @@
* under the License.
*/
-package com.epam.dlab.backendapi;
+package com.epam.dlab.backendapi.conf;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/MetadataHolder.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/MetadataHolder.java
index 7ad52d7..defbeaf 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/MetadataHolder.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/MetadataHolder.java
@@ -25,6 +25,7 @@
import java.util.Set;
+@FunctionalInterface
public interface MetadataHolder {
Set<ImageMetadataDTO> getMetadata(ImageType metadataType);
}
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CmdCommand.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CmdCommand.java
index d8fb126..0adfaa9 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CmdCommand.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CmdCommand.java
@@ -19,6 +19,7 @@
package com.epam.dlab.backendapi.core.commands;
+@FunctionalInterface
public interface CmdCommand {
String toCMD();
}
\ No newline at end of file
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CommandBuilder.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CommandBuilder.java
index a212d0a..f99eca4 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CommandBuilder.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CommandBuilder.java
@@ -19,8 +19,8 @@
package com.epam.dlab.backendapi.core.commands;
-import com.epam.dlab.backendapi.CloudConfiguration;
import com.epam.dlab.backendapi.ProvisioningServiceApplicationConfiguration;
+import com.epam.dlab.backendapi.conf.CloudConfiguration;
import com.epam.dlab.cloud.CloudProvider;
import com.epam.dlab.dto.ResourceBaseDTO;
import com.epam.dlab.dto.aws.AwsCloudSettings;
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CommandExecutorMockAsync.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CommandExecutorMockAsync.java
index 7277961..7ad66f8 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CommandExecutorMockAsync.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/commands/CommandExecutorMockAsync.java
@@ -42,7 +42,14 @@
import org.apache.commons.codec.Charsets;
import org.apache.commons.lang3.StringUtils;
-import java.io.*;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.net.URL;
import java.nio.file.Paths;
import java.util.List;
@@ -355,7 +362,7 @@
if (isSuccess) {
lib.setStatus(LibStatus.INSTALLED.toString());
} else {
- lib.setStatus(LibStatus.FAILED.toString());
+ lib.setStatus(LibStatus.INSTALLATION_ERROR.toString());
lib.setErrorMessage("Mock error message");
}
}
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/folderlistener/WatchItem.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/folderlistener/WatchItem.java
index ba72555..bb8fc03 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/folderlistener/WatchItem.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/folderlistener/WatchItem.java
@@ -20,18 +20,19 @@
package com.epam.dlab.backendapi.core.response.folderlistener;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ExecutionException;
-
import com.epam.dlab.backendapi.core.FileHandlerCallback;
import com.google.common.base.MoreObjects;
import lombok.extern.slf4j.Slf4j;
-/** Class to store the file handler for processing.
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+
+/**
+ * Class to store the file handler for processing.
*/
@Slf4j
public class WatchItem implements Comparable<WatchItem> {
-
+
/** Status of file processing.
* <pre>
* WAIT_FOR_FILE waiting for the file creation.
@@ -149,9 +150,10 @@
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return ItemStatus.IS_INTERRUPTED;
- } catch (ExecutionException e) {
- return ItemStatus.IS_FAILED;
- }
+ } catch (ExecutionException e) {
+ log.error("Execution exception occurred", e);
+ return ItemStatus.IS_FAILED;
+ }
}
return ItemStatus.INPROGRESS;
@@ -182,7 +184,7 @@
try {
futureResult = future.get();
} catch (Exception e) {
- log.error("Exception occurred during getting result: {}", e.getMessage());
+ log.error("Exception occurred during getting result: {}", e.getMessage(), e);
}
}
return futureResult;
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/handlers/ProjectCallbackHandler.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/handlers/ProjectCallbackHandler.java
index 688edb8..fa41998 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/handlers/ProjectCallbackHandler.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/handlers/ProjectCallbackHandler.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.core.response.handlers;
import com.epam.dlab.backendapi.core.commands.DockerAction;
@@ -19,8 +38,8 @@
private final String endpointName;
public ProjectCallbackHandler(RESTService selfService, String user,
- String uuid, DockerAction action, String callbackUri, String projectName,
- Class<? extends EdgeInfo> clazz, String endpointName) {
+ String uuid, DockerAction action, String callbackUri, String projectName,
+ Class<? extends EdgeInfo> clazz, String endpointName) {
super(selfService, user, uuid, action);
this.callbackUri = callbackUri;
this.projectName = projectName;
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/handlers/dao/FileSystemCallbackHandlerDao.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/handlers/dao/FileSystemCallbackHandlerDao.java
index 846e0d7..268950a 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/handlers/dao/FileSystemCallbackHandlerDao.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/core/response/handlers/dao/FileSystemCallbackHandlerDao.java
@@ -89,7 +89,7 @@
.ifPresent(FileUtils::deleteFile);
} catch (IOException e) {
log.error("Problem occurred with accessing directory {} due to: {}", configuration.getHandlerDirectory(),
- e.getLocalizedMessage());
+ e.getLocalizedMessage(), e);
}
}
@@ -102,7 +102,7 @@
log.trace("Persisting callback handler to file {}", absolutePath);
Files.write(Paths.get(absolutePath), mapper.writeValueAsBytes(handlerCallback), StandardOpenOption.CREATE);
} catch (Exception e) {
- log.warn("Can not persist file handler {} due to {}", fileName, e.getMessage());
+ log.warn("Can not persist file handler {} due to {}", fileName, e.getMessage(), e);
}
}
@@ -114,7 +114,7 @@
try {
return Optional.of(mapper.readValue(path.toFile(), PersistentFileHandler.class));
} catch (Exception e) {
- log.warn("Can not deserialize file handler from file: {}", path.toString());
+ log.warn("Can not deserialize file handler from file: {}", path.toString(), e);
}
return Optional.empty();
}
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java
index 005ad9f..2113e8c 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.resources;
import com.epam.dlab.auth.UserInfo;
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/ProvisioningHealthCheckResource.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/ProvisioningHealthCheckResource.java
index e50d7ae..a46171b 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/ProvisioningHealthCheckResource.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/ProvisioningHealthCheckResource.java
@@ -34,8 +34,6 @@
@Path("/healthcheck")
@Produces(MediaType.APPLICATION_JSON)
public class ProvisioningHealthCheckResource {
- private static final String HEALTH_CHECK = "ProvisioningHealthCheck";
-
@Inject
private ProvisioningServiceApplicationConfiguration configuration;
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/aws/EdgeResourceAws.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/aws/EdgeResourceAws.java
index 22c26e9..57956f3 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/aws/EdgeResourceAws.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/aws/EdgeResourceAws.java
@@ -28,7 +28,6 @@
import com.epam.dlab.dto.aws.edge.EdgeInfoAws;
import com.epam.dlab.dto.aws.keyload.UploadFileAws;
import com.epam.dlab.dto.base.keyload.UploadFileResult;
-import com.epam.dlab.rest.contracts.EdgeAPI;
import com.epam.dlab.util.FileUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import io.dropwizard.auth.Auth;
@@ -41,12 +40,14 @@
import javax.ws.rs.core.MediaType;
import java.io.IOException;
-import static com.epam.dlab.rest.contracts.ApiCallbacks.*;
+import static com.epam.dlab.rest.contracts.ApiCallbacks.EDGE;
+import static com.epam.dlab.rest.contracts.ApiCallbacks.KEY_LOADER;
+import static com.epam.dlab.rest.contracts.ApiCallbacks.STATUS_URI;
/**
* Provides API to manage Edge node on AWS
*/
-@Path(EdgeAPI.EDGE)
+@Path("infrastructure/edge")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Slf4j
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/azure/EdgeResourceAzure.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/azure/EdgeResourceAzure.java
index 4ebad5c..7781227 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/azure/EdgeResourceAzure.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/azure/EdgeResourceAzure.java
@@ -28,7 +28,6 @@
import com.epam.dlab.dto.azure.edge.EdgeInfoAzure;
import com.epam.dlab.dto.azure.keyload.UploadFileAzure;
import com.epam.dlab.dto.base.keyload.UploadFileResult;
-import com.epam.dlab.rest.contracts.EdgeAPI;
import com.epam.dlab.util.FileUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import io.dropwizard.auth.Auth;
@@ -41,12 +40,14 @@
import javax.ws.rs.core.MediaType;
import java.io.IOException;
-import static com.epam.dlab.rest.contracts.ApiCallbacks.*;
+import static com.epam.dlab.rest.contracts.ApiCallbacks.EDGE;
+import static com.epam.dlab.rest.contracts.ApiCallbacks.KEY_LOADER;
+import static com.epam.dlab.rest.contracts.ApiCallbacks.STATUS_URI;
/**
* Provides API to manage Edge node on Azure
*/
-@Path(EdgeAPI.EDGE)
+@Path("infrastructure/edge")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Slf4j
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/gcp/EdgeResourceGcp.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/gcp/EdgeResourceGcp.java
index 525e3e7..4509bff 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/gcp/EdgeResourceGcp.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/resources/gcp/EdgeResourceGcp.java
@@ -28,7 +28,6 @@
import com.epam.dlab.dto.base.keyload.UploadFileResult;
import com.epam.dlab.dto.gcp.edge.EdgeInfoGcp;
import com.epam.dlab.dto.gcp.keyload.UploadFileGcp;
-import com.epam.dlab.rest.contracts.EdgeAPI;
import com.epam.dlab.util.FileUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import io.dropwizard.auth.Auth;
@@ -41,12 +40,14 @@
import javax.ws.rs.core.MediaType;
import java.io.IOException;
-import static com.epam.dlab.rest.contracts.ApiCallbacks.*;
+import static com.epam.dlab.rest.contracts.ApiCallbacks.EDGE;
+import static com.epam.dlab.rest.contracts.ApiCallbacks.KEY_LOADER;
+import static com.epam.dlab.rest.contracts.ApiCallbacks.STATUS_URI;
/**
* Provides API to manage Edge node on GCP
*/
-@Path(EdgeAPI.EDGE)
+@Path("infrastructure/edge")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Slf4j
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java
index 65d4b70..8770591 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.service;
import com.epam.dlab.auth.UserInfo;
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/CheckInactivityServiceImpl.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/CheckInactivityServiceImpl.java
index 3713589..59e67b4 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/CheckInactivityServiceImpl.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/CheckInactivityServiceImpl.java
@@ -118,7 +118,7 @@
commandExecutor.executeAsync(userName, uuid, command);
} catch (Exception e) {
log.error("Exception occured during reuploading key: {} for command {}", e.getLocalizedMessage(),
- dockerCmd.toCMD());
+ dockerCmd.toCMD(), e);
}
}
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/KeyService.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/KeyService.java
index bbedc68..5d650da 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/KeyService.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/KeyService.java
@@ -89,7 +89,7 @@
commandExecutor.executeAsync(userName, uuid, command);
} catch (Exception e) {
log.error("Exception occured during reuploading key: {} for command {}", e.getLocalizedMessage(),
- runDockerCommand.toCMD());
+ runDockerCommand.toCMD(), e);
}
}
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java
index 1daf93f..5f24a1e 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.service.impl;
import com.epam.dlab.auth.UserInfo;
@@ -29,16 +48,22 @@
private static final String PROJECT_IMAGE = "docker.dlab-project";
private static final String EDGE_IMAGE = "docker.dlab-edge";
private static final String CALLBACK_URI = "/api/project/status";
+
+ protected final RESTService selfService;
+ private final ProvisioningServiceApplicationConfiguration configuration;
+ private final FolderListenerExecutor folderListenerExecutor;
+ private final ICommandExecutor commandExecutor;
+ private final CommandBuilder commandBuilder;
+
@Inject
- protected RESTService selfService;
- @Inject
- private ProvisioningServiceApplicationConfiguration configuration;
- @Inject
- private FolderListenerExecutor folderListenerExecutor;
- @Inject
- private ICommandExecutor commandExecutor;
- @Inject
- private CommandBuilder commandBuilder;
+ public ProjectServiceImpl(RESTService selfService, ProvisioningServiceApplicationConfiguration configuration,
+ FolderListenerExecutor folderListenerExecutor, ICommandExecutor commandExecutor, CommandBuilder commandBuilder) {
+ this.selfService = selfService;
+ this.configuration = configuration;
+ this.folderListenerExecutor = folderListenerExecutor;
+ this.commandExecutor = commandExecutor;
+ this.commandBuilder = commandBuilder;
+ }
@Override
public String create(UserInfo userInfo, ProjectCreateDTO dto) {
@@ -63,7 +88,7 @@
}
private String executeDocker(UserInfo userInfo, ResourceBaseDTO dto, DockerAction action, String projectName,
- String resourceType, String image, String endpoint) {
+ String resourceType, String image, String endpoint) {
String uuid = DockerCommands.generateUUID();
folderListenerExecutor.start(configuration.getKeyLoaderDirectory(),
@@ -92,7 +117,7 @@
try {
commandExecutor.executeAsync(userInfo.getName(), uuid, commandBuilder.buildCommand(runDockerCommand, dto));
} catch (JsonProcessingException e) {
- e.printStackTrace();
+ log.error("Something went wrong. Reason {}", e.getMessage(), e);
}
return uuid;
}
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/aws/BucketServiceAwsImpl.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/aws/BucketServiceAwsImpl.java
index 79831a4..6c5673d 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/aws/BucketServiceAwsImpl.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/aws/BucketServiceAwsImpl.java
@@ -48,19 +48,18 @@
@Override
public List<BucketDTO> getObjects(String bucket) {
- try {
- S3Client s3 = S3Client.create();
- ListObjectsRequest getRequest = ListObjectsRequest
- .builder()
- .bucket(bucket)
- .build();
+ try (S3Client s3 = S3Client.create()) {
+ ListObjectsRequest getRequest = ListObjectsRequest
+ .builder()
+ .bucket(bucket)
+ .build();
- return s3.listObjects(getRequest).contents()
- .stream()
- .map(o -> toBucketDTO(bucket, o))
- .collect(Collectors.toList());
+ return s3.listObjects(getRequest).contents()
+ .stream()
+ .map(o -> toBucketDTO(bucket, o))
+ .collect(Collectors.toList());
} catch (Exception e) {
- log.error("Cannot retrieve objects from bucket {}. Reason: {}", bucket, e.getMessage());
+ log.error("Cannot retrieve objects from bucket {}. Reason: {}", bucket, e.getMessage(), e);
throw new DlabException(String.format("Cannot retrieve objects from bucket %s. Reason: %s", bucket, e.getMessage()));
}
}
@@ -68,18 +67,17 @@
@Override
public void uploadObject(String bucket, String object, InputStream stream, String contentType, long fileSize) {
log.info("Uploading file {} to bucket {}", object, bucket);
- try {
- S3Client s3 = S3Client.create();
- PutObjectRequest uploadRequest = PutObjectRequest
- .builder()
- .bucket(bucket)
- .key(object)
- .contentType(contentType)
- .build();
- s3.putObject(uploadRequest, RequestBody.fromInputStream(stream, fileSize));
- } catch (Exception e) {
- log.error("Cannot upload object {} to bucket {}. Reason: {}", object, bucket, e.getMessage());
- throw new DlabException(String.format("Cannot upload object %s to bucket %s. Reason: %s", object, bucket, e.getMessage()));
+ try (S3Client s3 = S3Client.create()) {
+ PutObjectRequest uploadRequest = PutObjectRequest
+ .builder()
+ .bucket(bucket)
+ .key(object)
+ .contentType(contentType)
+ .build();
+ s3.putObject(uploadRequest, RequestBody.fromInputStream(stream, fileSize));
+ } catch (Exception e) {
+ log.error("Cannot upload object {} to bucket {}. Reason: {}", object, bucket, e.getMessage(), e);
+ throw new DlabException(String.format("Cannot upload object %s to bucket %s. Reason: %s", object, bucket, e.getMessage()));
}
log.info("Finished uploading file {} to bucket {}", object, bucket);
}
@@ -87,60 +85,57 @@
@Override
public void uploadFolder(UserInfo userInfo, String bucket, String folder) {
log.info("Uploading folder {} to bucket {}", folder, bucket);
- try {
- S3Client s3 = S3Client.create();
- PutObjectRequest uploadRequest = PutObjectRequest
- .builder()
- .bucket(bucket)
- .key(folder)
- .build();
- s3.putObject(uploadRequest, RequestBody.empty());
- } catch (Exception e) {
- log.error("Cannot upload folder {} to bucket {}. Reason: {}", folder, bucket, e.getMessage());
- throw new DlabException(String.format("Cannot upload folder %s to bucket %s. Reason: %s", folder, bucket, e.getMessage()));
- }
+ try (S3Client s3 = S3Client.create()) {
+ PutObjectRequest uploadRequest = PutObjectRequest
+ .builder()
+ .bucket(bucket)
+ .key(folder)
+ .build();
+ s3.putObject(uploadRequest, RequestBody.empty());
+ } catch (Exception e) {
+ log.error("Cannot upload folder {} to bucket {}. Reason: {}", folder, bucket, e.getMessage(), e);
+ throw new DlabException(String.format("Cannot upload folder %s to bucket %s. Reason: %s", folder, bucket, e.getMessage()));
+ }
log.info("Finished uploading folder {} to bucket {}", folder, bucket);
}
@Override
public void downloadObject(String bucket, String object, HttpServletResponse resp) {
log.info("Downloading file {} from bucket {}", object, bucket);
- try (ServletOutputStream outputStream = resp.getOutputStream()) {
- S3Client s3 = S3Client.create();
- GetObjectRequest downloadRequest = GetObjectRequest
- .builder()
- .bucket(bucket)
- .key(object)
- .build();
- s3.getObject(downloadRequest, ResponseTransformer.toOutputStream(outputStream));
- } catch (Exception e) {
- log.error("Cannot download object {} from bucket {}. Reason: {}", object, bucket, e.getMessage());
- throw new DlabException(String.format("Cannot download object %s from bucket %s. Reason: %s", object, bucket, e.getMessage()));
- }
+ try (ServletOutputStream outputStream = resp.getOutputStream(); S3Client s3 = S3Client.create()) {
+ GetObjectRequest downloadRequest = GetObjectRequest
+ .builder()
+ .bucket(bucket)
+ .key(object)
+ .build();
+ s3.getObject(downloadRequest, ResponseTransformer.toOutputStream(outputStream));
+ } catch (Exception e) {
+ log.error("Cannot download object {} from bucket {}. Reason: {}", object, bucket, e.getMessage(), e);
+ throw new DlabException(String.format("Cannot download object %s from bucket %s. Reason: %s", object, bucket, e.getMessage()));
+ }
log.info("Finished downloading file {} from bucket {}", object, bucket);
}
@Override
public void deleteObjects(String bucket, List<String> objects) {
- try {
- S3Client s3 = S3Client.create();
- List<ObjectIdentifier> objectsToDelete = objects
- .stream()
- .map(o -> ObjectIdentifier.builder()
- .key(o)
- .build())
- .collect(Collectors.toList());
+ try (S3Client s3 = S3Client.create()) {
+ List<ObjectIdentifier> objectsToDelete = objects
+ .stream()
+ .map(o -> ObjectIdentifier.builder()
+ .key(o)
+ .build())
+ .collect(Collectors.toList());
- DeleteObjectsRequest deleteObjectsRequests = DeleteObjectsRequest.builder()
- .bucket(bucket)
- .delete(Delete.builder()
+ DeleteObjectsRequest deleteObjectsRequests = DeleteObjectsRequest.builder()
+ .bucket(bucket)
+ .delete(Delete.builder()
.objects(objectsToDelete)
.build())
.build();
s3.deleteObjects(deleteObjectsRequests);
} catch (Exception e) {
- log.error("Cannot delete objects {} from bucket {}. Reason: {}", objects, bucket, e.getMessage());
+ log.error("Cannot delete objects {} from bucket {}. Reason: {}", objects, bucket, e.getMessage(), e);
throw new DlabException(String.format("Cannot delete objects %s from bucket %s. Reason: %s", objects, bucket, e.getMessage()));
}
}
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/azure/BucketServiceAzureImpl.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/azure/BucketServiceAzureImpl.java
index 3d1eec4..073aca2 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/azure/BucketServiceAzureImpl.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/azure/BucketServiceAzureImpl.java
@@ -68,7 +68,7 @@
.map(blob -> toBucketDTO(account.getContainer(), blob))
.collect(Collectors.toList());
} catch (Exception e) {
- log.error("Cannot retrieve objects from bucket {}. Reason: {}", bucket, e.getMessage());
+ log.error("Cannot retrieve objects from bucket {}. Reason: {}", bucket, e.getMessage(), e);
throw new DlabException(String.format("Cannot retrieve objects from bucket %s. Reason: %s", bucket, e.getMessage()));
}
}
@@ -83,7 +83,7 @@
BlobClient blobClient = blobContainerClient.getBlobClient(object);
blobClient.upload(stream, fileSize);
} catch (Exception e) {
- log.error("Cannot upload object {} to bucket {}. Reason: {}", object, bucket, e.getMessage());
+ log.error("Cannot upload object {} to bucket {}. Reason: {}", object, bucket, e.getMessage(), e);
throw new DlabException(String.format("Cannot upload object %s to bucket %s. Reason: %s", object, bucket, e.getMessage()));
}
log.info("Finished uploading file {} to bucket {}", object, bucket);
@@ -104,7 +104,7 @@
BlobClient blobClient = blobContainerClient.getBlobClient(object);
blobClient.download(outputStream);
} catch (Exception e) {
- log.error("Cannot download object {} from bucket {}. Reason: {}", object, bucket, e.getMessage());
+ log.error("Cannot download object {} from bucket {}. Reason: {}", object, bucket, e.getMessage(), e);
throw new DlabException(String.format("Cannot download object %s from bucket %s. Reason: %s", object, bucket, e.getMessage()));
}
log.info("Finished downloading file {} from bucket {}", object, bucket);
@@ -118,7 +118,7 @@
BlobContainerClient blobContainerClient = blobServiceClient.getBlobContainerClient(account.getContainer());
objects.forEach(object -> blobContainerClient.getBlobClient(object).delete());
} catch (Exception e) {
- log.error("Cannot delete objects {} from bucket {}. Reason: {}", objects, bucket, e.getMessage());
+ log.error("Cannot delete objects {} from bucket {}. Reason: {}", objects, bucket, e.getMessage(), e);
throw new DlabException(String.format("Cannot delete objects %s from bucket %s. Reason: %s", objects, bucket, e.getMessage()));
}
}
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/gcp/BucketServiceGcpImpl.java b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/gcp/BucketServiceGcpImpl.java
index 2f0b15a..4a28bf6 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/gcp/BucketServiceGcpImpl.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/backendapi/service/impl/gcp/BucketServiceGcpImpl.java
@@ -52,7 +52,7 @@
.map(this::toBucketDTO)
.collect(Collectors.toList());
} catch (Exception e) {
- log.error("Cannot retrieve objects from bucket {}. Reason: {}", bucket, e.getMessage());
+ log.error("Cannot retrieve objects from bucket {}. Reason: {}", bucket, e.getMessage(), e);
throw new DlabException(String.format("Cannot retrieve objects from bucket %s. Reason: %s", bucket, e.getMessage()));
}
}
@@ -68,7 +68,7 @@
.build();
storage.create(blobInfo, stream);
} catch (Exception e) {
- log.error("Cannot upload object {} to bucket {}. Reason: {}", object, bucket, e.getMessage());
+ log.error("Cannot upload object {} to bucket {}. Reason: {}", object, bucket, e.getMessage(), e);
throw new DlabException(String.format("Cannot upload object %s to bucket %s. Reason: %s", object, bucket, e.getMessage()));
}
log.info("Finished uploading file {} to bucket {}", object, bucket);
@@ -83,7 +83,7 @@
BlobInfo blobInfo = BlobInfo.newBuilder(blobId).build();
storage.create(blobInfo);
} catch (Exception e) {
- log.error("Cannot upload folder {} to bucket {}. Reason: {}", folder, bucket, e.getMessage());
+ log.error("Cannot upload folder {} to bucket {}. Reason: {}", folder, bucket, e.getMessage(), e);
throw new DlabException(String.format("Cannot upload folder %s to bucket %s. Reason: %s", folder, bucket, e.getMessage()));
}
log.info("Finished uploading folder {} to bucket {}", folder, bucket);
@@ -98,7 +98,7 @@
blob.downloadTo(outputStream);
log.info("Finished downloading file {} from bucket {}", object, bucket);
} catch (Exception e) {
- log.error("Cannot download object {} from bucket {}. Reason: {}", object, bucket, e.getMessage());
+ log.error("Cannot download object {} from bucket {}. Reason: {}", object, bucket, e.getMessage(), e);
throw new DlabException(String.format("Cannot download object %s from bucket %s. Reason: %s", object, bucket, e.getMessage()));
}
log.info("Finished downloading file {} from bucket {}", object, bucket);
@@ -114,7 +114,7 @@
.collect(Collectors.toList());
storage.delete(blobIds);
} catch (Exception e) {
- log.error("Cannot delete objects {} from bucket {}. Reason: {}", objects, bucket, e.getMessage());
+ log.error("Cannot delete objects {} from bucket {}. Reason: {}", objects, bucket, e.getMessage(), e);
throw new DlabException(String.format("Cannot delete objects %s from bucket %s. Reason: %s", objects, bucket, e.getMessage()));
}
}
diff --git a/services/provisioning-service/src/main/java/com/epam/dlab/process/builder/ProcessInfoBuilder.java b/services/provisioning-service/src/main/java/com/epam/dlab/process/builder/ProcessInfoBuilder.java
index f790fea..15a0e1e 100644
--- a/services/provisioning-service/src/main/java/com/epam/dlab/process/builder/ProcessInfoBuilder.java
+++ b/services/provisioning-service/src/main/java/com/epam/dlab/process/builder/ProcessInfoBuilder.java
@@ -38,7 +38,16 @@
import java.util.function.Function;
import java.util.function.Supplier;
-import static com.epam.dlab.process.model.ProcessStatus.*;
+import static com.epam.dlab.process.model.ProcessStatus.CREATED;
+import static com.epam.dlab.process.model.ProcessStatus.FAILED;
+import static com.epam.dlab.process.model.ProcessStatus.FINISHED;
+import static com.epam.dlab.process.model.ProcessStatus.KILLED;
+import static com.epam.dlab.process.model.ProcessStatus.LAUNCHING;
+import static com.epam.dlab.process.model.ProcessStatus.REJECTED;
+import static com.epam.dlab.process.model.ProcessStatus.RUNNING;
+import static com.epam.dlab.process.model.ProcessStatus.SCHEDULED;
+import static com.epam.dlab.process.model.ProcessStatus.STOPPED;
+import static com.epam.dlab.process.model.ProcessStatus.TIMEOUT;
@Slf4j
public class ProcessInfoBuilder implements Supplier<ProcessInfo>, Testing, TimeoutAction, Expireable {
@@ -168,7 +177,7 @@
try {
future.get();
} catch (Exception e) {
- log.error("Exception occurred during getting future result: {}", e.getMessage());
+ log.error("Exception occurred during getting future result: {}", e.getMessage(), e);
}
});
}
@@ -267,14 +276,14 @@
try {
return fPid.getInt(p);
} catch (IllegalAccessException e) {
- log.error("Unable to access PID. {}", e.getMessage());
+ log.error("Unable to access PID. {}", e.getMessage(), e);
return -1;
}
};
}
return pidSupplier.apply(process);
} catch (NoSuchFieldException e) {
- log.debug("PID field not found");
+ log.debug("PID field not found", e);
pidSupplier = p -> -1;
return -1;
}
diff --git a/services/self-service/entrypoint.sh b/services/self-service/entrypoint.sh
index ba2d35e..c3c47fd 100644
--- a/services/self-service/entrypoint.sh
+++ b/services/self-service/entrypoint.sh
@@ -1,5 +1,26 @@
#!/bin/sh
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
checkfile () {
if [ -s /root/step-certs/ca.crt ]
then
diff --git a/services/self-service/pom.xml b/services/self-service/pom.xml
index f21caf9..b5c075b 100644
--- a/services/self-service/pom.xml
+++ b/services/self-service/pom.xml
@@ -257,6 +257,17 @@
<exclude>**/*Module.*</exclude>
<exclude>**/*Form.*</exclude>
<exclude>com/epam/dlab/dto/**/*</exclude>
+ <exclude>com/epam/dlab/backendapi/auth/**/*</exclude>
+ <exclude>com/epam/dlab/backendapi/conf/**/*</exclude>
+ <exclude>com/epam/dlab/backendapi/domain/**/*</exclude>
+ <exclude>com/epam/dlab/backendapi/dropwizard/**/*</exclude>
+ <exclude>com/epam/dlab/backendapi/healthcheck/**/*</exclude>
+ <exclude>com/epam/dlab/backendapi/modules/**/*</exclude>
+ <exclude>com/epam/dlab/backendapi/resources/dto/**/*</exclude>
+ <exclude>com/epam/dlab/backendapi/roles/**/*</exclude>
+ <exclude>com/epam/dlab/backendapi/servlet/guacamole/**/*</exclude>
+ <exclude>com/epam/dlab/backendapi/util/**/*</exclude>
+ <exclude>com/epam/dlab/backendapi/validation/**/*</exclude>
</excludes>
</configuration>
</plugin>
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/annotation/Project.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/annotation/Project.java
index 5a1e5d4..0ce3414 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/annotation/Project.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/annotation/Project.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.annotation;
import java.lang.annotation.ElementType;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/auth/KeycloakAuthenticator.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/auth/KeycloakAuthenticator.java
index 5c24010..4b39290 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/auth/KeycloakAuthenticator.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/auth/KeycloakAuthenticator.java
@@ -1,15 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.auth;
import com.epam.dlab.auth.UserInfo;
import de.ahus1.keycloak.dropwizard.AbstractKeycloakAuthenticator;
import de.ahus1.keycloak.dropwizard.KeycloakConfiguration;
-import io.dropwizard.auth.AuthenticationException;
import org.keycloak.KeycloakSecurityContext;
import org.keycloak.representations.AccessToken;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
-import java.util.Optional;
import static java.util.Collections.emptyList;
@@ -22,16 +39,10 @@
}
@Override
- public Optional<UserInfo> authenticate(HttpServletRequest request) throws AuthenticationException {
- return super.authenticate(request);
-
- }
-
- @Override
@SuppressWarnings("unchecked")
protected UserInfo prepareAuthentication(KeycloakSecurityContext keycloakSecurityContext,
- HttpServletRequest httpServletRequest,
- KeycloakConfiguration keycloakConfiguration) {
+ HttpServletRequest httpServletRequest,
+ KeycloakConfiguration keycloakConfiguration) {
final AccessToken token = keycloakSecurityContext.getToken();
final UserInfo userInfo = new UserInfo(token.getPreferredUsername(),
keycloakSecurityContext.getTokenString());
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/auth/filters/DropwizardBearerTokenFilterImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/auth/filters/DropwizardBearerTokenFilterImpl.java
index 8c72669..df6f5fa 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/auth/filters/DropwizardBearerTokenFilterImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/auth/filters/DropwizardBearerTokenFilterImpl.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.auth.filters;
import org.keycloak.adapters.AdapterDeploymentContext;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/conf/CloudConfiguration.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/conf/CloudConfiguration.java
index bdc6ba5..2693e4b 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/conf/CloudConfiguration.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/conf/CloudConfiguration.java
@@ -1,9 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.conf;
import com.fasterxml.jackson.annotation.JsonProperty;
-import lombok.AllArgsConstructor;
import lombok.Data;
-import lombok.NoArgsConstructor;
@Data
public class CloudConfiguration {
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/conf/KeycloakConfiguration.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/conf/KeycloakConfiguration.java
index b252de9..212d565 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/conf/KeycloakConfiguration.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/conf/KeycloakConfiguration.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.conf;
import lombok.Data;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/AuditDAOImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/AuditDAOImpl.java
index 1106fdb..9886449 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/AuditDAOImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/AuditDAOImpl.java
@@ -57,7 +57,7 @@
import static com.mongodb.client.model.Filters.lte;
public class AuditDAOImpl extends BaseDAO implements AuditDAO {
- private final static String AUDIT_COLLECTION = "audit";
+ private static final String AUDIT_COLLECTION = "audit";
private static final String RESOURCE_NAME_FIELD = "resourceName";
private static final String RESOURCE_TYPE_FIELD = "type";
private static final String TIMESTAMP_FIELD = "timestamp";
@@ -86,8 +86,8 @@
countPipeline.add(match);
}
countPipeline.add(count());
- valuesPipeline.addAll(Arrays.asList(skip(pageSize * (pageNumber - 1)), limit(pageSize)));
valuesPipeline.add(sortCriteria());
+ valuesPipeline.addAll(Arrays.asList(skip(pageSize * (pageNumber - 1)), limit(pageSize)));
List<Bson> userFilter = Collections.singletonList(group(getGroupingFields(USER)));
List<Bson> projectFilter = Collections.singletonList(group(getGroupingFields(PROJECT)));
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDao.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDAO.java
similarity index 97%
rename from services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDao.java
rename to services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDAO.java
index e48c5ea..1a2a11c 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDao.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDAO.java
@@ -26,7 +26,7 @@
import java.util.List;
import java.util.Optional;
-public interface BackupDao {
+public interface BackupDAO {
void createOrUpdate(EnvBackupDTO dto, String user, EnvBackupStatus status);
List<BackupInfoRecord> getBackups(String userName);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDaoImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDAOImpl.java
similarity index 97%
rename from services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDaoImpl.java
rename to services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDAOImpl.java
index f1b599c..4ed2788 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDaoImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BackupDAOImpl.java
@@ -34,7 +34,7 @@
import static com.mongodb.client.model.Filters.eq;
@Singleton
-public class BackupDaoImpl extends BaseDAO implements BackupDao {
+public class BackupDAOImpl extends BaseDAO implements BackupDAO {
@Override
public void createOrUpdate(EnvBackupDTO dto, String user, EnvBackupStatus status) {
final Document idField = backupId(user, dto.getId());
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BaseBillingDAO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BaseBillingDAO.java
index 7975eeb..56a77a0 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BaseBillingDAO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/BaseBillingDAO.java
@@ -25,6 +25,7 @@
import com.google.inject.Inject;
import com.mongodb.client.model.Aggregates;
import com.mongodb.client.model.Filters;
+import com.mongodb.client.model.Sorts;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
@@ -48,6 +49,7 @@
import static com.mongodb.client.model.Accumulators.sum;
import static com.mongodb.client.model.Aggregates.group;
import static com.mongodb.client.model.Aggregates.match;
+import static com.mongodb.client.model.Aggregates.sort;
import static com.mongodb.client.model.Filters.and;
import static com.mongodb.client.model.Filters.eq;
import static com.mongodb.client.model.Filters.gte;
@@ -152,6 +154,7 @@
pipeline.add(Aggregates.match(Filters.and(matchCriteria)));
}
pipeline.add(groupCriteria());
+ pipeline.add(usageDateSort());
return StreamSupport.stream(getCollection(BILLING).aggregate(pipeline).spliterator(), false)
.map(this::toBillingReport)
.collect(Collectors.toList());
@@ -187,6 +190,10 @@
.orElse(BigDecimal.ZERO.doubleValue());
}
+ private Bson usageDateSort() {
+ return sort(Sorts.descending(USAGE_DATE));
+ }
+
private Bson groupCriteria() {
return group(getGroupingFields(USER, DLAB_ID, RESOURCE_TYPE, RESOURCE_NAME, PROJECT, PRODUCT, CURRENCY, SHAPE, EXPLORATORY),
sum(COST, "$" + COST),
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ExploratoryLibDAO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ExploratoryLibDAO.java
index 7fbb47a..d96f069 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ExploratoryLibDAO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ExploratoryLibDAO.java
@@ -22,6 +22,7 @@
import com.epam.dlab.backendapi.util.DateRemoverUtil;
import com.epam.dlab.dto.exploratory.LibInstallDTO;
import com.epam.dlab.dto.exploratory.LibInstallStatusDTO;
+import com.epam.dlab.dto.exploratory.LibStatus;
import com.epam.dlab.exceptions.DlabException;
import com.epam.dlab.model.ResourceType;
import com.epam.dlab.model.library.Library;
@@ -394,6 +395,7 @@
return ((List<Document>) libsDocument.getOrDefault(libFieldName, Collections.emptyList()))
.stream()
.map(d -> convertFromDocument(d, Library.class))
+ .filter(library -> LibStatus.INVALID_VERSION != library.getStatus())
.peek(l -> l.withType(libType).withResourceName(resourceName));
}
}
\ No newline at end of file
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDao.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDAO.java
similarity index 97%
rename from services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDao.java
rename to services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDAO.java
index 2665d47..9bab74d 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDao.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDAO.java
@@ -28,7 +28,7 @@
import java.util.List;
import java.util.Optional;
-public interface ImageExploratoryDao {
+public interface ImageExploratoryDAO {
boolean exist(String image, String project);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDaoImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDAOImpl.java
similarity index 90%
rename from services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDaoImpl.java
rename to services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDAOImpl.java
index 808dfbe..7aadcc4 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDaoImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ImageExploratoryDAOImpl.java
@@ -28,15 +28,23 @@
import org.bson.Document;
import org.bson.conversions.Bson;
-import java.util.*;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
import java.util.stream.Collectors;
-import static com.mongodb.client.model.Filters.*;
+import static com.mongodb.client.model.Filters.and;
+import static com.mongodb.client.model.Filters.eq;
+import static com.mongodb.client.model.Filters.in;
import static com.mongodb.client.model.Projections.elemMatch;
-import static com.mongodb.client.model.Projections.*;
+import static com.mongodb.client.model.Projections.excludeId;
+import static com.mongodb.client.model.Projections.fields;
+import static com.mongodb.client.model.Projections.include;
@Singleton
-public class ImageExploratoryDaoImpl extends BaseDAO implements ImageExploratoryDao {
+public class ImageExploratoryDAOImpl extends BaseDAO implements ImageExploratoryDAO {
private static final String LIBRARIES = "libraries";
private static final String IMAGE_NAME = "name";
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAO.java
index 9b7f0a0..24850cb 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAO.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.dao;
import com.epam.dlab.auth.UserInfo;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAOImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAOImpl.java
index d438eb5..f08e3a3 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAOImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/ProjectDAOImpl.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.dao;
import com.epam.dlab.auth.UserInfo;
@@ -40,10 +59,10 @@
private static final String ENDPOINT_FIELD = "endpoints.$.";
private static final String ANYUSER = Pattern.quote("$anyuser");
- private final UserGroupDao userGroupDao;
+ private final UserGroupDAO userGroupDao;
@Inject
- public ProjectDAOImpl(UserGroupDao userGroupDao) {
+ public ProjectDAOImpl(UserGroupDAO userGroupDao) {
this.userGroupDao = userGroupDao;
}
@@ -56,15 +75,18 @@
@Override
public List<ProjectDTO> getProjectsWithEndpointStatusNotIn(UserInstanceStatus... statuses) {
final List<String> statusList =
- Arrays.stream(statuses).map(UserInstanceStatus::name).collect(Collectors.toList());
+ Arrays.stream(statuses)
+ .map(UserInstanceStatus::name)
+ .collect(Collectors.toList());
return find(PROJECTS_COLLECTION, not(in(ENDPOINT_STATUS_FIELD, statusList)), ProjectDTO.class);
}
@Override
public List<ProjectDTO> getUserProjects(UserInfo userInfo, boolean active) {
- final Set<String> groups = Stream.concat(userGroupDao.getUserGroups(userInfo.getName()).stream(),
- userInfo.getRoles().stream())
+ Stream<String> userGroups = userGroupDao.getUserGroups(userInfo.getName()).stream();
+ Stream<String> roles = userInfo.getRoles().stream();
+ final Set<String> groups = Stream.concat(userGroups, roles)
.collect(Collectors.toSet());
return find(PROJECTS_COLLECTION, userProjectCondition(groups, active), ProjectDTO.class);
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/SecurityDAO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/SecurityDAO.java
index 0c76422..a0ec24f 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/SecurityDAO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/SecurityDAO.java
@@ -20,10 +20,8 @@
package com.epam.dlab.backendapi.dao;
import com.epam.dlab.auth.UserInfo;
-import com.epam.dlab.auth.dto.UserCredentialDTO;
import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
import com.epam.dlab.exceptions.DlabException;
-import com.epam.dlab.util.UsernameUtils;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.mongodb.client.FindIterable;
@@ -31,35 +29,35 @@
import org.bson.Document;
import org.keycloak.representations.AccessTokenResponse;
-import java.util.*;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
import java.util.stream.Collectors;
-import static com.epam.dlab.backendapi.dao.MongoCollections.LOGIN_ATTEMPTS;
import static com.epam.dlab.backendapi.dao.MongoCollections.ROLES;
-import static com.mongodb.client.model.Filters.*;
-import static com.mongodb.client.model.Projections.*;
+import static com.mongodb.client.model.Filters.and;
+import static com.mongodb.client.model.Filters.eq;
+import static com.mongodb.client.model.Filters.gte;
+import static com.mongodb.client.model.Filters.ne;
+import static com.mongodb.client.model.Projections.exclude;
+import static com.mongodb.client.model.Projections.fields;
+import static com.mongodb.client.model.Projections.include;
/**
* DAO write the attempt of user login into DLab.
*/
@Singleton
public class SecurityDAO extends BaseDAO {
+ private static final String SECURITY_COLLECTION = "security";
+ private static final String TOKEN_RESPONSE = "tokenResponse";
+ private static final String LAST_ACCESS = "last_access";
@Inject
private SelfServiceApplicationConfiguration conf;
- private static final String SECURITY_COLLECTION = "security";
- private static final String TOKEN_RESPONSE = "tokenResponse";
-
- /**
- * Write the attempt of user login into Mongo database.
- *
- * @param credentials user credentials.
- */
- public void writeLoginAttempt(UserCredentialDTO credentials) {
- insertOne(LOGIN_ATTEMPTS,
- () -> new Document("login", credentials.getUsername()).append("iamlogin", UsernameUtils.removeDomain
- (credentials.getUsername())));
- }
/**
* Return the roles or throw exception if roles collection does not exists.
@@ -83,7 +81,7 @@
new Document()
.append(ID, userName)
.append("created", new Date())
- .append("last_access", new Date())
+ .append(LAST_ACCESS, new Date())
.append(TOKEN_RESPONSE, convertToBson(accessTokenResponse))),
true);
}
@@ -93,15 +91,15 @@
new Document(SET,
new Document()
.append(ID, userName)
- .append("last_access", new Date())
+ .append(LAST_ACCESS, new Date())
.append(TOKEN_RESPONSE, convertToBson(accessTokenResponse))));
}
public Optional<UserInfo> getUser(String token) {
return Optional.ofNullable(mongoService.getCollection(SECURITY_COLLECTION)
- .findOneAndUpdate(and(eq(TOKEN_RESPONSE + ".access_token", token), gte("last_access",
+ .findOneAndUpdate(and(eq(TOKEN_RESPONSE + ".access_token", token), gte(LAST_ACCESS,
new Date(new Date().getTime() - conf.getInactiveUserTimeoutMillSec()))), new Document("$set",
- new Document("last_access", new Date()))))
+ new Document(LAST_ACCESS, new Date()))))
.map(d -> new UserInfo(d.getString(ID), token));
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDao.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDAO.java
similarity index 93%
rename from services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDao.java
rename to services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDAO.java
index 85ec7ae..9d6b72b 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDao.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDAO.java
@@ -20,7 +20,7 @@
import java.util.Set;
-public interface UserGroupDao {
+public interface UserGroupDAO {
void addUsers(String group, Set<String> users);
void updateUsers(String group, Set<String> users);
@@ -29,5 +29,5 @@
Set<String> getUserGroups(String user);
- Set<String> getUsers(String group);
+ Set<String> getUsers(String group);
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDaoImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDAOImpl.java
similarity index 96%
rename from services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDaoImpl.java
rename to services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDAOImpl.java
index ac66946..39fc11a 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDaoImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserGroupDAOImpl.java
@@ -32,7 +32,7 @@
import static com.mongodb.client.model.Filters.eq;
@Singleton
-public class UserGroupDaoImpl extends BaseDAO implements UserGroupDao {
+public class UserGroupDAOImpl extends BaseDAO implements UserGroupDAO {
private static final String USERS_FIELD = "users";
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDao.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDAO.java
similarity index 97%
rename from services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDao.java
rename to services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDAO.java
index 48abb54..5de090c 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDao.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDAO.java
@@ -26,7 +26,7 @@
import java.util.List;
import java.util.Set;
-public interface UserRoleDao {
+public interface UserRoleDAO {
List<UserRoleDto> findAll();
void insert(UserRoleDto dto);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDaoImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDAOImpl.java
similarity index 97%
rename from services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDaoImpl.java
rename to services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDAOImpl.java
index e95a41b..2eced33 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDaoImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dao/UserRoleDAOImpl.java
@@ -27,6 +27,7 @@
import com.google.inject.Singleton;
import com.mongodb.client.model.BsonField;
import com.mongodb.client.result.UpdateResult;
+import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.bson.conversions.Bson;
@@ -53,7 +54,8 @@
import static java.util.stream.Collectors.toList;
@Singleton
-public class UserRoleDaoImpl extends BaseDAO implements UserRoleDao {
+@Slf4j
+public class UserRoleDAOImpl extends BaseDAO implements UserRoleDAO {
private static final ObjectMapper MAPPER = new ObjectMapper();
private static final String[] DEFAULT_AWS_SHAPES = {"nbShapes_t2.medium_fetching", "compShapes_c4.xlarge_fetching"};
private static final String[] DEFAULT_GCP_SHAPES = {"compShapes_n1-standard-2_fetching", "nbShapes_n1-standard-2_fetching"};
@@ -177,6 +179,7 @@
return MAPPER.readValue(is, new TypeReference<List<UserRoleDto>>() {
});
} catch (IOException e) {
+ log.error("Can not marshall dlab roles due to: {}", e.getMessage(), e);
throw new IllegalStateException("Can not marshall dlab roles due to: " + e.getMessage());
}
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/CreateProjectDTO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/CreateProjectDTO.java
index dafb21f..b92d480 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/CreateProjectDTO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/CreateProjectDTO.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.domain;
import com.fasterxml.jackson.annotation.JsonProperty;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/EndpointDTO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/EndpointDTO.java
index f288a68..fcf2475 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/EndpointDTO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/EndpointDTO.java
@@ -24,7 +24,6 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import org.hibernate.validator.constraints.NotBlank;
-import org.hibernate.validator.constraints.NotEmpty;
import org.hibernate.validator.constraints.URL;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectDTO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectDTO.java
index 32e67ec..a8b30f2 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectDTO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectDTO.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.domain;
import com.epam.dlab.dto.UserInstanceStatus;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectEndpointDTO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectEndpointDTO.java
index 5a2f2ba..66b1dac 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectEndpointDTO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/ProjectEndpointDTO.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.domain;
import com.epam.dlab.dto.UserInstanceStatus;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/UpdateProjectBudgetDTO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/UpdateProjectBudgetDTO.java
index bf94438..472d34b 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/UpdateProjectBudgetDTO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/UpdateProjectBudgetDTO.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.domain;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/UpdateProjectDTO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/UpdateProjectDTO.java
index e4070bb..4622ac5 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/UpdateProjectDTO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/domain/UpdateProjectDTO.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.domain;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/bundles/DlabKeycloakBundle.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/bundles/DlabKeycloakBundle.java
index 5089c1c..b963160 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/bundles/DlabKeycloakBundle.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/bundles/DlabKeycloakBundle.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.dropwizard.bundles;
import com.epam.dlab.auth.UserInfo;
@@ -9,7 +28,6 @@
import de.ahus1.keycloak.dropwizard.KeycloakConfiguration;
import io.dropwizard.auth.Authenticator;
import io.dropwizard.auth.Authorizer;
-import io.dropwizard.setup.Environment;
import java.security.Principal;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/listeners/MongoStartupListener.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/listeners/MongoStartupListener.java
index d25e2dd..d029e86 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/listeners/MongoStartupListener.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/listeners/MongoStartupListener.java
@@ -1,9 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.dropwizard.listeners;
import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
import com.epam.dlab.backendapi.dao.EndpointDAO;
import com.epam.dlab.backendapi.dao.SettingsDAO;
-import com.epam.dlab.backendapi.dao.UserRoleDao;
+import com.epam.dlab.backendapi.dao.UserRoleDAO;
import com.epam.dlab.backendapi.resources.dto.UserRoleDto;
import com.epam.dlab.cloud.CloudProvider;
import com.fasterxml.jackson.core.type.TypeReference;
@@ -32,14 +51,14 @@
private static final String ROLES_FILE_FORMAT = "/mongo/%s/mongo_roles.json";
private static final ObjectMapper MAPPER = new ObjectMapper();
- private final UserRoleDao userRoleDao;
+ private final UserRoleDAO userRoleDao;
private final SelfServiceApplicationConfiguration configuration;
private final SettingsDAO settingsDAO;
private final EndpointDAO endpointDAO;
@Inject
- public MongoStartupListener(UserRoleDao userRoleDao, SelfServiceApplicationConfiguration configuration,
- SettingsDAO settingsDAO, EndpointDAO endpointDAO) {
+ public MongoStartupListener(UserRoleDAO userRoleDao, SelfServiceApplicationConfiguration configuration,
+ SettingsDAO settingsDAO, EndpointDAO endpointDAO) {
this.userRoleDao = userRoleDao;
this.configuration = configuration;
this.settingsDAO = settingsDAO;
@@ -71,7 +90,7 @@
return MAPPER.readValue(is, new TypeReference<List<UserRoleDto>>() {
});
} catch (IOException e) {
- log.error("Can not marshall dlab roles due to: {}", e.getMessage());
+ log.error("Can not marshall dlab roles due to: {}", e.getMessage(), e);
throw new IllegalStateException("Can not marshall dlab roles due to: " + e.getMessage());
}
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/listeners/RestoreHandlerStartupListener.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/listeners/RestoreHandlerStartupListener.java
index 0de166c..a92cae5 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/listeners/RestoreHandlerStartupListener.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/dropwizard/listeners/RestoreHandlerStartupListener.java
@@ -44,7 +44,7 @@
endpointService.getEndpointsWithStatus(EndpointDTO.EndpointStatus.ACTIVE)
.forEach(e -> provisioningService.post(e.getUrl() + "/handler/restore", StringUtils.EMPTY, Object.class));
} catch (Exception e) {
- log.error("Exception occurred during restore handler request: {}", e.getMessage());
+ log.error("Exception occurred during restore handler request: {}", e.getMessage(), e);
}
}
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/healthcheck/MongoHealthCheck.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/healthcheck/MongoHealthCheck.java
index 262671c..5ce1b28 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/healthcheck/MongoHealthCheck.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/healthcheck/MongoHealthCheck.java
@@ -38,7 +38,7 @@
try {
mongoService.ping();
} catch (Exception e) {
- log.error("Mongo is unavailable {}", e.getMessage());
+ log.error("Mongo is unavailable {}", e.getMessage(), e);
return Result.unhealthy(e.getMessage());
}
return Result.healthy();
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/interceptor/BudgetLimitInterceptor.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/interceptor/BudgetLimitInterceptor.java
index ce32e10..a9058bd 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/interceptor/BudgetLimitInterceptor.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/interceptor/BudgetLimitInterceptor.java
@@ -19,7 +19,6 @@
package com.epam.dlab.backendapi.interceptor;
-import com.epam.dlab.auth.UserInfo;
import com.epam.dlab.backendapi.annotation.Project;
import com.epam.dlab.backendapi.dao.BillingDAO;
import com.epam.dlab.backendapi.service.BillingService;
@@ -31,7 +30,6 @@
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
-import java.util.Arrays;
import java.util.Objects;
import java.util.stream.IntStream;
@@ -53,15 +51,6 @@
}
}
- private Boolean userQuoteReached(MethodInvocation mi) {
- return Arrays.stream(mi.getArguments())
- .filter(arg -> arg.getClass().equals(UserInfo.class))
- .findAny()
- .map(u -> ((UserInfo) u).getName())
- .map(billingDAO::isUserQuoteReached)
- .orElse(Boolean.FALSE);
- }
-
private Boolean projectQuoteReached(MethodInvocation mi) {
final Parameter[] parameters = mi.getMethod().getParameters();
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/DevModule.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/DevModule.java
index 5c8f9bf..c0c0912 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/DevModule.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/DevModule.java
@@ -25,20 +25,20 @@
import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
import com.epam.dlab.backendapi.dao.AuditDAO;
import com.epam.dlab.backendapi.dao.AuditDAOImpl;
-import com.epam.dlab.backendapi.dao.BackupDao;
-import com.epam.dlab.backendapi.dao.BackupDaoImpl;
+import com.epam.dlab.backendapi.dao.BackupDAO;
+import com.epam.dlab.backendapi.dao.BackupDAOImpl;
import com.epam.dlab.backendapi.dao.BaseBillingDAO;
import com.epam.dlab.backendapi.dao.BillingDAO;
import com.epam.dlab.backendapi.dao.EndpointDAO;
import com.epam.dlab.backendapi.dao.EndpointDAOImpl;
-import com.epam.dlab.backendapi.dao.ImageExploratoryDao;
-import com.epam.dlab.backendapi.dao.ImageExploratoryDaoImpl;
+import com.epam.dlab.backendapi.dao.ImageExploratoryDAO;
+import com.epam.dlab.backendapi.dao.ImageExploratoryDAOImpl;
import com.epam.dlab.backendapi.dao.ProjectDAO;
import com.epam.dlab.backendapi.dao.ProjectDAOImpl;
-import com.epam.dlab.backendapi.dao.UserGroupDao;
-import com.epam.dlab.backendapi.dao.UserGroupDaoImpl;
-import com.epam.dlab.backendapi.dao.UserRoleDao;
-import com.epam.dlab.backendapi.dao.UserRoleDaoImpl;
+import com.epam.dlab.backendapi.dao.UserGroupDAO;
+import com.epam.dlab.backendapi.dao.UserGroupDAOImpl;
+import com.epam.dlab.backendapi.dao.UserRoleDAO;
+import com.epam.dlab.backendapi.dao.UserRoleDAOImpl;
import com.epam.dlab.backendapi.service.AccessKeyService;
import com.epam.dlab.backendapi.service.ApplicationSettingService;
import com.epam.dlab.backendapi.service.ApplicationSettingServiceImpl;
@@ -145,9 +145,9 @@
.toInstance(configuration.getBillingFactory()
.build(environment, ServiceConsts.BILLING_SERVICE_NAME));
bind(ImageExploratoryService.class).to(ImageExploratoryServiceImpl.class);
- bind(ImageExploratoryDao.class).to(ImageExploratoryDaoImpl.class);
+ bind(ImageExploratoryDAO.class).to(ImageExploratoryDAOImpl.class);
bind(BackupService.class).to(BackupServiceImpl.class);
- bind(BackupDao.class).to(BackupDaoImpl.class);
+ bind(BackupDAO.class).to(BackupDAOImpl.class);
bind(ExploratoryService.class).to(ExploratoryServiceImpl.class);
bind(TagService.class).to(TagServiceImpl.class);
bind(InactivityService.class).to(InactivityServiceImpl.class);
@@ -166,8 +166,8 @@
bind(SystemInfoService.class).to(SystemInfoServiceImpl.class);
bind(UserGroupService.class).to(UserGroupServiceImpl.class);
bind(UserRoleService.class).to(UserRoleServiceImpl.class);
- bind(UserRoleDao.class).to(UserRoleDaoImpl.class);
- bind(UserGroupDao.class).to(UserGroupDaoImpl.class);
+ bind(UserRoleDAO.class).to(UserRoleDAOImpl.class);
+ bind(UserGroupDAO.class).to(UserGroupDAOImpl.class);
bind(ApplicationSettingService.class).to(ApplicationSettingServiceImpl.class);
bind(UserSettingService.class).to(UserSettingServiceImpl.class);
bind(GuacamoleService.class).to(GuacamoleServiceImpl.class);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/ProductionModule.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/ProductionModule.java
index 901a61f..2581026 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/ProductionModule.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/modules/ProductionModule.java
@@ -24,20 +24,20 @@
import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
import com.epam.dlab.backendapi.dao.AuditDAO;
import com.epam.dlab.backendapi.dao.AuditDAOImpl;
-import com.epam.dlab.backendapi.dao.BackupDao;
-import com.epam.dlab.backendapi.dao.BackupDaoImpl;
+import com.epam.dlab.backendapi.dao.BackupDAO;
+import com.epam.dlab.backendapi.dao.BackupDAOImpl;
import com.epam.dlab.backendapi.dao.BaseBillingDAO;
import com.epam.dlab.backendapi.dao.BillingDAO;
import com.epam.dlab.backendapi.dao.EndpointDAO;
import com.epam.dlab.backendapi.dao.EndpointDAOImpl;
-import com.epam.dlab.backendapi.dao.ImageExploratoryDao;
-import com.epam.dlab.backendapi.dao.ImageExploratoryDaoImpl;
+import com.epam.dlab.backendapi.dao.ImageExploratoryDAO;
+import com.epam.dlab.backendapi.dao.ImageExploratoryDAOImpl;
import com.epam.dlab.backendapi.dao.ProjectDAO;
import com.epam.dlab.backendapi.dao.ProjectDAOImpl;
-import com.epam.dlab.backendapi.dao.UserGroupDao;
-import com.epam.dlab.backendapi.dao.UserGroupDaoImpl;
-import com.epam.dlab.backendapi.dao.UserRoleDao;
-import com.epam.dlab.backendapi.dao.UserRoleDaoImpl;
+import com.epam.dlab.backendapi.dao.UserGroupDAO;
+import com.epam.dlab.backendapi.dao.UserGroupDAOImpl;
+import com.epam.dlab.backendapi.dao.UserRoleDAO;
+import com.epam.dlab.backendapi.dao.UserRoleDAOImpl;
import com.epam.dlab.backendapi.service.AccessKeyService;
import com.epam.dlab.backendapi.service.ApplicationSettingService;
import com.epam.dlab.backendapi.service.ApplicationSettingServiceImpl;
@@ -136,9 +136,9 @@
.toInstance(configuration.getBillingFactory()
.build(environment, ServiceConsts.BILLING_SERVICE_NAME));
bind(ImageExploratoryService.class).to(ImageExploratoryServiceImpl.class);
- bind(ImageExploratoryDao.class).to(ImageExploratoryDaoImpl.class);
+ bind(ImageExploratoryDAO.class).to(ImageExploratoryDAOImpl.class);
bind(BackupService.class).to(BackupServiceImpl.class);
- bind(BackupDao.class).to(BackupDaoImpl.class);
+ bind(BackupDAO.class).to(BackupDAOImpl.class);
bind(ExploratoryService.class).to(ExploratoryServiceImpl.class);
bind(Authorizer.class).to(SelfServiceSecurityAuthorizer.class);
bind(AccessKeyService.class).to(AccessKeyServiceImpl.class);
@@ -154,8 +154,8 @@
bind(SystemInfoService.class).to(SystemInfoServiceImpl.class);
bind(UserGroupService.class).to(UserGroupServiceImpl.class);
bind(UserRoleService.class).to(UserRoleServiceImpl.class);
- bind(UserRoleDao.class).to(UserRoleDaoImpl.class);
- bind(UserGroupDao.class).to(UserGroupDaoImpl.class);
+ bind(UserRoleDAO.class).to(UserRoleDAOImpl.class);
+ bind(UserGroupDAO.class).to(UserGroupDAOImpl.class);
bind(InactivityService.class).to(InactivityServiceImpl.class);
bind(ApplicationSettingService.class).to(ApplicationSettingServiceImpl.class);
bind(UserSettingService.class).to(UserSettingServiceImpl.class);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ImageExploratoryResource.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ImageExploratoryResource.java
index 282e1c6..e43f8c4 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ImageExploratoryResource.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ImageExploratoryResource.java
@@ -53,7 +53,7 @@
@Produces(MediaType.APPLICATION_JSON)
@Slf4j
public class ImageExploratoryResource {
- private final static String AUDIT_MESSAGE = "Create image: %s";
+ private static final String AUDIT_MESSAGE = "Create image: %s";
private final ImageExploratoryService imageExploratoryService;
private final RequestId requestId;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/KeycloakResource.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/KeycloakResource.java
index e7f8836..612a797 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/KeycloakResource.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/KeycloakResource.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.resources;
import com.epam.dlab.auth.UserInfo;
@@ -11,6 +30,7 @@
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.inject.Inject;
import io.dropwizard.auth.Auth;
+import lombok.extern.slf4j.Slf4j;
import org.keycloak.representations.AccessTokenResponse;
import javax.ws.rs.GET;
@@ -27,6 +47,7 @@
import static java.lang.String.format;
@Path("/oauth")
+@Slf4j
public class KeycloakResource {
private static final String LOGIN_URI_FORMAT = "%s/realms/%s/protocol/openid-connect/auth?client_id=%s" +
"&redirect_uri=%s&response_type=code";
@@ -42,7 +63,7 @@
@Inject
public KeycloakResource(SecurityService securityService, SelfServiceApplicationConfiguration configuration,
- SecurityDAO securityDAO, KeycloakService keycloakService) {
+ SecurityDAO securityDAO, KeycloakService keycloakService) {
this.securityDAO = securityDAO;
this.defaultAccess = configuration.getRoleDefaultAccess();
final KeycloakConfiguration keycloakConfiguration = configuration.getKeycloakConfiguration();
@@ -97,6 +118,7 @@
try {
tokenResponse = keycloakService.generateAccessToken(refreshToken);
} catch (DlabException e) {
+ log.error("Cannot refresh token due to: {}", e.getMessage(), e);
return Response.status(Response.Status.BAD_REQUEST)
.location(new URI(logoutUri))
.build();
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/LibExploratoryResource.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/LibExploratoryResource.java
index 2244460..1e4ee7b 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/LibExploratoryResource.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/LibExploratoryResource.java
@@ -60,7 +60,6 @@
@Produces(MediaType.APPLICATION_JSON)
@Slf4j
public class LibExploratoryResource {
- private static final String DROPWIZARD_ARTIFACT = "io.dropwizard:dropwizard-core:1.3.5";
private static final String AUDIT_MESSAGE = "Install libs: %s";
private final ExternalLibraryService externalLibraryService;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java
index 3d6a394..5b6a241 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/ProjectResource.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.resources;
import com.epam.dlab.auth.UserInfo;
@@ -73,7 +92,7 @@
@Consumes(MediaType.APPLICATION_JSON)
@RolesAllowed("/api/project/create")
public Response createProject(@Parameter(hidden = true) @Auth UserInfo userInfo,
- @Valid CreateProjectDTO projectDTO) {
+ @Valid CreateProjectDTO projectDTO) {
List<ProjectEndpointDTO> projectEndpointDTOS = projectDTO.getEndpoints()
.stream()
.map(e -> new ProjectEndpointDTO(e, UserInstanceStatus.CREATING, null))
@@ -100,7 +119,7 @@
@Consumes(MediaType.APPLICATION_JSON)
@RolesAllowed("/api/project")
public Response startProject(@Parameter(hidden = true) @Auth UserInfo userInfo,
- @NotNull @Valid ProjectActionFormDTO startProjectDto) {
+ @NotNull @Valid ProjectActionFormDTO startProjectDto) {
projectService.start(userInfo, startProjectDto.getEndpoints(), startProjectDto.getProjectName());
return Response
.accepted()
@@ -119,7 +138,7 @@
@Consumes(MediaType.APPLICATION_JSON)
@RolesAllowed("/api/project")
public Response stopProject(@Parameter(hidden = true) @Auth UserInfo userInfo,
- @NotNull @Valid ProjectActionFormDTO stopProjectDTO) {
+ @NotNull @Valid ProjectActionFormDTO stopProjectDTO) {
projectService.stopWithResources(userInfo, stopProjectDTO.getEndpoints(), stopProjectDTO.getProjectName());
return Response
.accepted()
@@ -140,8 +159,8 @@
@Produces(MediaType.APPLICATION_JSON)
@RolesAllowed("/api/project")
public Response getProject(@Parameter(hidden = true) @Auth UserInfo userInfo,
- @Parameter(description = "Project name")
- @PathParam("name") String name) {
+ @Parameter(description = "Project name")
+ @PathParam("name") String name) {
return Response
.ok(projectService.get(name))
.build();
@@ -172,7 +191,7 @@
@Path("/me")
@Produces(MediaType.APPLICATION_JSON)
public Response getUserProjects(@Parameter(hidden = true) @Auth UserInfo userInfo,
- @QueryParam("active") @DefaultValue("false") boolean active) {
+ @QueryParam("active") @DefaultValue("false") boolean active) {
return Response
.ok(projectService.getUserProjects(userInfo, active))
.build();
@@ -206,7 +225,7 @@
@Path("terminate")
@RolesAllowed("/api/project")
public Response removeProjectEndpoint(@Parameter(hidden = true) @Auth UserInfo userInfo,
- @NotNull @Valid ProjectActionFormDTO projectActionDTO) {
+ @NotNull @Valid ProjectActionFormDTO projectActionDTO) {
projectService.terminateEndpoint(userInfo, projectActionDTO.getEndpoints(), projectActionDTO.getProjectName());
return Response.ok().build();
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/GitCredsCallback.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/GitCredsCallback.java
index 5570232..3ef98c2 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/GitCredsCallback.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/GitCredsCallback.java
@@ -19,13 +19,11 @@
package com.epam.dlab.backendapi.resources.callback;
-import com.epam.dlab.auth.UserInfo;
import com.epam.dlab.backendapi.domain.RequestId;
import com.epam.dlab.dto.UserInstanceStatus;
import com.epam.dlab.dto.exploratory.ExploratoryStatusDTO;
import com.epam.dlab.rest.contracts.ApiCallbacks;
import com.google.inject.Inject;
-import io.dropwizard.auth.Auth;
import lombok.extern.slf4j.Slf4j;
import javax.ws.rs.Consumes;
@@ -54,7 +52,6 @@
@Path(ApiCallbacks.STATUS_URI)
public Response status(ExploratoryStatusDTO dto) {
if (UserInstanceStatus.CREATED != UserInstanceStatus.of(dto.getStatus())) {
- //TODO Handle error status?
log.error("Git creds has not been updated for exploratory environment {} for user {}, status is {}",
dto.getExploratoryName(), dto.getUser(), dto.getStatus());
} else {
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/LibraryCallback.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/LibraryCallback.java
index be8c2f1..6eaedf9 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/LibraryCallback.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/LibraryCallback.java
@@ -19,7 +19,6 @@
package com.epam.dlab.backendapi.resources.callback;
-import com.epam.dlab.auth.UserInfo;
import com.epam.dlab.backendapi.dao.ExploratoryLibDAO;
import com.epam.dlab.backendapi.domain.ExploratoryLibCache;
import com.epam.dlab.backendapi.domain.RequestId;
@@ -28,7 +27,6 @@
import com.epam.dlab.dto.exploratory.LibListStatusDTO;
import com.epam.dlab.exceptions.DlabException;
import com.google.inject.Inject;
-import io.dropwizard.auth.Auth;
import lombok.extern.slf4j.Slf4j;
import javax.ws.rs.Consumes;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/ProjectCallback.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/ProjectCallback.java
index 59c31da..4500e5e 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/ProjectCallback.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/ProjectCallback.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.resources.callback;
import com.epam.dlab.backendapi.dao.ProjectDAO;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/ReuploadKeyCallback.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/ReuploadKeyCallback.java
index 837498a..51324a4 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/ReuploadKeyCallback.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/callback/ReuploadKeyCallback.java
@@ -19,12 +19,10 @@
package com.epam.dlab.backendapi.resources.callback;
-import com.epam.dlab.auth.UserInfo;
import com.epam.dlab.backendapi.domain.RequestId;
import com.epam.dlab.backendapi.service.ReuploadKeyService;
import com.epam.dlab.dto.reuploadkey.ReuploadKeyStatusDTO;
import com.google.inject.Inject;
-import io.dropwizard.auth.Auth;
import lombok.extern.slf4j.Slf4j;
import javax.ws.rs.Consumes;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/KeysDTO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/KeysDTO.java
index 8093fc9..6f4e021 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/KeysDTO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/KeysDTO.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.resources.dto;
import lombok.AllArgsConstructor;
@@ -6,7 +25,7 @@
@AllArgsConstructor
@Data
public class KeysDTO {
- private String publicKey;
- private String privateKey;
- private String username;
+ private String publicKey;
+ private String privateKey;
+ private String username;
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/ProjectActionFormDTO.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/ProjectActionFormDTO.java
index 24d8342..ccdd3c4 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/ProjectActionFormDTO.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/resources/dto/ProjectActionFormDTO.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.resources.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/roles/UserRole.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/roles/UserRole.java
index e5343dd..bb16414 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/roles/UserRole.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/roles/UserRole.java
@@ -120,8 +120,12 @@
@Override
public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
UserRole userRole = (UserRole) o;
return this.id.equals(userRole.getId()) && this.type.equals(userRole.getType()) && this.name.equals(userRole.getName());
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/schedulers/billing/BillingScheduler.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/schedulers/billing/BillingScheduler.java
index 45563a2..ad3ffcc 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/schedulers/billing/BillingScheduler.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/schedulers/billing/BillingScheduler.java
@@ -46,7 +46,7 @@
try {
billingService.updateRemoteBillingData(securityService.getServiceAccountInfo("admin"));
} catch (Exception e) {
- log.error("Something went wrong {}", e.getMessage());
+ log.error("Something went wrong {}", e.getMessage(), e);
}
}
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/schedulers/endpoint/CheckEndpointStatusScheduler.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/schedulers/endpoint/CheckEndpointStatusScheduler.java
index 5707553..02d109d 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/schedulers/endpoint/CheckEndpointStatusScheduler.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/schedulers/endpoint/CheckEndpointStatusScheduler.java
@@ -50,7 +50,7 @@
try {
endpointService.checkUrl(serviceUser, endpoint.getUrl());
} catch (Exception e) {
- log.warn("Failed connecting to endpoint {}, url: '{}'. {}", endpoint.getName(), endpoint.getUrl(), e.getMessage());
+ log.warn("Failed connecting to endpoint {}, url: '{}'. {}", endpoint.getName(), endpoint.getUrl(), e.getMessage(), e);
return endpoint.getStatus() == EndpointDTO.EndpointStatus.ACTIVE;
}
return endpoint.getStatus() == EndpointDTO.EndpointStatus.INACTIVE;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/AccessKeyService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/AccessKeyService.java
index c037285..2c84226 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/AccessKeyService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/AccessKeyService.java
@@ -22,7 +22,7 @@
import com.epam.dlab.auth.UserInfo;
import com.epam.dlab.backendapi.resources.dto.KeysDTO;
+@FunctionalInterface
public interface AccessKeyService {
-
KeysDTO generateKeys(UserInfo userInfo);
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/EndpointService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/EndpointService.java
index 24fcddd..e30c46e 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/EndpointService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/EndpointService.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.service;
import com.epam.dlab.auth.UserInfo;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ExternalLibraryService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ExternalLibraryService.java
index 9298c5c..2ecd82a 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ExternalLibraryService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ExternalLibraryService.java
@@ -21,6 +21,7 @@
import com.epam.dlab.backendapi.resources.dto.LibraryDTO;
+@FunctionalInterface
public interface ExternalLibraryService {
LibraryDTO getLibrary(String groupId, String artifactId, String version);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/GuacamoleService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/GuacamoleService.java
index 06dc8b1..68df4b1 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/GuacamoleService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/GuacamoleService.java
@@ -1,8 +1,28 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.service;
import com.epam.dlab.auth.UserInfo;
import org.apache.guacamole.net.GuacamoleTunnel;
+@FunctionalInterface
public interface GuacamoleService {
GuacamoleTunnel getTunnel(UserInfo userInfo, String host, String endpoint);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/KeycloakService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/KeycloakService.java
index e55b0cc..b62de5f 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/KeycloakService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/KeycloakService.java
@@ -1,10 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.service;
import org.keycloak.representations.AccessTokenResponse;
public interface KeycloakService {
AccessTokenResponse getToken(String code);
+
AccessTokenResponse refreshToken(String refreshToken);
+
AccessTokenResponse generateAccessToken(String refreshToken);
+
AccessTokenResponse generateServiceAccountToken();
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/KeycloakServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/KeycloakServiceImpl.java
index b7c508a..871839d 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/KeycloakServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/KeycloakServiceImpl.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.service;
import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
@@ -20,6 +39,7 @@
public class KeycloakServiceImpl implements KeycloakService {
private static final String URI = "/realms/%s/protocol/openid-connect/token";
+ private static final String GRANT_TYPE = "grant_type";
private final Client httpClient;
private final KeycloakConfiguration conf;
private final SecurityDAO securityDAO;
@@ -61,8 +81,8 @@
String.valueOf(conf.getCredentials().get("secret"))));
final Response response =
httpClient.target(conf.getAuthServerUrl() + String.format(URI, conf.getRealm())).request()
- .header(HttpHeaders.AUTHORIZATION, "Basic " + credentials)
- .post(Entity.form(requestForm));
+ .header(HttpHeaders.AUTHORIZATION, "Basic " + credentials)
+ .post(Entity.form(requestForm));
if (response.getStatusInfo().getFamily() != Response.Status.Family.SUCCESSFUL) {
log.error("Error getting token:code {}, body {}", response.getStatus(), response.readEntity(String.class));
@@ -73,19 +93,19 @@
private Form accessTokenRequestForm(String code) {
return new Form()
- .param("grant_type", "authorization_code")
+ .param(GRANT_TYPE, "authorization_code")
.param("code", code)
.param("redirect_uri", redirectUri);
}
private Form refreshTokenRequestForm(String refreshToken) {
return new Form()
- .param("grant_type", "refresh_token")
+ .param(GRANT_TYPE, "refresh_token")
.param("refresh_token", refreshToken);
}
private Form serviceAccountRequestForm() {
return new Form()
- .param("grant_type", "client_credentials");
+ .param(GRANT_TYPE, "client_credentials");
}
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java
index e6745db..2656e48 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ProjectService.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.service;
import com.epam.dlab.auth.UserInfo;
@@ -18,25 +37,25 @@
void create(UserInfo userInfo, ProjectDTO projectDTO, String resourceName);
- ProjectDTO get(String name);
+ ProjectDTO get(String name);
- void terminateEndpoint(UserInfo userInfo, String endpoint, String name);
+ void terminateEndpoint(UserInfo userInfo, String endpoint, String name);
- void terminateEndpoint(UserInfo userInfo, List<String> endpoints, String name);
+ void terminateEndpoint(UserInfo userInfo, List<String> endpoints, String name);
- void start(UserInfo userInfo, String endpoint, String name);
+ void start(UserInfo userInfo, String endpoint, String name);
- void start(UserInfo userInfo, List<String> endpoints, String name);
+ void start(UserInfo userInfo, List<String> endpoints, String name);
- void stop(UserInfo userInfo, String endpoint, String name, String auditInfo);
+ void stop(UserInfo userInfo, String endpoint, String name, String auditInfo);
- void stopWithResources(UserInfo userInfo, List<String> endpoints, String projectName);
+ void stopWithResources(UserInfo userInfo, List<String> endpoints, String projectName);
- void update(UserInfo userInfo, UpdateProjectDTO projectDTO, String projectName);
+ void update(UserInfo userInfo, UpdateProjectDTO projectDTO, String projectName);
- void updateBudget(UserInfo userInfo, List<UpdateProjectBudgetDTO> projects);
+ void updateBudget(UserInfo userInfo, List<UpdateProjectBudgetDTO> projects);
- boolean isAnyProjectAssigned(UserInfo userInfo);
+ boolean isAnyProjectAssigned(UserInfo userInfo);
- boolean checkExploratoriesAndComputationalProgress(String projectName, List<String> endpoints);
+ boolean checkExploratoriesAndComputationalProgress(String projectName, List<String> endpoints);
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ReuploadKeyService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ReuploadKeyService.java
index 0c2b199..25d2cc0 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ReuploadKeyService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/ReuploadKeyService.java
@@ -19,10 +19,9 @@
package com.epam.dlab.backendapi.service;
-import com.epam.dlab.auth.UserInfo;
import com.epam.dlab.dto.reuploadkey.ReuploadKeyStatusDTO;
-import com.epam.dlab.model.ResourceData;
+@FunctionalInterface
public interface ReuploadKeyService {
void updateResourceData(ReuploadKeyStatusDTO dto);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SecurityService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SecurityService.java
index 6f78ad2..c30a670 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SecurityService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SecurityService.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.service;
import com.epam.dlab.auth.UserInfo;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SecurityServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SecurityServiceImpl.java
index b405db8..73dc677 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SecurityServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SecurityServiceImpl.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.service;
import com.epam.dlab.auth.UserInfo;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SystemInfoService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SystemInfoService.java
index b3802ce..6e6a576 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SystemInfoService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/SystemInfoService.java
@@ -20,6 +20,7 @@
import com.epam.dlab.backendapi.resources.dto.SystemInfoDto;
+@FunctionalInterface
public interface SystemInfoService {
SystemInfoDto getSystemInfo();
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/TagService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/TagService.java
index f436f6d..b5451ca 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/TagService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/TagService.java
@@ -1,9 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.service;
import com.epam.dlab.auth.UserInfo;
import java.util.Map;
+@FunctionalInterface
public interface TagService {
Map<String, String> getResourceTags(UserInfo userInfo, String endpoint, String project, String customTag);
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/TagServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/TagServiceImpl.java
index 5f1504c..3b281fd 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/TagServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/TagServiceImpl.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.service;
import com.epam.dlab.auth.UserInfo;
@@ -12,7 +31,7 @@
@Override
public Map<String, String> getResourceTags(UserInfo userInfo, String endpoint, String project,
- String customTag) {
+ String customTag) {
Map<String, String> tags = new HashMap<>();
tags.put("user_tag", userInfo.getName());
tags.put("endpoint_tag", endpoint);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/UserRoleServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/UserRoleServiceImpl.java
index 92e0afb..5f3f6a3 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/UserRoleServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/UserRoleServiceImpl.java
@@ -18,7 +18,7 @@
*/
package com.epam.dlab.backendapi.service;
-import com.epam.dlab.backendapi.dao.UserRoleDao;
+import com.epam.dlab.backendapi.dao.UserRoleDAO;
import com.epam.dlab.backendapi.resources.dto.UserRoleDto;
import com.epam.dlab.exceptions.ResourceNotFoundException;
import com.google.inject.Inject;
@@ -33,7 +33,7 @@
private static final String ROLE_NOT_FOUND_MSG = "Any of role : %s were not found";
@Inject
- private UserRoleDao userRoleDao;
+ private UserRoleDAO userRoleDao;
@Override
public List<UserRoleDto> getUserRoles() {
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BackupServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BackupServiceImpl.java
index b50b0ae..1a93470 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BackupServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BackupServiceImpl.java
@@ -20,7 +20,7 @@
package com.epam.dlab.backendapi.service.impl;
import com.epam.dlab.auth.UserInfo;
-import com.epam.dlab.backendapi.dao.BackupDao;
+import com.epam.dlab.backendapi.dao.BackupDAO;
import com.epam.dlab.backendapi.resources.dto.BackupInfoRecord;
import com.epam.dlab.backendapi.service.BackupService;
import com.epam.dlab.constants.ServiceConsts;
@@ -43,7 +43,7 @@
private RESTService provisioningService;
@Inject
- private BackupDao backupDao;
+ private BackupDAO backupDao;
@Override
public String createBackup(EnvBackupDTO dto, UserInfo user) {
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BillingServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BillingServiceImpl.java
index 2bcf644..2810a33 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BillingServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BillingServiceImpl.java
@@ -22,7 +22,7 @@
import com.epam.dlab.auth.UserInfo;
import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
import com.epam.dlab.backendapi.dao.BillingDAO;
-import com.epam.dlab.backendapi.dao.ImageExploratoryDao;
+import com.epam.dlab.backendapi.dao.ImageExploratoryDAO;
import com.epam.dlab.backendapi.dao.ProjectDAO;
import com.epam.dlab.backendapi.domain.BillingReport;
import com.epam.dlab.backendapi.domain.BillingReportLine;
@@ -83,14 +83,14 @@
private final ExploratoryService exploratoryService;
private final SelfServiceApplicationConfiguration configuration;
private final RESTService provisioningService;
- private final ImageExploratoryDao imageExploratoryDao;
+ private final ImageExploratoryDAO imageExploratoryDao;
private final BillingDAO billingDAO;
private final String sbn;
@Inject
public BillingServiceImpl(ProjectService projectService, ProjectDAO projectDAO, EndpointService endpointService,
ExploratoryService exploratoryService, SelfServiceApplicationConfiguration configuration,
- @Named(ServiceConsts.BILLING_SERVICE_NAME) RESTService provisioningService, ImageExploratoryDao imageExploratoryDao,
+ @Named(ServiceConsts.BILLING_SERVICE_NAME) RESTService provisioningService, ImageExploratoryDAO imageExploratoryDao,
BillingDAO billingDAO) {
this.projectService = projectService;
this.projectDAO = projectDAO;
@@ -116,12 +116,12 @@
final double sum = billingReportLines.stream().mapToDouble(BillingReportLine::getCost).sum();
final String currency = billingReportLines.stream().map(BillingReportLine::getCurrency).distinct().count() == 1 ? billingReportLines.get(0).getCurrency() : null;
return BillingReport.builder()
- .name("Billing report")
- .sbn(sbn)
- .reportLines(billingReportLines)
- .usageDateFrom(min)
- .usageDateTo(max)
- .totalCost(new BigDecimal(sum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue())
+ .name("Billing report")
+ .sbn(sbn)
+ .reportLines(billingReportLines)
+ .usageDateFrom(min)
+ .usageDateTo(max)
+ .totalCost(BigDecimal.valueOf(sum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue())
.currency(currency)
.isReportHeaderCompletable(hasUserBillingRole(user))
.build();
@@ -155,9 +155,9 @@
.collect(Collectors.toList());;
final String currency = billingData.stream().map(BillingReportLine::getCurrency).distinct().count() == 1 ? billingData.get(0).getCurrency() : null;
return BillingReport.builder()
- .name(exploratoryName)
- .reportLines(billingData)
- .totalCost(new BigDecimal(sum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue())
+ .name(exploratoryName)
+ .reportLines(billingData)
+ .totalCost(BigDecimal.valueOf(sum).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue())
.currency(currency)
.build();
}
@@ -297,16 +297,16 @@
billingDAO.save(billingReportLines);
}
- private List<BillingData> getBillingData(UserInfo userInfo, EndpointDTO e) {
- try {
- return provisioningService.get(getBillingUrl(e.getUrl(), BILLING_PATH), userInfo.getAccessToken(),
- new GenericType<List<BillingData>>() {
- });
- } catch (Exception ex) {
- log.error("Cannot retrieve billing information for {}. {}", e.getName(), ex.getMessage());
- return Collections.emptyList();
- }
- }
+ private List<BillingData> getBillingData(UserInfo userInfo, EndpointDTO endpointDTO) {
+ try {
+ return provisioningService.get(getBillingUrl(endpointDTO.getUrl(), BILLING_PATH), userInfo.getAccessToken(),
+ new GenericType<List<BillingData>>() {
+ });
+ } catch (Exception e) {
+ log.error("Cannot retrieve billing information for {} . Reason {}.", endpointDTO.getName(), e.getMessage(), e);
+ return Collections.emptyList();
+ }
+ }
private String getBillingUrl(String endpointUrl, String path) {
URI uri;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BucketServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BucketServiceImpl.java
index 0d27a86..8049857 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BucketServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/BucketServiceImpl.java
@@ -66,6 +66,7 @@
private static final String BUCKET_UPLOAD_FOLDER = "%sbucket/folder/upload";
private static final String BUCKET_DOWNLOAD_OBJECT = "%sbucket/%s/object/%s/download";
private static final String BUCKET_DELETE_OBJECT = "%sbucket/objects/delete";
+ private static final String SOMETHING_WENT_WRONG_MESSAGE = "Something went wrong. Response status is %s ";
private final EndpointService endpointService;
private final RESTService provisioningService;
@@ -83,7 +84,7 @@
return provisioningService.get(String.format(BUCKET_GET_OBJECTS, endpointDTO.getUrl(), bucket), userInfo.getAccessToken(), new GenericType<List<BucketDTO>>() {
});
} catch (Exception e) {
- log.error("Cannot get objects from bucket {} for user {}, endpoint {}. Reason {}", bucket, userInfo.getName(), endpoint, e.getMessage());
+ log.error("Cannot get objects from bucket {} for user {}, endpoint {}. Reason {}", bucket, userInfo.getName(), endpoint, e.getMessage(), e);
throw new DlabException(String.format("Cannot get objects from bucket %s for user %s, endpoint %s. Reason %s", bucket, userInfo.getName(), endpoint, e.getMessage()));
}
}
@@ -97,10 +98,10 @@
FormDataMultiPart formData = getFormDataMultiPart(bucket, object, inputStream, contentType, fileSize);
Response response = provisioningService.postForm(String.format(BUCKET_UPLOAD_OBJECT, endpointDTO.getUrl()), userInfo.getAccessToken(), formData, Response.class);
if (response.getStatus() != HttpStatus.SC_OK) {
- throw new DlabException(String.format("Something went wrong. Response status is %s ", response.getStatus()));
+ throw new DlabException(String.format(SOMETHING_WENT_WRONG_MESSAGE, response.getStatus()));
}
} catch (Exception e) {
- log.error("Cannot upload object {} to bucket {} for user {}, endpoint {}. Reason {}", object, bucket, userInfo.getName(), endpoint, e.getMessage());
+ log.error("Cannot upload object {} to bucket {} for user {}, endpoint {}. Reason {}", object, bucket, userInfo.getName(), endpoint, e.getMessage(), e);
throw new DlabException(String.format("Cannot upload object %s to bucket %s for user %s, endpoint %s. Reason %s", object, bucket, userInfo.getName(), endpoint, e.getMessage()));
}
log.info("Finished uploading file {} for user {} to bucket {}", object, userInfo.getName(), bucket);
@@ -118,10 +119,10 @@
FolderUploadDTO dto = new FolderUploadDTO(bucket, folder);
Response response = provisioningService.post(String.format(BUCKET_UPLOAD_FOLDER, endpointDTO.getUrl()), userInfo.getAccessToken(), dto, Response.class);
if (response.getStatus() != HttpStatus.SC_OK) {
- throw new DlabException(String.format("Something went wrong. Response status is %s ", response.getStatus()));
+ throw new DlabException(String.format(SOMETHING_WENT_WRONG_MESSAGE, response.getStatus()));
}
} catch (Exception e) {
- log.error("Cannot upload folder {} to bucket {} for user {}, endpoint {}. Reason {}", folder, bucket, userInfo.getName(), endpoint, e.getMessage());
+ log.error("Cannot upload folder {} to bucket {} for user {}, endpoint {}. Reason {}", folder, bucket, userInfo.getName(), endpoint, e.getMessage(), e);
throw new DlabException(String.format("Cannot upload object %s to bucket %s for user %s, endpoint %s. Reason %s", folder, bucket, userInfo.getName(), endpoint, e.getMessage()));
}
log.info("Finished uploading folder {} for user {} to bucket {}", folder, userInfo.getName(), bucket);
@@ -137,7 +138,7 @@
IOUtils.copyLarge(inputStream, outputStream);
log.info("Finished downloading file {} for user {} from bucket {}", object, userInfo.getName(), bucket);
} catch (Exception e) {
- log.error("Cannot upload object {} from bucket {} for user {}, endpoint {}. Reason {}", object, bucket, userInfo.getName(), endpoint, e.getMessage());
+ log.error("Cannot upload object {} from bucket {} for user {}, endpoint {}. Reason {}", object, bucket, userInfo.getName(), endpoint, e.getMessage(), e);
throw new DlabException(String.format("Cannot download object %s from bucket %s for user %s, endpoint %s. Reason %s", object, bucket, userInfo.getName(), endpoint, e.getMessage()));
}
}
@@ -150,10 +151,10 @@
BucketDeleteDTO bucketDeleteDTO = new BucketDeleteDTO(bucket, objects);
Response response = provisioningService.post(String.format(BUCKET_DELETE_OBJECT, endpointDTO.getUrl()), userInfo.getAccessToken(), bucketDeleteDTO, Response.class);
if (response.getStatus() != HttpStatus.SC_OK) {
- throw new DlabException(String.format("Something went wrong. Response status is %s ", response.getStatus()));
+ throw new DlabException(String.format(SOMETHING_WENT_WRONG_MESSAGE, response.getStatus()));
}
} catch (Exception e) {
- log.error("Cannot delete objects {} from bucket {} for user {}, endpoint {}. Reason {}", objects, bucket, userInfo.getName(), endpoint, e.getMessage());
+ log.error("Cannot delete objects {} from bucket {} for user {}, endpoint {}. Reason {}", objects, bucket, userInfo.getName(), endpoint, e.getMessage(), e);
throw new DlabException(String.format("Cannot delete objects %s from bucket %s for user %s, endpoint %s. Reason %s", objects, bucket, userInfo.getName(), endpoint, e.getMessage()));
}
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ComputationalServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ComputationalServiceImpl.java
index 1bfd0b7..0a87667 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ComputationalServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ComputationalServiceImpl.java
@@ -340,8 +340,7 @@
try {
return Optional.of(computationalDAO.fetchComputationalFields(user, project, exploratoryName, computationalName));
} catch (DlabException e) {
- log.warn("Computational resource {} affiliated with exploratory {} for user {} not found.",
- computationalName, exploratoryName, user);
+ log.warn("Computational resource {} affiliated with exploratory {} for user {} not found.", computationalName, exploratoryName, user, e);
}
return Optional.empty();
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/EndpointServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/EndpointServiceImpl.java
index e3ad62c..cbb7bd1 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/EndpointServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/EndpointServiceImpl.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.service.impl;
import com.epam.dlab.auth.UserInfo;
@@ -6,7 +25,7 @@
import com.epam.dlab.backendapi.annotation.User;
import com.epam.dlab.backendapi.dao.EndpointDAO;
import com.epam.dlab.backendapi.dao.ExploratoryDAO;
-import com.epam.dlab.backendapi.dao.UserRoleDao;
+import com.epam.dlab.backendapi.dao.UserRoleDAO;
import com.epam.dlab.backendapi.domain.EndpointDTO;
import com.epam.dlab.backendapi.domain.EndpointResourcesDTO;
import com.epam.dlab.backendapi.domain.ProjectDTO;
@@ -43,12 +62,12 @@
private final ProjectService projectService;
private final ExploratoryDAO exploratoryDAO;
private final RESTService provisioningService;
- private final UserRoleDao userRoleDao;
+ private final UserRoleDAO userRoleDao;
@Inject
public EndpointServiceImpl(EndpointDAO endpointDAO, ProjectService projectService, ExploratoryDAO exploratoryDAO,
- @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService,
- UserRoleDao userRoleDao) {
+ @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService,
+ UserRoleDAO userRoleDao) {
this.endpointDAO = endpointDAO;
this.projectService = projectService;
@@ -83,26 +102,26 @@
.orElseThrow(() -> new ResourceNotFoundException("Endpoint with name " + name + " not found"));
}
- /**
- * Create new endpoint object in the System.
- * The Endpoint objects should contain Unique values of the 'url' and 'name' fields,
- * i.e two objects with same URLs should not be created in the system.
- *
- * @param userInfo user properties
- * @param resourceName name of the endpoint
- * @param endpointDTO object with endpoint fields
- */
- @Audit(action = CONNECT, type = ENDPOINT)
- @Override
- public void create(@User UserInfo userInfo, @ResourceName String resourceName, EndpointDTO endpointDTO) {
- if (endpointDAO.get(endpointDTO.getName()).isPresent()) {
- throw new ResourceConflictException("The Endpoint with this name exists in system");
- }
- if (endpointDAO.getEndpointWithUrl(endpointDTO.getUrl()).isPresent()) {
- throw new ResourceConflictException("The Endpoint URL with this address exists in system");
- }
- CloudProvider cloudProvider = checkUrl(userInfo, endpointDTO.getUrl());
- if (Objects.isNull(cloudProvider)) {
+ /**
+ * Create new endpoint object in the System.
+ * The Endpoint objects should contain Unique values of the 'url' and 'name' fields,
+ * i.e two objects with same URLs should not be created in the system.
+ *
+ * @param userInfo user properties
+ * @param resourceName name of the endpoint
+ * @param endpointDTO object with endpoint fields
+ */
+ @Audit(action = CONNECT, type = ENDPOINT)
+ @Override
+ public void create(@User UserInfo userInfo, @ResourceName String resourceName, EndpointDTO endpointDTO) {
+ if (endpointDAO.get(endpointDTO.getName()).isPresent()) {
+ throw new ResourceConflictException("The Endpoint with this name exists in system");
+ }
+ if (endpointDAO.getEndpointWithUrl(endpointDTO.getUrl()).isPresent()) {
+ throw new ResourceConflictException("The Endpoint URL with this address exists in system");
+ }
+ CloudProvider cloudProvider = checkUrl(userInfo, endpointDTO.getUrl());
+ if (Objects.isNull(cloudProvider)) {
throw new DlabException("CloudProvider cannot be null");
}
endpointDAO.create(new EndpointDTO(endpointDTO.getName(), endpointDTO.getUrl(), endpointDTO.getAccount(),
@@ -113,26 +132,26 @@
@Override
public void updateEndpointStatus(String name, EndpointDTO.EndpointStatus status) {
endpointDAO.updateEndpointStatus(name, status.name());
- }
+ }
- @Override
- public void remove(UserInfo userInfo, String name) {
- EndpointDTO endpointDTO = endpointDAO.get(name).orElseThrow(() -> new ResourceNotFoundException(String.format("Endpoint %s does not exist", name)));
- List<ProjectDTO> projects = projectService.getProjectsByEndpoint(name);
- checkProjectEndpointResourcesStatuses(projects, name);
- CloudProvider cloudProvider = endpointDTO.getCloudProvider();
- removeEndpoint(userInfo, name, cloudProvider, projects);
- }
+ @Override
+ public void remove(UserInfo userInfo, String name) {
+ EndpointDTO endpointDTO = endpointDAO.get(name).orElseThrow(() -> new ResourceNotFoundException(String.format("Endpoint %s does not exist", name)));
+ List<ProjectDTO> projects = projectService.getProjectsByEndpoint(name);
+ checkProjectEndpointResourcesStatuses(projects, name);
+ CloudProvider cloudProvider = endpointDTO.getCloudProvider();
+ removeEndpoint(userInfo, name, cloudProvider, projects);
+ }
@Audit(action = DISCONNECT, type = ENDPOINT)
- public void removeEndpoint(@User UserInfo userInfo, @ResourceName String name, CloudProvider cloudProvider, List<ProjectDTO> projects) {
- removeEndpointInAllProjects(userInfo, name, projects);
- endpointDAO.remove(name);
- List<CloudProvider> remainingProviders = endpointDAO.getEndpoints()
- .stream()
- .map(EndpointDTO::getCloudProvider)
- .collect(Collectors.toList());
- userRoleDao.removeUnnecessaryRoles(cloudProvider, remainingProviders);
+ public void removeEndpoint(@User UserInfo userInfo, @ResourceName String name, CloudProvider cloudProvider, List<ProjectDTO> projects) {
+ removeEndpointInAllProjects(userInfo, name, projects);
+ endpointDAO.remove(name);
+ List<CloudProvider> remainingProviders = endpointDAO.getEndpoints()
+ .stream()
+ .map(EndpointDTO::getCloudProvider)
+ .collect(Collectors.toList());
+ userRoleDao.removeUnnecessaryRoles(cloudProvider, remainingProviders);
}
@Override
@@ -148,9 +167,9 @@
response = provisioningService.get(url + HEALTH_CHECK, userInfo.getAccessToken(), Response.class);
cloudProvider = response.readEntity(CloudProvider.class);
} catch (Exception e) {
- log.error("Cannot connect to url '{}'. {}", url, e.getMessage());
- throw new DlabException(String.format("Cannot connect to url '%s'.", url));
- }
+ log.error("Cannot connect to url '{}'. {}", url, e.getMessage(), e);
+ throw new DlabException(String.format("Cannot connect to url '%s'.", url));
+ }
if (response.getStatus() != 200) {
log.warn("Endpoint url {} is not valid", url);
throw new ResourceNotFoundException(String.format("Endpoint url '%s' is not valid", url));
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ExploratoryServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ExploratoryServiceImpl.java
index e89eda3..cdafb03 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ExploratoryServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ExploratoryServiceImpl.java
@@ -30,7 +30,7 @@
import com.epam.dlab.backendapi.dao.ComputationalDAO;
import com.epam.dlab.backendapi.dao.ExploratoryDAO;
import com.epam.dlab.backendapi.dao.GitCredsDAO;
-import com.epam.dlab.backendapi.dao.ImageExploratoryDao;
+import com.epam.dlab.backendapi.dao.ImageExploratoryDAO;
import com.epam.dlab.backendapi.domain.AuditActionEnum;
import com.epam.dlab.backendapi.domain.AuditDTO;
import com.epam.dlab.backendapi.domain.AuditResourceTypeEnum;
@@ -101,7 +101,7 @@
private final ExploratoryDAO exploratoryDAO;
private final ComputationalDAO computationalDAO;
private final GitCredsDAO gitCredsDAO;
- private final ImageExploratoryDao imageExploratoryDao;
+ private final ImageExploratoryDAO imageExploratoryDao;
private final RESTService provisioningService;
private final RequestBuilder requestBuilder;
private final RequestId requestId;
@@ -112,9 +112,9 @@
@Inject
public ExploratoryServiceImpl(ProjectService projectService, ExploratoryDAO exploratoryDAO, ComputationalDAO computationalDAO, GitCredsDAO gitCredsDAO,
- ImageExploratoryDao imageExploratoryDao, @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService,
- RequestBuilder requestBuilder, RequestId requestId, TagService tagService, EndpointService endpointService, AuditService auditService,
- SelfServiceApplicationConfiguration configuration) {
+ ImageExploratoryDAO imageExploratoryDao, @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService,
+ RequestBuilder requestBuilder, RequestId requestId, TagService tagService, EndpointService endpointService, AuditService auditService,
+ SelfServiceApplicationConfiguration configuration) {
this.projectService = projectService;
this.exploratoryDAO = exploratoryDAO;
this.computationalDAO = computationalDAO;
@@ -229,7 +229,7 @@
try {
return Optional.of(exploratoryDAO.fetchExploratoryFields(user, project, exploratoryName));
} catch (DlabException e) {
- log.warn("User instance with exploratory {}, project {} for user {} not found.", exploratoryName, project, user);
+ log.warn("User instance with exploratory {}, project {} for user {} not found.", exploratoryName, project, user, e);
}
return Optional.empty();
}
@@ -239,7 +239,7 @@
try {
return Optional.of(exploratoryDAO.fetchExploratoryFields(user, project, exploratoryName, includeCompResources));
} catch (DlabException e) {
- log.warn("User instance with exploratory {}, project {} for user {} not found.", exploratoryName, project, user);
+ log.warn("User instance with exploratory {}, project {} for user {} not found.", exploratoryName, project, user, e);
}
return Optional.empty();
}
@@ -460,7 +460,8 @@
private LibInstallDTO toLibInstallDto(Library l) {
return new LibInstallDTO(l.getGroup(), l.getName(), l.getVersion())
- .withStatus(l.getStatus().toString())
+ .withStatus(String.valueOf(l.getStatus()))
+ .withAddedPackages(l.getAddedPackages())
.withErrorMessage(l.getErrorMessage());
}
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/GuacamoleServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/GuacamoleServiceImpl.java
index 2394595..e94bf91 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/GuacamoleServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/GuacamoleServiceImpl.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.service.impl;
import com.epam.dlab.auth.UserInfo;
@@ -35,8 +54,8 @@
@Inject
public GuacamoleServiceImpl(SelfServiceApplicationConfiguration conf,
- @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService,
- EndpointService endpointService) {
+ @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService,
+ EndpointService endpointService) {
this.conf = conf;
this.provisioningService = provisioningService;
this.endpointService = endpointService;
@@ -61,7 +80,7 @@
}
private GuacamoleConfiguration getGuacamoleConfig(String privateKeyContent, Map<String, String> guacamoleParams,
- String host) {
+ String host) {
GuacamoleConfiguration guacamoleConfiguration = new GuacamoleConfiguration();
guacamoleConfiguration.setProtocol(guacamoleParams.get(CONNECTION_PROTOCOL_PARAM));
guacamoleConfiguration.setParameters(guacamoleParams);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ImageExploratoryServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ImageExploratoryServiceImpl.java
index 10e5126..4aae5b1 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ImageExploratoryServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ImageExploratoryServiceImpl.java
@@ -27,7 +27,7 @@
import com.epam.dlab.backendapi.annotation.User;
import com.epam.dlab.backendapi.dao.ExploratoryDAO;
import com.epam.dlab.backendapi.dao.ExploratoryLibDAO;
-import com.epam.dlab.backendapi.dao.ImageExploratoryDao;
+import com.epam.dlab.backendapi.dao.ImageExploratoryDAO;
import com.epam.dlab.backendapi.domain.EndpointDTO;
import com.epam.dlab.backendapi.domain.ProjectDTO;
import com.epam.dlab.backendapi.resources.dto.ImageInfoRecord;
@@ -64,24 +64,24 @@
@Singleton
@Slf4j
public class ImageExploratoryServiceImpl implements ImageExploratoryService {
- private static final String IMAGE_EXISTS_MSG = "Image with name %s is already exist in project %s";
- private static final String IMAGE_NOT_FOUND_MSG = "Image with name %s was not found for user %s";
+ private static final String IMAGE_EXISTS_MSG = "Image with name %s is already exist in project %s";
+ private static final String IMAGE_NOT_FOUND_MSG = "Image with name %s was not found for user %s";
- @Inject
- private ExploratoryDAO exploratoryDAO;
- @Inject
- private ImageExploratoryDao imageExploratoryDao;
- @Inject
- private ExploratoryLibDAO libDAO;
- @Inject
- @Named(ServiceConsts.PROVISIONING_SERVICE_NAME)
- private RESTService provisioningService;
- @Inject
- private RequestBuilder requestBuilder;
- @Inject
- private EndpointService endpointService;
- @Inject
- private ProjectService projectService;
+ @Inject
+ private ExploratoryDAO exploratoryDAO;
+ @Inject
+ private ImageExploratoryDAO imageExploratoryDao;
+ @Inject
+ private ExploratoryLibDAO libDAO;
+ @Inject
+ @Named(ServiceConsts.PROVISIONING_SERVICE_NAME)
+ private RESTService provisioningService;
+ @Inject
+ private RequestBuilder requestBuilder;
+ @Inject
+ private EndpointService endpointService;
+ @Inject
+ private ProjectService projectService;
@Audit(action = CREATE, type = IMAGE)
@Override
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/InfrastructureTemplateServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/InfrastructureTemplateServiceImpl.java
index 9f3f05f..03f093b 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/InfrastructureTemplateServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/InfrastructureTemplateServiceImpl.java
@@ -23,7 +23,7 @@
import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
import com.epam.dlab.backendapi.dao.ProjectDAO;
import com.epam.dlab.backendapi.dao.SettingsDAO;
-import com.epam.dlab.backendapi.dao.UserGroupDao;
+import com.epam.dlab.backendapi.dao.UserGroupDAO;
import com.epam.dlab.backendapi.domain.EndpointDTO;
import com.epam.dlab.backendapi.resources.dto.SparkStandaloneConfiguration;
import com.epam.dlab.backendapi.resources.dto.aws.AwsEmrConfiguration;
@@ -52,6 +52,7 @@
import java.util.Set;
import java.util.stream.Collectors;
+import static com.epam.dlab.cloud.CloudProvider.AZURE;
import static com.epam.dlab.rest.contracts.DockerAPI.DOCKER_COMPUTATIONAL;
import static com.epam.dlab.rest.contracts.DockerAPI.DOCKER_EXPLORATORY;
@@ -67,7 +68,7 @@
@Inject
private EndpointService endpointService;
@Inject
- private UserGroupDao userGroupDao;
+ private UserGroupDAO userGroupDao;
@Inject
@@ -144,7 +145,7 @@
* Temporary filter for creation of exploratory env due to Azure issues
*/
private boolean exploratoryGpuIssuesAzureFilter(ExploratoryMetadataDTO e, CloudProvider cloudProvider) {
- return (!"redhat".equals(settingsDAO.getConfOsFamily()) || cloudProvider != CloudProvider.AZURE) ||
+ return (!"redhat".equals(settingsDAO.getConfOsFamily()) || cloudProvider != AZURE) ||
!(e.getImage().endsWith("deeplearning") || e.getImage().endsWith("tensor"));
}
@@ -203,7 +204,8 @@
.minDataprocPreemptibleInstanceCount(configuration.getMinDataprocPreemptibleCount())
.build());
case AZURE:
- log.error("Dataengine service is not supported currently for {}", cloudProvider);
+ log.error("Dataengine service is not supported currently for {}", AZURE);
+ throw new UnsupportedOperationException("Dataengine service is not supported currently for " + AZURE);
default:
throw new UnsupportedOperationException("Dataengine service is not supported currently for " + cloudProvider);
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/MavenCentralLibraryService.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/MavenCentralLibraryService.java
index b7cbce8..13d0c86 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/MavenCentralLibraryService.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/MavenCentralLibraryService.java
@@ -32,7 +32,6 @@
import javax.inject.Inject;
import java.net.URI;
-import static java.lang.String.format;
import static java.lang.String.join;
@Singleton
@@ -41,7 +40,7 @@
private static final String QUOTE_ENCODED = "%22";
private static final String SEARCH_API_QUERY_FORMAT = "/solrsearch/select?q=%s&rows=20&wt=json&core=gav&p=jar";
- private static final String LIB_NOT_FOUND_MSG = "Artifact with id=%s, groupId=%s and version %s not found";
+ private static final String LIB_NOT_FOUND_MSG = "No matches found";
private final RESTService restClient;
@Inject
@@ -63,8 +62,7 @@
.stream()
.findFirst()
.map(artifact -> new LibraryDTO(join(":", groupId, artifactId), version))
- .orElseThrow(() -> new ResourceNotFoundException(format(LIB_NOT_FOUND_MSG, artifactId, groupId,
- version)));
+ .orElseThrow(() -> new ResourceNotFoundException(LIB_NOT_FOUND_MSG));
}
private String groupQuery(String groupId) {
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java
index a6a51bf..7ee90ba 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/ProjectServiceImpl.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.service.impl;
import com.epam.dlab.auth.UserInfo;
@@ -11,7 +30,7 @@
import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
import com.epam.dlab.backendapi.dao.ExploratoryDAO;
import com.epam.dlab.backendapi.dao.ProjectDAO;
-import com.epam.dlab.backendapi.dao.UserGroupDao;
+import com.epam.dlab.backendapi.dao.UserGroupDAO;
import com.epam.dlab.backendapi.domain.BudgetDTO;
import com.epam.dlab.backendapi.domain.EndpointDTO;
import com.epam.dlab.backendapi.domain.ProjectDTO;
@@ -36,7 +55,6 @@
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
-import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.function.Supplier;
@@ -70,7 +88,7 @@
private final ProjectDAO projectDAO;
private final ExploratoryService exploratoryService;
- private final UserGroupDao userGroupDao;
+ private final UserGroupDAO userGroupDao;
private final RESTService provisioningService;
private final RequestId requestId;
private final RequestBuilder requestBuilder;
@@ -81,10 +99,10 @@
@Inject
public ProjectServiceImpl(ProjectDAO projectDAO, ExploratoryService exploratoryService,
- UserGroupDao userGroupDao,
- @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService,
- RequestId requestId, RequestBuilder requestBuilder, EndpointService endpointService,
- ExploratoryDAO exploratoryDAO, SelfServiceApplicationConfiguration configuration) {
+ UserGroupDAO userGroupDao,
+ @Named(ServiceConsts.PROVISIONING_SERVICE_NAME) RESTService provisioningService,
+ RequestId requestId, RequestBuilder requestBuilder, EndpointService endpointService,
+ ExploratoryDAO exploratoryDAO, SelfServiceApplicationConfiguration configuration) {
this.projectDAO = projectDAO;
this.exploratoryService = exploratoryService;
this.userGroupDao = userGroupDao;
@@ -136,13 +154,13 @@
.orElseThrow(projectNotFound());
}
- @Audit(action = TERMINATE, type = EDGE_NODE)
- @Override
- public void terminateEndpoint(@User UserInfo userInfo, @ResourceName String endpoint, @Project String name) {
- projectActionOnCloud(userInfo, name, TERMINATE_PRJ_API, endpoint);
- projectDAO.updateEdgeStatus(name, endpoint, UserInstanceStatus.TERMINATING);
- exploratoryService.updateProjectExploratoryStatuses(userInfo, name, endpoint, UserInstanceStatus.TERMINATING);
- }
+ @Audit(action = TERMINATE, type = EDGE_NODE)
+ @Override
+ public void terminateEndpoint(@User UserInfo userInfo, @ResourceName String endpoint, @Project String name) {
+ projectActionOnCloud(userInfo, name, TERMINATE_PRJ_API, endpoint);
+ projectDAO.updateEdgeStatus(name, endpoint, UserInstanceStatus.TERMINATING);
+ exploratoryService.updateProjectExploratoryStatuses(userInfo, name, endpoint, UserInstanceStatus.TERMINATING);
+ }
@ProjectAdmin
@Override
@@ -179,15 +197,15 @@
List<ProjectEndpointDTO> endpointDTOs = getProjectEndpointDTOS(endpoints, projectName);
checkProjectRelatedResourcesInProgress(projectName, endpointDTOs, STOP_ACTION);
- endpointDTOs
- .stream()
- .filter(e -> !Arrays.asList(UserInstanceStatus.TERMINATED, UserInstanceStatus.TERMINATING, UserInstanceStatus.STOPPED,
- UserInstanceStatus.FAILED).contains(e.getStatus()))
- .forEach(e -> stop(userInfo, e.getName(), projectName, null));
+ endpointDTOs
+ .stream()
+ .filter(e -> !Arrays.asList(UserInstanceStatus.TERMINATED, UserInstanceStatus.TERMINATING, UserInstanceStatus.STOPPED,
+ UserInstanceStatus.FAILED).contains(e.getStatus()))
+ .forEach(e -> stop(userInfo, e.getName(), projectName, null));
- exploratoryDAO.fetchRunningExploratoryFieldsForProject(projectName,
- endpointDTOs
- .stream()
+ exploratoryDAO.fetchRunningExploratoryFieldsForProject(projectName,
+ endpointDTOs
+ .stream()
.map(ProjectEndpointDTO::getName)
.collect(Collectors.toList()))
.forEach(e -> exploratoryService.stop(userInfo, e.getUser(), projectName, e.getExploratoryName(), null));
@@ -196,39 +214,39 @@
@ProjectAdmin
@Override
public void update(@User UserInfo userInfo, UpdateProjectDTO projectDTO, @Project String projectName) {
- final ProjectDTO project = projectDAO.get(projectDTO.getName()).orElseThrow(projectNotFound());
- final Set<String> endpoints = project.getEndpoints()
- .stream()
- .map(ProjectEndpointDTO::getName)
- .collect(toSet());
- final Set<String> newEndpoints = new HashSet<>(projectDTO.getEndpoints());
- newEndpoints.removeAll(endpoints);
- final String projectUpdateAudit = updateProjectAudit(projectDTO, project, newEndpoints);
- updateProject(userInfo, projectName, projectDTO, project, newEndpoints, projectUpdateAudit);
- }
+ final ProjectDTO project = projectDAO.get(projectDTO.getName()).orElseThrow(projectNotFound());
+ final Set<String> endpoints = project.getEndpoints()
+ .stream()
+ .map(ProjectEndpointDTO::getName)
+ .collect(toSet());
+ final Set<String> newEndpoints = new HashSet<>(projectDTO.getEndpoints());
+ newEndpoints.removeAll(endpoints);
+ final String projectUpdateAudit = updateProjectAudit(projectDTO, project, newEndpoints);
+ updateProject(userInfo, projectName, projectDTO, project, newEndpoints, projectUpdateAudit);
+ }
- @Audit(action = UPDATE, type = PROJECT)
- public void updateProject(@User UserInfo userInfo, @Project @ResourceName String projectName, UpdateProjectDTO projectDTO, ProjectDTO project, Set<String> newEndpoints,
- @Info String projectAudit) {
- final List<ProjectEndpointDTO> endpointsToBeCreated = newEndpoints
- .stream()
- .map(e -> new ProjectEndpointDTO(e, UserInstanceStatus.CREATING, null))
- .collect(Collectors.toList());
- project.getEndpoints().addAll(endpointsToBeCreated);
- projectDAO.update(new ProjectDTO(project.getName(), projectDTO.getGroups(), project.getKey(),
- project.getTag(), project.getBudget(), project.getEndpoints(), projectDTO.isSharedImageEnabled()));
- endpointsToBeCreated.forEach(e -> createEndpoint(userInfo, projectName, project, e.getName(), String.format(AUDIT_ADD_EDGE_NODE, e.getName(), project.getName())));
- }
+ @Audit(action = UPDATE, type = PROJECT)
+ public void updateProject(@User UserInfo userInfo, @Project @ResourceName String projectName, UpdateProjectDTO projectDTO, ProjectDTO project, Set<String> newEndpoints,
+ @Info String projectAudit) {
+ final List<ProjectEndpointDTO> endpointsToBeCreated = newEndpoints
+ .stream()
+ .map(e -> new ProjectEndpointDTO(e, UserInstanceStatus.CREATING, null))
+ .collect(Collectors.toList());
+ project.getEndpoints().addAll(endpointsToBeCreated);
+ projectDAO.update(new ProjectDTO(project.getName(), projectDTO.getGroups(), project.getKey(),
+ project.getTag(), project.getBudget(), project.getEndpoints(), projectDTO.isSharedImageEnabled()));
+ endpointsToBeCreated.forEach(e -> createEndpoint(userInfo, projectName, project, e.getName(), String.format(AUDIT_ADD_EDGE_NODE, e.getName(), project.getName())));
+ }
- @Override
- public void updateBudget(UserInfo userInfo, List<UpdateProjectBudgetDTO> dtos) {
- final List<ProjectDTO> projects = dtos
- .stream()
- .map(this::getUpdateProjectDTO)
- .collect(Collectors.toList());
+ @Override
+ public void updateBudget(UserInfo userInfo, List<UpdateProjectBudgetDTO> dtos) {
+ final List<ProjectDTO> projects = dtos
+ .stream()
+ .map(this::getUpdateProjectDTO)
+ .collect(Collectors.toList());
- projects.forEach(p -> updateBudget(userInfo, p.getName(), p.getBudget(), getUpdateBudgetAudit(p)));
- }
+ projects.forEach(p -> updateBudget(userInfo, p.getName(), p.getBudget(), getUpdateBudgetAudit(p)));
+ }
@Audit(action = UPDATE, type = PROJECT)
public void updateBudget(@User UserInfo userInfo, @Project @ResourceName String name, BudgetDTO budget, @Info String updateBudgetAudit) {
@@ -258,7 +276,7 @@
try {
project.getEndpoints().forEach(e -> createEndpoint(user, project.getName(), project, e.getName(), String.format(AUDIT_ADD_EDGE_NODE, e.getName(), project.getName())));
} catch (Exception e) {
- log.error("Can not create project due to: {}", e.getMessage());
+ log.error("Can not create project due to: {}", e.getMessage(), e);
projectDAO.updateStatus(project.getName(), ProjectDTO.Status.FAILED);
}
}
@@ -278,17 +296,17 @@
requestBuilder.newProjectAction(user, projectName, endpointDTO), String.class);
requestId.put(user.getName(), uuid);
} catch (Exception e) {
- log.error("Can not terminate project due to: {}", e.getMessage());
+ log.error("Can not terminate project due to: {}", e.getMessage(), e);
projectDAO.updateStatus(projectName, ProjectDTO.Status.FAILED);
}
}
private void checkProjectRelatedResourcesInProgress(String projectName, List<ProjectEndpointDTO> endpoints, String action) {
- boolean edgeProgress = endpoints
+ boolean edgeProgress = endpoints
.stream()
.anyMatch(e ->
- Arrays.asList(UserInstanceStatus.CREATING, UserInstanceStatus.STARTING, UserInstanceStatus.STOPPING,
- UserInstanceStatus.TERMINATING).contains(e.getStatus()));
+ Arrays.asList(UserInstanceStatus.CREATING, UserInstanceStatus.STARTING, UserInstanceStatus.STOPPING,
+ UserInstanceStatus.TERMINATING).contains(e.getStatus()));
List<String> endpointNames = endpoints
.stream()
@@ -323,6 +341,9 @@
}
private String getUpdateBudgetAudit(ProjectDTO p) {
+ if (!configuration.isAuditEnabled()) {
+ return null;
+ }
Integer value = Optional.ofNullable(get(p.getName()).getBudget())
.map(BudgetDTO::getValue)
.orElse(null);
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/UserGroupServiceImpl.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/UserGroupServiceImpl.java
index 5b5b7e5..0475492 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/UserGroupServiceImpl.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/service/impl/UserGroupServiceImpl.java
@@ -24,8 +24,8 @@
import com.epam.dlab.backendapi.annotation.User;
import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
import com.epam.dlab.backendapi.dao.ProjectDAO;
-import com.epam.dlab.backendapi.dao.UserGroupDao;
-import com.epam.dlab.backendapi.dao.UserRoleDao;
+import com.epam.dlab.backendapi.dao.UserGroupDAO;
+import com.epam.dlab.backendapi.dao.UserRoleDAO;
import com.epam.dlab.backendapi.domain.AuditDTO;
import com.epam.dlab.backendapi.domain.ProjectDTO;
import com.epam.dlab.backendapi.resources.dto.UserGroupDto;
@@ -65,17 +65,18 @@
private static final String ROLE_NOT_FOUND_MSG = "Any of role : %s were not found";
private static final String ADMIN = "admin";
private static final String PROJECT_ADMIN = "projectAdmin";
+ private static final String INAPPROPRIATE_PERMISSION = "User %s doesn't have appropriate permission";
- private final UserGroupDao userGroupDao;
- private final UserRoleDao userRoleDao;
+ private final UserGroupDAO userGroupDao;
+ private final UserRoleDAO userRoleDao;
private final ProjectDAO projectDAO;
private final ProjectService projectService;
private final AuditService auditService;
private final SelfServiceApplicationConfiguration configuration;
@Inject
- public UserGroupServiceImpl(UserGroupDao userGroupDao, UserRoleDao userRoleDao, ProjectDAO projectDAO, ProjectService projectService, AuditService auditService,
- SelfServiceApplicationConfiguration configuration) {
+ public UserGroupServiceImpl(UserGroupDAO userGroupDao, UserRoleDAO userRoleDao, ProjectDAO projectDAO, ProjectService projectService, AuditService auditService,
+ SelfServiceApplicationConfiguration configuration) {
this.userGroupDao = userGroupDao;
this.userRoleDao = userRoleDao;
this.projectDAO = projectDAO;
@@ -103,10 +104,10 @@
.flatMap(Collection::stream)
.filter(g -> g.equalsIgnoreCase(group))
.findAny()
- .orElseThrow(() -> new DlabException(String.format("User %s doesn't have appropriate permission", userInfo.getName())));
+ .orElseThrow(() -> new DlabException(String.format(INAPPROPRIATE_PERMISSION, userInfo.getName())));
updateGroup(userInfo.getName(), group, roles, users);
} else {
- throw new DlabException(String.format("User %s doesn't have appropriate permission", userInfo.getName()));
+ throw new DlabException(String.format(INAPPROPRIATE_PERMISSION, userInfo.getName()));
}
}
@@ -140,7 +141,7 @@
.filter(userGroup -> groups.contains(userGroup.getGroup()) && !containsAdministrationPermissions(userGroup))
.collect(Collectors.toList());
} else {
- throw new DlabException(String.format("User %s doesn't have appropriate permission", user.getName()));
+ throw new DlabException(String.format(INAPPROPRIATE_PERMISSION, user.getName()));
}
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/servlet/guacamole/GuacamoleServlet.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/servlet/guacamole/GuacamoleServlet.java
index d74c68d..aa7995f 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/servlet/guacamole/GuacamoleServlet.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/servlet/guacamole/GuacamoleServlet.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.servlet.guacamole;
import com.epam.dlab.auth.UserInfo;
@@ -8,6 +27,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.inject.Inject;
import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.guacamole.net.GuacamoleTunnel;
import org.apache.guacamole.servlet.GuacamoleHTTPTunnelServlet;
@@ -19,6 +39,7 @@
import javax.ws.rs.core.HttpHeaders;
import java.io.IOException;
+@Slf4j
public class GuacamoleServlet extends GuacamoleHTTPTunnelServlet {
private static final String UNAUTHORIZED_MSG = "User is not authenticated";
private static final String DLAB_PREFIX = "DLab-";
@@ -39,12 +60,11 @@
try {
final String authorization = request.getHeader(DLAB_PREFIX + HttpHeaders.AUTHORIZATION);
final String credentials = StringUtils.substringAfter(authorization, AUTH_HEADER_PREFIX);
- final UserInfo userInfo =
- securityDAO.getUser(credentials)
- .orElseThrow(() -> new DlabAuthenticationException(UNAUTHORIZED_MSG));
+ final UserInfo userInfo = getUserInfo(credentials);
final CreateTerminalDTO createTerminalDTO = mapper.readValue(request.getReader(), CreateTerminalDTO.class);
return guacamoleService.getTunnel(userInfo, createTerminalDTO.getHost(), createTerminalDTO.getEndpoint());
} catch (IOException e) {
+ log.error("Cannot read request body. Reason {}", e.getMessage(), e);
throw new DlabException("Can not read request body: " + e.getMessage(), e);
}
}
@@ -54,10 +74,21 @@
try {
super.handleTunnelRequest(request, response);
} catch (DlabAuthenticationException e) {
+ log.error(UNAUTHORIZED_MSG, e);
sendError(response, HttpStatus.SC_UNAUTHORIZED, HttpStatus.SC_UNAUTHORIZED, UNAUTHORIZED_MSG);
}
}
+ private UserInfo getUserInfo(String credentials) {
+ try {
+ return securityDAO.getUser(credentials)
+ .orElseThrow(() -> new DlabAuthenticationException(UNAUTHORIZED_MSG));
+ } catch (DlabAuthenticationException e) {
+ log.error(UNAUTHORIZED_MSG, e);
+ throw new DlabException(UNAUTHORIZED_MSG);
+ }
+ }
+
@Data
private static class CreateTerminalDTO {
private String host;
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/util/CSVFormatter.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/util/CSVFormatter.java
index 7f0bbf7..a42a76d 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/util/CSVFormatter.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/util/CSVFormatter.java
@@ -22,21 +22,21 @@
import java.util.List;
public class CSVFormatter {
+ public static final char SEPARATOR = ',';
- private CSVFormatter() {
- }
+ private CSVFormatter() {
+ }
- public static final char SEPARATOR = ',';
- public static String formatLine(List<String> values, char separator) {
- boolean first = true;
- StringBuilder builder = new StringBuilder();
- for (String value : values) {
- if (!first) {
- builder.append(separator);
- }
- builder.append(followCsvStandard(value));
- first = false;
+ public static String formatLine(List<String> values, char separator) {
+ boolean first = true;
+ StringBuilder builder = new StringBuilder();
+ for (String value : values) {
+ if (!first) {
+ builder.append(separator);
+ }
+ builder.append(followCsvStandard(value));
+ first = false;
}
return builder.append(System.lineSeparator()).toString();
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/util/KeycloakUtil.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/util/KeycloakUtil.java
index 63fc62c..94e1957 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/util/KeycloakUtil.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/util/KeycloakUtil.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.util;
import com.epam.dlab.exceptions.DlabException;
@@ -7,16 +26,16 @@
public class KeycloakUtil {
- public static IDToken parseToken(String encoded) {
- try {
- String[] parts = encoded.split("\\.");
- if (parts.length < 2 || parts.length > 3) {
- throw new IllegalArgumentException("Parsing error");
- }
- byte[] bytes = Base64Url.decode(parts[1]);
- return JsonSerialization.readValue(bytes, IDToken.class);
- } catch (Exception e) {
- throw new DlabException("Can not parse token due to: " + e.getMessage());
- }
- }
+ public static IDToken parseToken(String encoded) {
+ try {
+ String[] parts = encoded.split("\\.");
+ if (parts.length < 2 || parts.length > 3) {
+ throw new IllegalArgumentException("Parsing error");
+ }
+ byte[] bytes = Base64Url.decode(parts[1]);
+ return JsonSerialization.readValue(bytes, IDToken.class);
+ } catch (Exception e) {
+ throw new DlabException("Can not parse token due to: " + e.getMessage(), e);
+ }
+ }
}
diff --git a/services/self-service/src/main/java/com/epam/dlab/backendapi/validation/annotation/LibNameValid.java b/services/self-service/src/main/java/com/epam/dlab/backendapi/validation/annotation/LibNameValid.java
index 1e8be9b..fb10ed2 100644
--- a/services/self-service/src/main/java/com/epam/dlab/backendapi/validation/annotation/LibNameValid.java
+++ b/services/self-service/src/main/java/com/epam/dlab/backendapi/validation/annotation/LibNameValid.java
@@ -34,8 +34,7 @@
public @interface LibNameValid {
- String message() default "Wrong library name format. Should be <groupId>:<artifactId>:<versionId>. E.g. io" +
- ".dropwizard:dropwizard-core:1.3.5";
+ String message() default "Wrong library name format. Should be <groupId>:<artifactId>:<versionId>";
Class<?>[] groups() default {};
diff --git a/services/self-service/src/main/resources/webapp/browserslist b/services/self-service/src/main/resources/webapp/browserslist
index 8084853..6382d82 100644
--- a/services/self-service/src/main/resources/webapp/browserslist
+++ b/services/self-service/src/main/resources/webapp/browserslist
@@ -1,3 +1,24 @@
+# *****************************************************************************
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+# ******************************************************************************
+
# This file is used by the build system to adjust CSS and JS output to support the specified browsers below.
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
@@ -9,4 +30,4 @@
last 2 versions
Firefox ESR
not dead
-not IE 9-11 # For IE 9-11 support, remove 'not'.
\ No newline at end of file
+not IE 9-11 # For IE 9-11 support, remove 'not'.
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.html b/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.html
index c555280..591cdee 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.html
@@ -49,8 +49,13 @@
<input type="number" (keypress)="CheckUtils.numberOnly($event)" min="0"
placeholder="Enter limit, in USD" formControlName="budget">
<span class="error"
- *ngIf="manageUsersForm?.controls['projects']['controls'][i].controls['budget'].hasError('overrun')">Per-user
- quotes cannot be greater than total budget</span>
+ *ngIf="manageUsersForm?.controls['projects']['controls'][i].controls['budget'].hasError('overrun') &&
+ !manageUsersForm?.controls['projects']['controls'][i].controls['budget'].hasError('max')"
+ >
+ Projects budget cannot be higher than total budget
+ </span>
+ <span class="error"
+ *ngIf="manageUsersForm?.controls['projects']['controls'][i].controls['budget'].hasError('max')">Project budget cannot be higher than 1000000000</span>
</div>
</mat-list-item>
</div>
@@ -60,10 +65,15 @@
<div class="username ellipsis">
<span class="ellipsis">Total budget</span>
</div>
+ <div class="period">
+ </div>
<div class="quotes">
<input type="number" (keypress)="CheckUtils.numberOnly($event)" formControlName="total"
placeholder="Enter total budget, in USD">
- <span class="error" *ngIf="manageUsersForm?.controls['total'].hasError('overrun')">Total budget cannot be lower than a sum of users quotes</span>
+ <span class="error" *ngIf="manageUsersForm?.controls['total'].hasError('overrun')
+ && !manageUsersForm?.controls['total'].hasError('max')">Total budget cannot be lower than a sum of projects quotes</span>
+ <span class="error"
+ *ngIf="manageUsersForm?.controls['total'].hasError('max')">Total budget cannot be higher than 1000000000</span>
</div>
</mat-list-item>
</div>
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.scss b/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.scss
index 4e1aadf..1cea435 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.scss
@@ -50,8 +50,9 @@
.error {
position: absolute;
left: 0;
- top: 34px;
+ top: 37px;
font-family: 'Open Sans', sans-serif;
+ font-size: 11px;
}
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.ts b/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.ts
index 848daf7..4aa2871 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/management/manage-environment/manage-environment-dilog.component.ts
@@ -60,10 +60,12 @@
this.isFormChanged = JSON.stringify(this.initialFormState) === JSON.stringify(this.manageUsersForm.value);
if ((this.getCurrentTotalValue() && this.getCurrentTotalValue() >= this.getCurrentUsersTotal())) {
this.manageUsersForm.controls['projects']['controls'].forEach(v => {
- v.controls['budget'].setErrors(null);
+ v.controls['budget'].errors &&
+ 'max' in v.controls['budget'].errors ? null : v.controls['budget'].setErrors(null);
}
);
- this.manageUsersForm.controls['total'].setErrors(null);
+ this.manageUsersForm.controls['total'].errors &&
+ this.manageUsersForm.controls['total'].errors ? null : this.manageUsersForm.controls['total'].setErrors(null);
}
});
}
@@ -99,14 +101,14 @@
this.manageUsersForm.setControl('projects',
this._fb.array((this.data.projectsList || []).map((x: any) => this._fb.group({
project: x.name,
- budget: [x.budget.value, [ this.userValidityCheck.bind(this)]],
+ budget: [x.budget.value, [ Validators.max(1000000000), this.userValidityCheck.bind(this)]],
monthlyBudget: x.budget.monthlyBudget,
}))));
}
private initForm(): void {
this.manageUsersForm = this._fb.group({
- total: [null, [Validators.min(0), this.totalValidityCheck.bind(this)]],
+ total: [null, [Validators.min(0), this.totalValidityCheck.bind(this), Validators.max(1000000000)]],
projects: this._fb.array([this._fb.group({ project: '', budget: null, status: '' })])
});
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/management/management-grid/management-grid.component.html b/services/self-service/src/main/resources/webapp/src/app/administration/management/management-grid/management-grid.component.html
index bf3ef16..8d2df70 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/management/management-grid/management-grid.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/management/management-grid/management-grid.component.html
@@ -122,7 +122,7 @@
<span [hidden]="filtering && filterForm.statuses.length > 0 && !collapsedFilterRow">more_vert</span>
</i>
</button> </th>
- <td mat-cell *matCellDef="let element" class="ani status label-header" >
+ <td mat-cell *matCellDef="let element" class="ani status" >
<span ngClass="{{element.status || ''}}">{{ element.status }}</span>
</td>
</ng-container>
@@ -231,7 +231,7 @@
</ng-container>
<ng-container matColumnDef="type-filter" sticky>
<th mat-header-cell *matHeaderCellDef class="filter-row-item">
- <input placeholder="Filter by environment type" type="text" class="form-control filter-field"
+ <input placeholder="Filter by environment name" type="text" class="form-control filter-field"
[value]="filterForm.type" (input)="filterForm.type = $event.target['value']"/>
</th>
</ng-container>
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/management/management-grid/management-grid.component.scss b/services/self-service/src/main/resources/webapp/src/app/administration/management/management-grid/management-grid.component.scss
index 00f13e0..9d9f4b5 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/management/management-grid/management-grid.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/management/management-grid/management-grid.component.scss
@@ -19,13 +19,17 @@
.data-grid {
&.management {
+ .filter-row-item{
+ padding: 5px;
+ }
+
.settings{
min-width: 7%;
}
.mat-column-checkbox{
padding-left: 10px;
padding-right: 0px;
- min-width: 68px;
+ min-width: 38px;
&.label-header{
}
@@ -57,7 +61,6 @@
.resources {
width: 24%;
- padding: 5px;
}
.settings {
@@ -67,6 +70,7 @@
}
.actions {
margin-top: 0px;
+ padding-right: 10px;
.label{
padding-right: 5px;
}
@@ -76,6 +80,53 @@
}
+ .label-header{
+ padding-left: 15px;
+ height: 56px;
+
+ .ar{
+ left: 21px;
+ top: 2px;
+ }
+ .settings{
+ min-width: 7%;
+ }
+ &.mat-column-checkbox{
+ z-index: 12 !important;
+ padding-left: 10px;
+ .ar{
+ position: absolute;
+ top: 10px;
+ }
+ }
+ &.user{
+ z-index: 11 !important;
+ }
+ &.type{
+ z-index: 10 !important;
+ }
+
+ &.project {
+ z-index: 9 !important;
+ }
+
+ &.shape {
+ z-index: 8 !important;
+ }
+
+ &.status {
+ z-index: 7 !important;
+ }
+
+ &.resources {
+ z-index: 6 !important;
+ }
+
+ &.actions {
+ z-index: 5 !important;
+ }
+ }
+
.dashboard_table_body {
td:first-child {
cursor: default;
@@ -105,6 +156,7 @@
td:not(.info) {
padding: 5px;
+ padding-left: 20px;
}
.header-row {
@@ -114,7 +166,6 @@
padding-top: 14px;
vertical-align: super !important;
padding-left: 5px;
- font-size: 12px;
}
.actions {
text-align: right;
@@ -127,6 +178,11 @@
.filter-row {
background: inherit;
+
+ .filter-field{
+ font-size: 13px;
+ padding-left: 15px;
+ }
}
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/management/management.component.html b/services/self-service/src/main/resources/webapp/src/app/administration/management/management.component.html
index 02ab5b9..187a3ee 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/management/management.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/management/management.component.html
@@ -67,7 +67,7 @@
</button> -->
</div>
<button mat-raised-button class="butt" (click)="refreshGrid()">
- <i class="material-icons">autorenew</i>Refresh
+ <i class="material-icons refresh-icon">autorenew</i>Refresh
</button>
</div>
<mat-divider></mat-divider>
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/project/project-list/project-list.component.scss b/services/self-service/src/main/resources/webapp/src/app/administration/project/project-list/project-list.component.scss
index b985d94..9050ff6 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/project/project-list/project-list.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/project/project-list/project-list.component.scss
@@ -26,7 +26,15 @@
.name {
width: 25%;
- padding: 10px 0 10px 24px;
+ padding: 20px 0 10px 24px;
+ }
+
+ th.name{
+ padding-top: 10px;
+ }
+
+ .mat-header-row{
+ padding-top: 12px;
}
.endpoints {
@@ -77,7 +85,6 @@
&.mat-header-cell{
padding-top: 19px;
- padding-right: 13px;
color: rgba(0,0,0,.54);
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/administration/project/project.component.html b/services/self-service/src/main/resources/webapp/src/app/administration/project/project.component.html
index 3be7a10..98ea6aa 100644
--- a/services/self-service/src/main/resources/webapp/src/app/administration/project/project.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/administration/project/project.component.html
@@ -39,7 +39,7 @@
</span>
</button>
<button mat-raised-button class="butt" (click)="refreshGrid()" [hidden]="!projectList.length">
- <i class="material-icons">autorenew</i>Refresh
+ <i class="material-icons refresh-icon">autorenew</i>Refresh
</button>
</div>
</div>
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/interceptors/error.interceptor.ts b/services/self-service/src/main/resources/webapp/src/app/core/interceptors/error.interceptor.ts
index 4ae3899..d1ae984 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/interceptors/error.interceptor.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/interceptors/error.interceptor.ts
@@ -18,7 +18,7 @@
*/
import { Injectable } from '@angular/core';
-import { BehaviorSubject } from 'rxjs';
+import {BehaviorSubject} from 'rxjs';
import {
HttpInterceptor,
HttpRequest,
@@ -47,6 +47,7 @@
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(
catchError(error => {
+ if (error.error && error.error.message && error.error.message.indexOf('query param artifact') !== -1) return _throw(error);
if (error instanceof HttpErrorResponse) {
switch ((<HttpErrorResponse>error).status) {
case HTTP_STATUS_CODES.UNAUTHORIZED:
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/pipes/keys-pipe/keys.pipe.ts b/services/self-service/src/main/resources/webapp/src/app/core/pipes/keys-pipe/keys.pipe.ts
index 5fe18ad..8c6fb0b 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/pipes/keys-pipe/keys.pipe.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/pipes/keys-pipe/keys.pipe.ts
@@ -22,7 +22,7 @@
@Pipe({ name: 'keys' })
export class KeysPipe implements PipeTransform {
- transform(value, args: string[]): any {
+ transform(value): any {
const keys = [];
for (const key in value) {
keys.push({ key: key, value: value[key]});
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/pipes/underscoreless-pipe/underscoreless.pipe.ts b/services/self-service/src/main/resources/webapp/src/app/core/pipes/underscoreless-pipe/underscoreless.pipe.ts
index a21da90..32670b0 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/pipes/underscoreless-pipe/underscoreless.pipe.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/pipes/underscoreless-pipe/underscoreless.pipe.ts
@@ -22,7 +22,7 @@
@Pipe({ name: 'underscoreless' })
export class UnderscorelessPipe implements PipeTransform {
- transform(value, args: string[]): any {
+ transform(value): any {
return value.replace(/_/g, ' ');
}
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/services/applicationServiceFacade.service.ts b/services/self-service/src/main/resources/webapp/src/app/core/services/applicationServiceFacade.service.ts
index 2c0e661..39e92af 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/services/applicationServiceFacade.service.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/services/applicationServiceFacade.service.ts
@@ -78,6 +78,7 @@
private static readonly ENDPOINT = 'endpoint';
private static readonly ENDPOINT_CONNECTION = 'endpoint_connection';
private static readonly AUDIT = 'audit';
+ private static readonly QUOTA = 'quota';
private requestRegistry: Dictionary<string>;
@@ -307,6 +308,13 @@
data);
}
+ public buildGetQuotaStatus(): Observable<any> {
+ return this.buildRequest(HTTPMethod.GET,
+ this.requestRegistry.Item(ApplicationServiceFacade.QUOTA),
+ null
+ );
+ }
+
public buildRunEdgeNodeRequest(): Observable<any> {
return this.buildRequest(HTTPMethod.POST,
this.requestRegistry.Item(ApplicationServiceFacade.EDGE_NODE_START),
@@ -723,6 +731,7 @@
// billing report
this.requestRegistry.Add(ApplicationServiceFacade.BILLING, '/api/billing/report');
this.requestRegistry.Add(ApplicationServiceFacade.DOWNLOAD_REPORT, '/api/billing/report/download');
+ this.requestRegistry.Add(ApplicationServiceFacade.QUOTA, '/api/billing/quota');
// project
this.requestRegistry.Add(ApplicationServiceFacade.PROJECT, '/api/project');
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/services/audit.service.ts b/services/self-service/src/main/resources/webapp/src/app/core/services/audit.service.ts
index 1d54792..520f623 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/services/audit.service.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/services/audit.service.ts
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import { Injectable } from '@angular/core';
import {ApplicationServiceFacade} from './applicationServiceFacade.service';
import {catchError, map} from 'rxjs/operators';
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/services/bucket-browser.service.ts b/services/self-service/src/main/resources/webapp/src/app/core/services/bucket-browser.service.ts
index 4d2fe83..45982eb 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/services/bucket-browser.service.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/services/bucket-browser.service.ts
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import { Injectable } from '@angular/core';
import {Observable} from 'rxjs';
import {catchError, map} from 'rxjs/operators';
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/services/healthStatus.service.ts b/services/self-service/src/main/resources/webapp/src/app/core/services/healthStatus.service.ts
index 02004f3..09f902e 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/services/healthStatus.service.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/services/healthStatus.service.ts
@@ -84,6 +84,14 @@
catchError(ErrorUtils.handleServiceError));
}
+ public getQuotaStatus(): Observable<{}> {
+ return this.applicationServiceFacade
+ .buildGetQuotaStatus()
+ .pipe(
+ map(response => response),
+ catchError(ErrorUtils.handleServiceError));
+ }
+
public runEdgeNode(): Observable<{}> {
return this.applicationServiceFacade
.buildRunEdgeNodeRequest()
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/services/librariesInstallation.service.ts b/services/self-service/src/main/resources/webapp/src/app/core/services/librariesInstallation.service.ts
index 2119b1a..38d18bc 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/services/librariesInstallation.service.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/services/librariesInstallation.service.ts
@@ -49,7 +49,6 @@
public getAvailableDependencies(data): Observable<{}> {
const body = `/maven?artifact=${data}`;
-
return this.applicationServiceFacade
.buildGetAvailableDependenciest(body)
.pipe(
diff --git a/services/self-service/src/main/resources/webapp/src/app/core/util/patterns.ts b/services/self-service/src/main/resources/webapp/src/app/core/util/patterns.ts
index 8246bba..981e661 100644
--- a/services/self-service/src/main/resources/webapp/src/app/core/util/patterns.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/core/util/patterns.ts
@@ -24,6 +24,6 @@
url: '[a-zA-Z0-9.://%#&\\.@:%-_\+~#=]*\.[^\s]*[a-zA-Z0-9]/+',
nodeCountPattern: '^[1-9]\\d*$',
integerRegex: '^[0-9]*$',
- folderRegex: /^[a-zA-Z0-9!@$%^&*()_+\-=\[\]{};':|,.<>~` ]*$/,
+ folderRegex: /^[a-zA-Z0-9!@$^&*()_+\-=\[\]{};':|,.<>~` ]*$/,
fullUrl: /^(http?|ftp|https):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+([.:])(\d{4}|com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*\/$/
};
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.html b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.html
index a6125f9..cfdaa59 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.html
@@ -17,11 +17,25 @@
~ under the License.
-->
-<section class="audit-table-wrapper">
+<section class="audit-table-wrapper" id="scrolling">
<table mat-table [dataSource]="auditData" class="data-grid audit mat-elevation-z6">
+ <ng-container matColumnDef="date">
+ <th mat-header-cell *matHeaderCellDef class="th_date label-header">
+ <div class="label"><span class="text">Date</span></div>
+ <button mat-icon-button aria-label="More" class="ar" (click)="toggleFilterRow()">
+ <i class="material-icons">
+ <span>more_vert</span>
+ </i>
+ </button>
+ </th>
+ <td mat-cell *matCellDef="let element"> {{element.timestamp | date: 'dd/MM/yyyy hh:mm:ss aa'}} </td>
+ <td mat-footer-cell *matFooterCellDef class="table-footer">
+ </td>
+ </ng-container>
+
<ng-container matColumnDef="user">
- <th mat-header-cell *matHeaderCellDef class="th_user label-header">
+ <th mat-header-cell *matHeaderCellDef class="th_user label-header" [ngStyle]="{'z-index': 99}">
<div class="label"><span class="audit-user"> User</span></div>
<button mat-icon-button aria-label="More" class="ar" (click)="toggleFilterRow()">
<i class="material-icons">
@@ -34,6 +48,28 @@
<td mat-footer-cell *matFooterCellDef class="table-footer"></td>
</ng-container>
+ <ng-container matColumnDef="action">
+ <th mat-header-cell *matHeaderCellDef class="th_action label-header" [ngStyle]="{'zIndex': 98, 'display': 'sticky'}">
+ <div class="label">
+ <span class="text"> Action </span>
+ </div>
+ <button mat-icon-button aria-label="More" class="ar" (click)="toggleFilterRow()">
+ <i class="material-icons">
+ <span>more_vert</span>
+ </i>
+ </button>
+ </th>
+ <td mat-cell *matCellDef=" let element" class="th_action">
+ <div class="action-wrapper">
+ <span class="ellipsis">{{element.action | convertaction }}</span>
+ <div class="audit-info" (click)="openActionInfo(element)" *ngIf="element.info">
+ <i class="material-icons">info</i>
+ </div>
+ </div>
+ </td>
+ <td mat-footer-cell *matFooterCellDef class="table-footer"></td>
+ </ng-container>
+
<ng-container matColumnDef="project">
<th mat-header-cell *matHeaderCellDef class="th_project label-header">
<div class="label"><span class="text">Project</span></div>
@@ -125,32 +161,6 @@
</td>
</ng-container>
- <ng-container matColumnDef="action">
- <th mat-header-cell *matHeaderCellDef class="th_action label-header">
- <div class="label">
- <span class="text"> Action </span>
- </div>
- </th>
- <td mat-cell *matCellDef=" let element">
- <div class="action-wrapper">
- <span>{{element.action | convertaction }}</span>
- <div class="audit-info" (click)="openActionInfo(element)" *ngIf="element.info">
- <i class="material-icons">info</i>
- </div>
- </div>
- </td>
- <td mat-footer-cell *matFooterCellDef class="table-footer"></td>
- </ng-container>
-
- <ng-container matColumnDef="date">
- <th mat-header-cell *matHeaderCellDef class="th_date label-header">
- <div class="label"><span class="text">Date</span></div>
- </th>
- <td mat-cell *matCellDef="let element"> {{element.timestamp | date: 'dd/MM/yyyy hh:mm:ss aa'}} </td>
- <td mat-footer-cell *matFooterCellDef class="table-footer">
- </td>
- </ng-container>
-
<ng-container matColumnDef="buttons">
<th mat-header-cell *matHeaderCellDef class="th_buttons label-header"></th>
<td mat-cell *matCellDef="let element"></td>
@@ -189,16 +199,17 @@
<ng-container matColumnDef="actions-filter">
<th mat-header-cell *matHeaderCellDef class="filter-row-item">
+
</th>
</ng-container>
- <ng-container matColumnDef="action-filter" stickyEnd>
- <th mat-header-cell *matHeaderCellDef>
+ <ng-container matColumnDef="date-filter">
+ <th mat-header-cell *matHeaderCellDef class="filter-row-item">
</th>
</ng-container>
<ng-container matColumnDef="filter-buttons" stickyEnd>
- <th mat-header-cell *matHeaderCellDef>
+ <th mat-header-cell *matHeaderCellDef class="filter-row-item">
<div class="actions audit-actions">
<button mat-icon-button class="btn reset" (click)="resetFilterConfigurations()">
<i class="material-icons">close</i>
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.scss b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.scss
index 29250ea..493e094 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.scss
@@ -19,12 +19,16 @@
.audit-table-wrapper {
width: 100%;
+ max-height: calc(100vh - 130px);
+ overflow: auto;
+ box-shadow: 0 3px 5px -1px rgba(0,0,0,.2), 0 6px 10px 0 rgba(0,0,0,.14), 0 1px 18px 0 rgba(0,0,0,.12);
.audit {
width: 100%;
min-width: 1100px;
overflow: auto;
border-collapse: inherit;
+ box-shadow: none;
.mat-cell {
vertical-align: middle;
@@ -33,36 +37,39 @@
tr {
.th_user {
width: 19%;
+ z-index: 9 !important;
}
.th_action {
width: 11%;
- .label{
- padding-bottom: 10px;
- }
+ z-index: 8 !important;
+ max-width: 250px;
}
.th_date {
width: 14%;
- .label{
- padding-bottom: 10px;
- }
+ z-index: 10 !important;
+ padding-left: 0;
}
- .th_project{
+ .th_project {
width: 11%;
+ z-index: 7 !important;
}
- .th_resource{
+ .th_resource {
width: 14%;
+ z-index: 5 !important;
}
- .th_resource-type{
+ .th_resource-type {
width: 14%;
+ z-index: 6 !important;
}
- .th_buttons{
+ .th_buttons {
width: 6%;
+ z-index: 4 !important;
}
th {
@@ -76,7 +83,7 @@
td {
font-size: 13px;
- padding-left: 15px;
+ padding-left: 20px;
&.info {
z-index: 1 !important;
@@ -189,7 +196,7 @@
vertical-align: super !important;
.text {
- padding-left: 15px;
+ padding-left: 20px;
}
}
@@ -222,10 +229,16 @@
}
}
- .action-wrapper{
+ .action-wrapper {
display: flex;
align-items: center;
- .audit-info{
+ justify-content: space-between;
+ padding-right: 10px;
+ span{
+ max-width: 85%;
+ }
+
+ .audit-info {
color: lightgray;
cursor: pointer;
margin-left: 5px;
@@ -239,48 +252,56 @@
.dropdown-multiselect {
button {
- font-size: 14px;
+ font-size: 13px;
height: 34px;
padding: 7px 20px;
}
}
}
- .user-col{
- padding-left: 5px;
- }
}
-.selected-items-wrapper{
+.selected-items-wrapper {
display: flex;
align-items: center;
- .select-wrapper{
+
+ .select-wrapper {
margin-left: 20px;
width: 80px;
}
}
-.pagination-wrapper{
+.pagination-wrapper {
display: flex;
align-items: center;
justify-content: space-between;
padding-right: 30px;
- .navigation-butts{
- cursor: pointer;
- .not-active{
+
+ .not-active {
+ .navigation-butts {
color: lightgray;
}
}
-}
-.audit-actions{
+ .navigation-butts {
+ cursor: pointer;
+ color: #35afd5;
+
+ .not-active {
+ color: lightgray;
+ }
+ }
+ }
+
+
+.audit-actions {
text-align: right;
}
-.audit-user{
- padding-left: 19px;
+.audit-user {
+ padding-left: 20px;
}
-.table-footer{
+.table-footer {
position: sticky;
bottom: 0;
background: inherit;
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.ts b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.ts
index 4dc5aae..953aeae 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-grid/audit-grid.component.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import {Component, Inject, OnInit} from '@angular/core';
+import {Component, EventEmitter, Inject, OnInit, Output} from '@angular/core';
import {FilterAuditModel} from '../filter-audit.model';
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material/dialog';
import {AuditService} from '../../../core/services/audit.service';
@@ -43,7 +43,7 @@
export class AuditGridComponent implements OnInit {
public auditData: Array<AuditItem>;
public displayedColumns: string[] = ['date', 'user', 'action', 'project', 'resource-type', 'resource', 'buttons'];
- public displayedFilterColumns: string[] = ['action-filter', 'user-filter', 'actions-filter', 'project-filter', 'resource-type-filter', 'resource-filter', 'filter-buttons'];
+ public displayedFilterColumns: string[] = ['date-filter', 'user-filter', 'actions-filter', 'project-filter', 'resource-type-filter', 'resource-filter', 'filter-buttons'];
public collapseFilterRow: boolean = false;
public filterConfiguration: FilterAuditModel = new FilterAuditModel([], [], [], [], [], '', '');
public filterAuditData: FilterAuditModel = new FilterAuditModel([], [], [], [], [], '', '');
@@ -55,6 +55,8 @@
private copiedFilterAuditData: FilterAuditModel;
public isNavigationDisabled: boolean;
+ @Output() resetDateFilter: EventEmitter<any> = new EventEmitter();
+
constructor(
public dialogRef: MatDialogRef<AuditInfoDialogComponent>,
@@ -157,6 +159,7 @@
public resetFilterConfigurations(): void {
this.filterAuditData = FilterAuditModel.getDefault();
+ this.resetDateFilter.emit();
this.buildAuditGrid(true);
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.html b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.html
index 3562b08..468ebb3 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.html
@@ -16,7 +16,7 @@
~ specific language governing permissions and limitations
~ under the License.
-->
-<section class="toolbar">
+<section class="audit-toolbar">
<div class="info_color">
<div class="general" *ngIf="reportData">
<div><span>Service base name: </span><strong>{{ reportData.sbn }}</strong></div>
@@ -35,7 +35,7 @@
</div>
<div class="action-butt">
<button mat-raised-button class="butt" (click)="rebuild($event)">
- <i class="material-icons">autorenew</i>Refresh
+ <i class="material-icons refresh-icon">autorenew</i>Refresh
</button>
</div>
</section>
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.scss b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.scss
index 744bfdc..0bf0071 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.scss
@@ -17,7 +17,7 @@
* under the License.
*/
-section.toolbar {
+section.audit-toolbar {
display: flex;
justify-content: space-between;
font-weight: 300;
@@ -62,79 +62,5 @@
}
}
-/* daterangepicker themes */
-#range-picker {
- margin-top: 5px;
-}
-#range-picker path#Shape {
- fill: #36afd5;
-}
-#range-picker .ng-daterangepicker,
-#range-picker .ng-daterangepicker.is-active,
-#range-picker .ng-daterangepicker .calendar {
- border: none;
- border-radius: 0;
- box-shadow: 0 3px 1px -2px rgba(0, 0, 0, .2), 0 2px 2px 0 rgba(0, 0, 0, .14), 0 1px 5px 0 rgba(0, 0, 0, .12);
-}
-
-#range-picker .ng-daterangepicker .calendar::after {
- border-top: 1px solid rgba(234, 234, 234, 0.64);
- border-left: 1px solid rgba(234, 234, 234, 0.64);
-}
-
-#range-picker .ng-daterangepicker .calendar .side-container .side-button {
- background: #fff;
- color: #718ba6;
- border: none;
- border-radius: 0px;
- box-shadow: 0 3px 1px -2px rgba(0, 0, 0, .2), 0 2px 2px 0 rgba(0, 0, 0, .14), 0 1px 5px 0 rgba(0, 0, 0, .12)
-}
-
-#range-picker .ng-daterangepicker .calendar .side-container .side-button.is-active,
-#range-picker .ng-daterangepicker .input-section .label-txt {
- color: #35afd5;
-}
-
-#range-picker .ng-daterangepicker .calendar .calendar-container .day-num.is-active,
-#range-picker .ng-daterangepicker .calendar .calendar-container .days .day-num:hover {
- background: #35afd5;
- background-clip: padding-box;
-
-}
-
-#range-picker .ng-daterangepicker .calendar .calendar-container .day-names,
-#range-picker .ng-daterangepicker .calendar .calendar-container .days {
- width: 310px;
-}
-
-#range-picker .ng-daterangepicker .calendar .day.is-within-range.is-first-weekday,
-#range-picker .ng-daterangepicker .calendar .day.is-within-range.is-last-weekday {
- background-clip: padding-box;
-}
-
-#range-picker .ng-daterangepicker .calendar .calendar-container .day.is-within-range {
- background: #e9f8fc
-}
-
-#range-picker .ng-daterangepicker .input-section .cal-icon svg path {
- fill: #35afd5;
-}
-
-#range-picker .ng-daterangepicker .input-section .value-txt {
- color: #718ba6;
-}
-
-#range-picker .ng-daterangepicker .input-section .value-txt.untouched,
-#range-picker .ng-daterangepicker .input-section .label-txt.untouched {
- color: #fff;
-}
-
-#range-picker .ng-daterangepicker .input-section .value-txt.untouched::after {
- content: 'Select date';
- position: absolute;
- top: 22px;
- left: 34px;
- color: #718ba6;
-}
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.ts b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.ts
index cc4933e..f1a889a 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit-toolbar/audit-toolbar.component.ts
@@ -61,31 +61,37 @@
}
ngOnInit() {
- // if (localStorage.getItem('report_period')) {
- // const availableRange = JSON.parse(localStorage.getItem('report_period'));
- // this.availablePeriodFrom = availableRange.start_date;
- // this.availablePeriodTo = availableRange.end_date; }
- // this.subscriptions.add(this.healthStatusService.statusData.pipe(skip(1)).subscribe(result => {
- // this.healthStatus = result;
- // }));
+ this.setInitDatapickerConfig();
}
ngAfterViewInit() {
this.clearRangePicker();
}
+ private setInitDatapickerConfig() {
+ const labels = <NodeListOf<Element>>document.querySelectorAll('.label-txt');
+ const rangeLabels = <NodeListOf<Element>>document.querySelectorAll('.value-txt');
+ labels[0].innerHTML = 'From date';
+ labels[1].innerHTML = 'To date';
+ for (let label = 0; label < rangeLabels.length; ++label) {
+ rangeLabels[label].classList.add('d-none');
+ rangeLabels[label].classList.add('untouched');
+ }
+ }
+
setDateRange() {
const availableRange = JSON.parse(localStorage.getItem('report_period'));
+ const rangeLabels = <NodeListOf<Element>>document.querySelectorAll('.value-txt');
+ for (let label = 0; label < rangeLabels.length; ++label) {
+ rangeLabels[label].classList.remove('d-none');
+ }
this.availablePeriodFrom = availableRange.start_date;
this.availablePeriodTo = availableRange.end_date;
}
clearRangePicker(): void {
- const rangeLabels = <NodeListOf<Element>>document.querySelectorAll('.value-txt');
-
- for (let label = 0; label < rangeLabels.length; ++label)
- rangeLabels[label].classList.add('untouched');
+ this.setInitDatapickerConfig();
}
onChange(dateRange: string): void {
@@ -94,8 +100,14 @@
for (let label = 0; label < rangeLabels.length; ++label)
if (rangeLabels[label].classList.contains('untouched')) {
rangeLabels[label].classList.remove('untouched');
+ rangeLabels[label].classList.remove('d-none');
}
+
+ const labels = <NodeListOf<Element>>document.querySelectorAll('.label-txt');
+ labels[0].innerHTML = 'From:';
+ labels[1].innerHTML = 'To:';
+
const reportDateRange = dateRange.split('-');
this.setRangeOption.emit({
start_date: reportDateRange[0].split('/').join('-'),
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit.component.ts b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit.component.ts
index 6f48b71..af3919d 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/audit/audit.component.ts
@@ -42,7 +42,7 @@
<audit-toolbar (rebuildAudit)="rebuildAuditGrid()" (setRangeOption) = setRangeOption($event)>
</audit-toolbar>
<mat-divider></mat-divider>
- <dlab-audit-grid></dlab-audit-grid>
+ <dlab-audit-grid (resetDateFilter)="resetDatepicker()"></dlab-audit-grid>
</div>
`,
@@ -96,6 +96,10 @@
}
public setRangeOption(event) {
- this.auditGrid.setAvaliblePeriod(event)
+ this.auditGrid.setAvaliblePeriod(event);
+ }
+
+ public resetDatepicker() {
+ this.auditToolbar.clearRangePicker();
}
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/audit/filter-audit.model.ts b/services/self-service/src/main/resources/webapp/src/app/reports/audit/filter-audit.model.ts
index b4b6845..b1b6a65 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/audit/filter-audit.model.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/audit/filter-audit.model.ts
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
export class FilterAuditModel {
static getDefault(): FilterAuditModel {
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.html b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.html
index 9366725..1481d53 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.html
@@ -17,8 +17,22 @@
~ under the License.
-->
-<section class="table-wrapper">
- <table mat-table [dataSource]="reportData" class="data-grid reporting mat-elevation-z6">
+<div class="wrapper">
+<section class="table-wrapper" id="scrolling" #tableWrapper (scroll)="scrollTable($event)">
+
+<!-- <div class="navigation-btn">-->
+<!-- <div class="left">-->
+<!-- <button mat-fab aria-label="Scroll left">-->
+<!-- <mat-icon>keyboard_arrow_left</mat-icon>-->
+<!-- </button>-->
+<!-- </div>-->
+<!-- <div class="right">-->
+<!-- <button mat-fab aria-label="Scroll right">-->
+<!-- <mat-icon>keyboard_arrow_right</mat-icon>-->
+<!-- </button>-->
+<!-- </div>-->
+<!-- </div>-->
+ <table mat-table [dataSource]="reportData" class="data-grid reporting mat-elevation-z6" #table>
<ng-container matColumnDef="name">
<th mat-header-cell *matHeaderCellDef class="env_name label-header">
@@ -36,13 +50,15 @@
<ng-container matColumnDef="user">
<th mat-header-cell *matHeaderCellDef class="th_user label-header">
- <div class="sort">
- <div class="sort-arrow up" (click)="sortBy('user', 'down')" [ngClass]="{'active': !!this.active['userdown']}"></div>
- <div class="sort-arrow down" (click)="sortBy('user', 'up')" [ngClass]="{'active': !!this.active['userup']}"></div>
- </div>
+
<div class="label">
+ <div class="sort sort-user">
+ <div class="sort-arrow up" (click)="sortBy('user', 'down')" [ngClass]="{'active': !!this.active['userdown']}"></div>
+ <div class="sort-arrow down" (click)="sortBy('user', 'up')" [ngClass]="{'active': !!this.active['userup']}"></div>
+ </div>
<span class="text"> User </span>
</div>
+
<button mat-icon-button aria-label="More" class="ar" (click)="toggleFilterRow()">
<i class="material-icons">
<span *ngIf="filteredReportData.users.length > 0; else user_filtered">filter_list</span>
@@ -56,11 +72,15 @@
<ng-container matColumnDef="project">
<th mat-header-cell *matHeaderCellDef class="th_project label-header">
- <div class="sort">
- <div class="sort-arrow up" (click)="sortBy('project', 'down')" [ngClass]="{'active': !!this.active['projectdown']}"></div>
- <div class="sort-arrow down" (click)="sortBy('project', 'up')" [ngClass]="{'active': !!this.active['projectup']}"></div>
+
+ <div class="label">
+ <div class="sort sort-project">
+ <div class="sort-arrow up" (click)="sortBy('project', 'down')" [ngClass]="{'active': !!this.active['projectdown']}"></div>
+ <div class="sort-arrow down" (click)="sortBy('project', 'up')" [ngClass]="{'active': !!this.active['projectup']}"></div>
+ </div>
+ <span class="text">Project</span>
</div>
- <div class="label"><span class="text">Project</span></div>
+
<button mat-icon-button aria-label="More" class="ar" (click)="toggleFilterRow()">
<i class="material-icons">
<span *ngIf="filteredReportData.projects.length > 0; else project_filtered">filter_list</span>
@@ -141,6 +161,21 @@
<td mat-footer-cell *matFooterCellDef class="table-footer"></td>
</ng-container>
+ <ng-container matColumnDef="empty">
+ <th mat-header-cell *matHeaderCellDef class="th_empty label-header">
+ </th>
+ <td mat-cell *matCellDef="let element">
+ </td>
+ <td mat-footer-cell *matFooterCellDef class="table-footer total-cost" [colSpan]="2">
+ <span class="strong">
+ Total <span *ngIf="reportData?.length"> {{ fullReport['total_cost'] }}
+ {{ fullReport['currency'] }}</span>
+ </span>
+ </td>
+ </ng-container>
+
+
+
<ng-container matColumnDef="charge" stickyEnd>
<th mat-header-cell *matHeaderCellDef class="th_charges label-header">
<div class="label">
@@ -155,17 +190,17 @@
<td mat-cell *matCellDef="let element">
{{ element.cost }} {{ element['currency'] }}
</td>
- <td mat-footer-cell *matFooterCellDef class="table-footer total-cost">
- Total <span *ngIf="reportData?.length"> {{ fullReport['total_cost'] }}
- {{ fullReport['currency'] }}</span>
+ <td mat-footer-cell *matFooterCellDef class="table-footer total-cost d-none">
</td>
</ng-container>
<!-- ----------------FILTER -->
<ng-container matColumnDef="name-filter">
<th mat-header-cell *matHeaderCellDef class="filter-row-item">
- <input #nameFilter type="text" placeholder="Filter by environment name" class="form-control filter-field"
- [value]="filtered?.dlab_id" (input)="filteredReportData.dlab_id = $event.target['value']" />
+ <div class="input-wrapper">
+ <input #nameFilter type="text" placeholder="Filter by environment name" class="form-control filter-field"
+ [value]="filtered?.dlab_id" (input)="filteredReportData.dlab_id = $event.target['value']" />
+ </div>
</th>
</ng-container>
<ng-container matColumnDef="user-filter">
@@ -200,6 +235,12 @@
[model]="filteredReportData['shapes']"></multi-select-dropdown>
</th>
</ng-container>
+
+ <ng-container matColumnDef="empty-filter">
+ <th mat-header-cell *matHeaderCellDef class="filter-row-item">
+ </th>
+ </ng-container>
+
<ng-container matColumnDef="service-filter">
<th mat-header-cell *matHeaderCellDef class="filter-row-item">
<multi-select-dropdown *ngIf="filterConfiguration" (selectionChange)="onUpdate($event)"
@@ -210,7 +251,7 @@
</ng-container>
<ng-container matColumnDef="actions" stickyEnd>
<th mat-header-cell *matHeaderCellDef class="filter-row-item">
- <div class="actions th_charges">
+ <div class="actions">
<button mat-icon-button class="btn reset" (click)="resetFiltering(); isFiltered = !isFiltered">
<i class="material-icons">close</i>
</button>
@@ -222,8 +263,8 @@
</th>
</ng-container>
<ng-container matColumnDef="placeholder">
- <td mat-footer-cell *matFooterCellDef colspan="8" class="info">
- No data available
+ <td mat-footer-cell *matFooterCellDef colspan="9" class="info">
+ <span>No data available</span>
</td>
</ng-container>
@@ -238,3 +279,19 @@
<tr [hidden]="reportData?.length" mat-footer-row *matFooterRowDef="['placeholder']"></tr>
</table>
</section>
+ <div class="buttons" *ngIf="isScrollButtonsVisible && reportData?.length">
+ <div class="button-container">
+ <button mat-mini-fab aria-label="Scroll left" (click)="sctollTo('left')" [ngClass]="{'not-allowed': tableWrapper.scrollLeft === 0 }">
+ <mat-icon [ngClass]="{'highlight': tableWrapper.scrollLeft !== 0}">keyboard_arrow_left</mat-icon>
+ </button>
+ </div>
+ <div class="button-container">
+ <button mat-mini-fab aria-label="Scroll right"
+ (click)="sctollTo('right')"
+ [ngClass]="{'not-allowed': !isMaxRight }"
+ >
+ <mat-icon [ngClass]="{'highlight': isMaxRight }">keyboard_arrow_right</mat-icon>
+ </button>
+ </div>
+ </div>
+</div>
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.scss b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.scss
index 9c4f819..253d354 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.scss
@@ -19,9 +19,40 @@
.table-wrapper {
width: 100%;
-
+ display: block;
+ max-height: calc(100vh - 130px);
+ overflow: auto;
+ position: relative;
+ scroll-behavior: smooth;
+ box-shadow: 0 3px 5px -1px rgba(0,0,0,.2), 0 6px 10px 0 rgba(0,0,0,.14), 0 1px 18px 0 rgba(0,0,0,.12);
}
+.wrapper{
+ position: relative;
+
+ .buttons{
+ position: absolute;
+ display: flex;
+ justify-content: space-around;
+ z-index: 1000;
+ bottom: 9px;
+ left: 0;
+ right: 0;
+
+ button{
+ background-color: #fff;
+ box-shadow: none;
+ mat-icon{
+ color: lightgrey;
+ &.highlight{
+ color: #35afd5;
+ }
+ }
+ }
+ }
+}
+
+
.reporting {
width: 100%;
min-width: 1100px;
@@ -35,15 +66,14 @@
tr {
th {
padding-right: 5px;
- z-index: 2 !important;
&.th_charges{
- z-index: 3 !important;
+ z-index: 16 !important;
}
}
td {
font-size: 13px;
- padding-left: 15px;
+ padding-left: 20px;
&.info {
z-index: 1 !important;
@@ -66,17 +96,20 @@
&.header-row {
th {
- font-size: 11px;
+
.label{
padding-left: 0;
+ position: relative;
+ font-size: 13px;
}
}
}
}
.th_shape {
- width: 10%;
+ width: 12%;
min-width: 150px;
+ z-index: 10 !important;
}
.th_user,
@@ -85,10 +118,13 @@
.tags {
width: 15%;
min-width: 150px;
- overflow: hidden;
word-wrap: break-word;
}
+ .service{
+ width: 10%;
+ }
+
.tags {
.label {
padding-top: 0;
@@ -97,30 +133,45 @@
.service {
min-width: 175px;
+ z-index: 9 !important;
}
.env_name {
- width: 16%;
+ width: 21%;
min-width: 200px;
+ z-index: 15 !important;
+ padding-left: 0;
+ }
+
+ .th_user{
+ z-index: 14 !important;
+ }
+
+ .th_empty {
+ width: 1%;
+ z-index: 4 !important;
}
.th_project{
width: 12%;
+ z-index: 13 !important;
+ min-width: 150px;
}
.th_type {
- width: 10%;
- min-width: 150px;
+ width: 12%;
+ min-width: 170px;
+ z-index: 12 !important;
}
.th_status {
width: 8%;
min-width: 150px;
+ z-index: 11 !important;
}
.th_charges {
- width: 10%;
- min-width: 155px;
+ min-width: 135px;
text-align: right;
.label {
@@ -128,10 +179,6 @@
}
}
- .th_project {
- min-width: 150px;
- }
-
.tags-col {
padding: 5px;
@@ -148,8 +195,11 @@
}
}
- .mat-column-charge {
+ .mat-column-charge,
+ .filter-row-item:last-child,
+ .table-footer.mat-column-charge{
text-align: right;
+ background-color: #f8f8f8;
}
.header-row {
@@ -159,7 +209,12 @@
padding-top: 0;
.label {
- padding-top: 12px;
+ padding-top: 10px;
+ }
+
+ &.label-header{
+ box-shadow: none;
+ border-bottom: 1px solid lightgrey !important;
}
}
@@ -169,13 +224,18 @@
vertical-align: super !important;
.text{
- padding-left: 15px;
+ padding-left: 20px;
}
}
.sort{
position: absolute;
- bottom: 20px;
+ bottom: 2px;
+
+ &-user,
+ &-project{
+ right: -15px;
+ }
&-arrow{
width: 6px;
@@ -201,11 +261,13 @@
}
}
-
-
.filter-row {
.actions {
text-align: right;
+
+ button{
+ background: inherit;
+ }
}
}
@@ -245,9 +307,22 @@
&.total-cost{
min-width: 140px;
padding-left: 0 !important;
+ text-align: right;
+ padding-right: 25px;
+ position: sticky;
+ right: 0;
+ z-index: 17;
}
}
+ .left {
+ }
+
+ .right {
+ position: absolute;
+ right: 0;
+ }
+
@media screen and (max-width: 1280px) {
.dashboard_table.reporting {
.env_name,
@@ -261,10 +336,6 @@
width: 12%;
}
- .th_charges {
- width: 6%;
- }
-
.user-field {
word-wrap: break-word;
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.ts b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.ts
index 9c88f27..bf25aae 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/reporting-grid/reporting-grid.component.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import {Component, OnInit, Output, EventEmitter, ViewChild, Input} from '@angular/core';
+import {Component, OnInit, Output, EventEmitter, ViewChild, Input, HostListener, AfterViewInit, ChangeDetectorRef} from '@angular/core';
import { ReportingConfigModel } from '../../../../dictionary/global.dictionary';
@Component({
@@ -27,7 +27,7 @@
'../../../resources/resources-grid/resources-grid.component.scss'],
})
-export class ReportingGridComponent implements OnInit {
+export class ReportingGridComponent implements OnInit, AfterViewInit {
filterConfiguration: ReportingConfigModel;
// filteredReportData: ReportingConfigModel = new ReportingConfigModel([], [], [], [], [], '', '', '', []);
@@ -36,18 +36,45 @@
fullReport: Array<any>;
isFiltered: boolean = false;
active: object = {};
+ public isScrollButtonsVisible: boolean;
@ViewChild('nameFilter', { static: false }) filter;
+ @ViewChild('tableWrapper', { static: false }) tableWrapper;
+ @ViewChild('table', { static: false }) table;
@Output() filterReport: EventEmitter<{}> = new EventEmitter();
@Output() resetRangePicker: EventEmitter<boolean> = new EventEmitter();
@Input() filteredReportData: ReportingConfigModel;
- displayedColumns: string[] = ['name', 'user', 'project', 'type', 'status', 'shape', 'service', 'charge'];
- displayedFilterColumns: string[] = ['name-filter', 'user-filter', 'project-filter', 'type-filter', 'status-filter', 'shape-filter', 'service-filter', 'actions'];
+
+ @HostListener('window:resize', ['$event'])
+ onResize(event) {
+ this.isScrollButtonsVisible = this.tableWrapper.nativeElement.offsetWidth - this.table._elementRef.nativeElement.offsetWidth < 0;
+ this.isMaxRight = this.checkMaxRight();
+ }
+ @HostListener('scroll', ['$event'])
+ scrollTable($event: Event) {
+ this.isMaxRight = this.checkMaxRight();
+ }
+
+
+
+ displayedColumns: string[] = ['name', 'user', 'project', 'type', 'status', 'shape', 'service', 'empty', 'charge'];
+ displayedFilterColumns: string[] = ['name-filter', 'user-filter', 'project-filter', 'type-filter', 'status-filter', 'shape-filter', 'service-filter', 'empty-filter', 'actions'];
filtered: any;
+ isMaxRight: boolean;
+
+ constructor(private changeDetector: ChangeDetectorRef) {
+ }
ngOnInit() {}
+ ngAfterViewInit() {
+ window.setTimeout(() => {
+ this.isScrollButtonsVisible = this.tableWrapper.nativeElement.offsetWidth - this.table._elementRef.nativeElement.offsetWidth < 0;
+ this.isMaxRight = this.checkMaxRight();
+ }, 500);
+ }
+
onUpdate($event): void {
this.filteredReportData[$event.type] = $event.model;
}
@@ -116,4 +143,18 @@
shapeSplit(shape) {
return shape.split(/(?=Slave)/g);
}
+
+ public sctollTo(direction: string) {
+ if (direction === 'left') {
+ this.tableWrapper.nativeElement.scrollLeft = 0;
+ } else {
+ this.tableWrapper.nativeElement.scrollLeft = this.tableWrapper.nativeElement.offsetWidth;
+ }
+ }
+
+ private checkMaxRight() {
+ return this.isMaxRight = this.tableWrapper.nativeElement.offsetWidth +
+ this.tableWrapper.nativeElement.scrollLeft + 2 <= this.table._elementRef.nativeElement.offsetWidth;
+ }
+
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.html b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.html
index 7979849..d7da74b 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.html
@@ -38,7 +38,7 @@
<i class="material-icons">file_download</i>Export
</button>
<button mat-raised-button class="butt" (click)="rebuild($event)">
- <i class="material-icons">autorenew</i>Refresh
+ <i class="material-icons refresh-icon">autorenew</i>Refresh
</button>
</div>
</section>
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.scss b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.scss
index 4a150bf..f23b8a9 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.scss
@@ -62,79 +62,3 @@
}
}
-/* daterangepicker themes */
-#range-picker {
- margin-top: 5px;
-}
-
-#range-picker path#Shape {
- fill: #36afd5;
-}
-
-#range-picker .ng-daterangepicker,
-#range-picker .ng-daterangepicker.is-active,
-#range-picker .ng-daterangepicker .calendar {
- border: none;
- border-radius: 0;
- box-shadow: 0 3px 1px -2px rgba(0, 0, 0, .2), 0 2px 2px 0 rgba(0, 0, 0, .14), 0 1px 5px 0 rgba(0, 0, 0, .12);
-}
-
-#range-picker .ng-daterangepicker .calendar::after {
- border-top: 1px solid rgba(234, 234, 234, 0.64);
- border-left: 1px solid rgba(234, 234, 234, 0.64);
-}
-
-#range-picker .ng-daterangepicker .calendar .side-container .side-button {
- background: #fff;
- color: #718ba6;
- border: none;
- border-radius: 0px;
- box-shadow: 0 3px 1px -2px rgba(0, 0, 0, .2), 0 2px 2px 0 rgba(0, 0, 0, .14), 0 1px 5px 0 rgba(0, 0, 0, .12)
-}
-
-#range-picker .ng-daterangepicker .calendar .side-container .side-button.is-active,
-#range-picker .ng-daterangepicker .input-section .label-txt {
- color: #35afd5;
-}
-
-#range-picker .ng-daterangepicker .calendar .calendar-container .day-num.is-active,
-#range-picker .ng-daterangepicker .calendar .calendar-container .days .day-num:hover {
- background: #35afd5;
- background-clip: padding-box;
-
-}
-
-#range-picker .ng-daterangepicker .calendar .calendar-container .day-names,
-#range-picker .ng-daterangepicker .calendar .calendar-container .days {
- width: 310px;
-}
-
-#range-picker .ng-daterangepicker .calendar .day.is-within-range.is-first-weekday,
-#range-picker .ng-daterangepicker .calendar .day.is-within-range.is-last-weekday {
- background-clip: padding-box;
-}
-
-#range-picker .ng-daterangepicker .calendar .calendar-container .day.is-within-range {
- background: #e9f8fc
-}
-
-#range-picker .ng-daterangepicker .input-section .cal-icon svg path {
- fill: #35afd5;
-}
-
-#range-picker .ng-daterangepicker .input-section .value-txt {
- color: #718ba6;
-}
-
-#range-picker .ng-daterangepicker .input-section .value-txt.untouched,
-#range-picker .ng-daterangepicker .input-section .label-txt.untouched {
- color: #fff;
-}
-
-#range-picker .ng-daterangepicker .input-section .value-txt.untouched::after {
- content: 'Select date';
- position: absolute;
- top: 22px;
- left: 34px;
- color: #718ba6;
-}
diff --git a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.ts b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.ts
index 503ffaa..aa4a962 100644
--- a/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/reports/reporting/toolbar/toolbar.component.ts
@@ -61,31 +61,42 @@
}
ngOnInit() {
- if (localStorage.getItem('report_period')) {
- const availableRange = JSON.parse(localStorage.getItem('report_period'));
- this.availablePeriodFrom = availableRange.start_date;
- this.availablePeriodTo = availableRange.end_date; }
+ // if (localStorage.getItem('report_period')) {
+ // const availableRange = JSON.parse(localStorage.getItem('report_period'));
+ // this.availablePeriodFrom = availableRange.start_date;
+ // this.availablePeriodTo = availableRange.end_date;
+ // } else {
+
+ // }
this.subscriptions.add(this.healthStatusService.statusData.pipe(skip(1)).subscribe(result => {
this.healthStatus = result;
}));
+ this.setInitDatapickerConfig();
}
ngAfterViewInit() {
this.clearRangePicker();
}
+ private setInitDatapickerConfig() {
+ const labels = <NodeListOf<Element>>document.querySelectorAll('.label-txt');
+ const rangeLabels = <NodeListOf<Element>>document.querySelectorAll('.value-txt');
+ labels[0].innerHTML = 'From date';
+ labels[1].innerHTML = 'To date';
+ for (let label = 0; label < rangeLabels.length; ++label) {
+ rangeLabels[label].classList.add('untouched');
+ rangeLabels[label].classList.add('d-none');
+ }
+ }
+
setDateRange() {
const availableRange = JSON.parse(localStorage.getItem('report_period'));
-
this.availablePeriodFrom = availableRange.start_date;
this.availablePeriodTo = availableRange.end_date;
}
clearRangePicker(): void {
- const rangeLabels = <NodeListOf<Element>>document.querySelectorAll('.value-txt');
-
- for (let label = 0; label < rangeLabels.length; ++label)
- rangeLabels[label].classList.add('untouched');
+ this.setInitDatapickerConfig();
}
onChange(dateRange: string): void {
@@ -94,7 +105,11 @@
for (let label = 0; label < rangeLabels.length; ++label)
if (rangeLabels[label].classList.contains('untouched')) {
rangeLabels[label].classList.remove('untouched');
+ rangeLabels[label].classList.remove('d-none');
}
+ const labels = <NodeListOf<Element>>document.querySelectorAll('.label-txt');
+ labels[0].innerHTML = 'From:';
+ labels[1].innerHTML = 'To:';
const reportDateRange = dateRange.split('-');
this.setRangeOption.emit({
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.html
index bb769aa..c1e3be4 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.html
@@ -95,7 +95,7 @@
(click)="refreshBucket()"
[disabled]="allDisable"
>
- <i class="material-icons">autorenew</i>Refresh
+ <i class="material-icons refresh-icon">autorenew</i>Refresh
</button>
</div>
<p class="path"><span>Bucket path:</span>
@@ -190,7 +190,8 @@
</span>
</div>
<div class="size">{{file.object?.size | convertFileSize}}</div>
- <div class="date" *ngIf="!file.isDownloading">{{convertDate(file.object?.lastModifiedDate) | date: 'dd/MM/yyyy hh:mm:ss aa' }}</div>
+<!-- <div class="date" *ngIf="!file.isDownloading">{{convertDate(file.object?.lastModifiedDate) | date: 'dd/MM/yyyy hh:mm:ss aa' }}</div>-->
+ <div class="date" *ngIf="!file.isDownloading">{{file.object?.lastModifiedDate}}</div>
<div class="progress-wrapper" *ngIf="file.isDownloading">
<div class="progres">
<span class="progress-bar-text">{{file.progress || 0}}% Downloading...</span>
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.scss
index fbdf05b..2cf6731 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.scss
@@ -105,15 +105,20 @@
direction: rtl;
&-folder{
- padding-left: 5px;
+ padding-left: 20px;
padding-right: 5px;
color: #00bcd4;
cursor: pointer;
+
+ &:first-of-type{
+ padding-left: 5px;
+ }
}
&-icon i{
- transform: translateY(2px);
+ transform: translateY(1px);
font-size: 15px;
+ position: absolute;
}
}
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.ts
index 3ffcada..2be3dad 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-browser.component.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import { Component, OnInit, ViewChild, Inject } from '@angular/core';
+import {Component, OnInit, ViewChild, Inject, OnDestroy} from '@angular/core';
import { FormGroup, FormBuilder } from '@angular/forms';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { ToastrService } from 'ngx-toastr';
@@ -31,13 +31,16 @@
import {logger} from 'codelyzer/util/logger';
import {HttpEventType, HttpResponse} from '@angular/common/http';
import {CopyPathUtils} from '../../core/util/copyPathUtils';
+import {Subject} from 'rxjs';
+import {takeUntil} from 'rxjs/operators';
@Component({
selector: 'dlab-bucket-browser',
templateUrl: './bucket-browser.component.html',
styleUrls: ['./bucket-browser.component.scss']
})
-export class BucketBrowserComponent implements OnInit {
+export class BucketBrowserComponent implements OnInit, OnDestroy {
+ private unsubscribe$ = new Subject();
public addedFiles = [];
public folderItems = [];
public originFolderItems = [];
@@ -92,6 +95,11 @@
this.cloud = this.getCloud();
}
+ ngOnDestroy() {
+ this.unsubscribe$.next();
+ this.unsubscribe$.complete();
+ }
+
public getTokenValidTime() {
const token = JSON.parse(atob(this.storage.getToken().split('.')[1]));
return token.exp * 1000 - new Date().getTime();
@@ -99,7 +107,11 @@
private refreshToken() {
this.isTokenRefreshing = true;
- this.auth.refreshToken().subscribe(tokens => {
+ this.auth.refreshToken()
+ .pipe(
+ takeUntil(this.unsubscribe$)
+ )
+ .subscribe(tokens => {
this.storage.storeTokens(tokens);
this.isTokenRefreshing = false;
this.sendFile();
@@ -152,7 +164,11 @@
if (res) {
if (this.refreshTokenLimit > this.getTokenValidTime()) {
this.isTokenRefreshing = true;
- this.auth.refreshToken().subscribe(v => {
+ this.auth.refreshToken()
+ .pipe(
+ takeUntil(this.unsubscribe$)
+ )
+ .subscribe(v => {
this.uploadingQueue(files);
this.isTokenRefreshing = false;
});
@@ -164,7 +180,11 @@
} else {
if (this.refreshTokenLimit > this.getTokenValidTime()) {
this.isTokenRefreshing = true;
- this.auth.refreshToken().subscribe(v => {
+ this.auth.refreshToken()
+ .pipe(
+ takeUntil(this.unsubscribe$)
+ )
+ .subscribe(v => {
this.uploadingQueue(files);
this.isTokenRefreshing = false;
});
@@ -371,6 +391,9 @@
selected[0]['isDownloading'] = true;
this.folderItems.forEach(item => item.isSelected = false);
this.bucketBrowserService.downloadFile(`/${this.bucketName}/object/${path}/endpoint/${this.endpoint}/download`)
+ .pipe(
+ takeUntil(this.unsubscribe$)
+ )
.subscribe(event => {
if (event['type'] === HttpEventType.DownloadProgress) {
selected[0].progress = Math.round(100 * event['loaded'] / selected[0].object.size);
@@ -402,7 +425,11 @@
!res && this.clearSelection();
res && this.bucketBrowserService.deleteFile({
bucket: this.bucketName, endpoint: this.endpoint, 'objects': dataForServer
- }).subscribe(() => {
+ })
+ .pipe(
+ takeUntil(this.unsubscribe$)
+ )
+ .subscribe(() => {
this.bucketDataService.refreshBucketdata(this.bucketName, this.endpoint);
this.toastr.success('Objects successfully deleted!', 'Success!');
this.clearSelection();
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-data.service.ts b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-data.service.ts
index 5dae6b4..700005f 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-data.service.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/bucket-data.service.ts
@@ -30,8 +30,13 @@
export class BucketDataService {
public _bucketData = new BehaviorSubject<any>(null);
public serverData: any = [];
- get data(): TodoItemNode[] { return this._bucketData.value; }
+
+ get data(): TodoItemNode[] {
+ return this._bucketData.value;
+ }
+
emptyFolder = null;
+
constructor(
private bucketBrowserService: BucketBrowserService,
) {
@@ -39,21 +44,25 @@
public refreshBucketdata(bucket, endpoint) {
let backetData = [];
- this.bucketBrowserService.getBucketData(bucket, endpoint).subscribe(v => {
- const copiedData = JSON.parse(JSON.stringify(v));
- this.serverData = v;
- if (this.emptyFolder) {
- copiedData.unshift(this.emptyFolder);
- }
- backetData = this.convertToFolderTree(copiedData);
- const data = this.buildFileTree({[bucket]: backetData}, 0);
- this._bucketData.next(data);
- });
- // this.serverData = array;
- // backetData = this.convertToFolderTree(array);
+ // this.bucketBrowserService.getBucketData(bucket, endpoint).subscribe(v => {
+ // const copiedData = JSON.parse(JSON.stringify(v));
+ // this.serverData = v;
+ // if (this.emptyFolder) {
+ // copiedData.unshift(this.emptyFolder);
+ // }
+ //
+ // backetData = this.convertToFolderTree(copiedData);
// const data = this.buildFileTree({[bucket]: backetData}, 0);
// this._bucketData.next(data);
+ // });
+ if (this.emptyFolder) {
+ array.unshift(this.emptyFolder);
+ }
+ this.serverData = array;
+ backetData = this.convertToFolderTree(array);
+ const data = this.buildFileTree({[bucket]: backetData}, 0);
+ this._bucketData.next(data);
}
public buildFileTree(obj: {[key: string]: any}, level: number): TodoItemNode[] {
@@ -121,6 +130,7 @@
if (!pointer.obj) {
pointer.obj = object;
}
+
});
};
@@ -138,4 +148,5 @@
}
return finalData;
}
+
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.html
index 8d294a5..0da2a14 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.html
@@ -1,3 +1,22 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
<mat-tree-node
*matTreeNodeDef="let node"
@@ -13,7 +32,7 @@
[matTooltipClass]="'bucket-item-tooltip'"
>{{node.name}}</div>
</mat-tree-node>
- <mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding matTreeNodePaddingIndent="17">
+ <mat-tree-node *matTreeNodeDef="let node;when: hasChild" matTreeNodePadding matTreeNodePaddingIndent="17">
<button mat-icon-button matTreeNodeToggle
[attr.aria-label]="'toggle ' + node.name">
<mat-icon class="mat-icon-rtl-mirror">
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.scss
index fd06d7a..5bd774a 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.scss
@@ -1,4 +1,21 @@
-
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
.folder{
padding-left: 5px;
max-width: 350px;
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.ts
index ed222f6..cc8f5d8 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/buckets-tree/bucket-tree.component.ts
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {FlatTreeControl} from '@angular/cdk/tree';
import {MatTreeFlatDataSource, MatTreeFlattener} from '@angular/material/tree';
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.html
index 2e8115f..6879271 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.html
@@ -1,3 +1,22 @@
+<!--
+ ~ Licensed to the Apache Software Foundation (ASF) under one
+ ~ or more contributor license agreements. See the NOTICE file
+ ~ distributed with this work for additional information
+ ~ regarding copyright ownership. The ASF licenses this file
+ ~ to you under the Apache License, Version 2.0 (the
+ ~ "License"); you may not use this file except in compliance
+ ~ with the License. You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing,
+ ~ software distributed under the License is distributed on an
+ ~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ ~ KIND, either express or implied. See the License for the
+ ~ specific language governing permissions and limitations
+ ~ under the License.
+ -->
+
<mat-tree [dataSource]="dataSource" [treeControl]="treeControl">
<mat-tree-node
@@ -16,7 +35,7 @@
<mat-label>New folder</mat-label>
<input matInput #itemValue [formControl]="folderFormControl" [errorStateMatcher]="matcher">
<mat-error *ngIf="!folderFormControl.hasError('required') && !folderFormControl.hasError('isDuplicate')">
- The folder name can only contain Latin letters, numbers and special characters except for #, ?, /, \, "
+ The folder name can only contain Latin letters, numbers and special characters except for #, ?, /, \, %"
</mat-error>
<mat-error *ngIf="folderFormControl.hasError('required')">
Folder name is <strong>required</strong>
@@ -39,7 +58,7 @@
</form>
</mat-tree-node>
- <mat-tree-node *matTreeNodeDef="let node; when: hasChild" matTreeNodePadding matTreeNodePaddingIndent="17" [ngClass]="{'cursor-not-allow': bucketDataService.emptyFolder}">
+ <mat-tree-node *matTreeNodeDef="let node; when: hasChild" matTreeNodePadding matTreeNodePaddingIndent="17" [ngClass]="{'cursor-not-allow': bucketDataService.emptyFolder}">
<button mat-icon-button matTreeNodeToggle
[attr.aria-label]="'toggle ' + node.filename" [ngClass]="{'not-allowed': bucketDataService.emptyFolder}">
<mat-icon class="mat-icon-rtl-mirror" [ngClass]="{'active-item': (selectedFolder === node && !bucketDataService.emptyFolder)}">
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.scss
index 22c36d0..fd962ad 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.scss
@@ -1,3 +1,21 @@
+/*!
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
.folder{
padding-left: 5px;
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.ts
index 1684b26..cd7d199 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/bucket-browser/folder-tree/folder-tree.component.ts
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import {Component, Output, EventEmitter, OnDestroy, Input, OnInit} from '@angular/core';
import {FlatTreeControl} from '@angular/cdk/tree';
import {MatTreeFlatDataSource, MatTreeFlattener} from '@angular/material/tree';
@@ -65,7 +84,7 @@
if (this.selectedFolder && !this.bucketDataService.emptyFolder) {
setTimeout(() => {
const element = document.querySelector('.folder-item-line.active-item');
- element && element.scrollIntoView({ block: 'center', behavior: 'smooth' });
+ element && element.scrollIntoView({ block: 'start', behavior: 'smooth' });
}, 0);
} else if (this.selectedFolder && this.bucketDataService.emptyFolder) {
setTimeout(() => {
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resource-create-dialog/computational-resource-create-dialog.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resource-create-dialog/computational-resource-create-dialog.component.html
index 94265fd..62ab6af 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resource-create-dialog/computational-resource-create-dialog.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resource-create-dialog/computational-resource-create-dialog.component.html
@@ -149,7 +149,7 @@
<label class="label">
<input #preemptibleNode type="checkbox" (change)="selectPreemptibleNodes($event)" />
<span>Preemptible node</span>
- <span class="align" *ngIf="preemptible?.nativeElement['checked'] || false"> count</span>
+ <span class="align" [hidden]="!preemptible?.nativeElement['checked']"> count</span>
</label>
<div *ngIf="preemptible?.nativeElement['checked']" class="preemptible-details control"
[ngClass]="{ show: preemptible?.nativeElement['checked'] || false}">
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resource-create-dialog/computational-resource-create-dialog.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resource-create-dialog/computational-resource-create-dialog.component.ts
index 8968a3a..9f319cc 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resource-create-dialog/computational-resource-create-dialog.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resource-create-dialog/computational-resource-create-dialog.component.ts
@@ -134,7 +134,7 @@
public createComputationalResource(data) {
this.model.createComputationalResource(data, this.selectedImage, this.notebook_instance, this.spotInstance, this.PROVIDER.toLowerCase())
.subscribe((response: any) => {
- if (response.status === HTTP_STATUS_CODES.OK) this.dialogRef.close();
+ if (response.status === HTTP_STATUS_CODES.OK) this.dialogRef.close(true);
}, error => this.toastr.error(error.message, 'Oops!'));
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resources-list/computational-resources-list.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resources-list/computational-resources-list.component.scss
index 2df7536..582f51f 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resources-list/computational-resources-list.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/computational/computational-resources-list/computational-resources-list.component.scss
@@ -17,10 +17,13 @@
* under the License.
*/
+ :host{
+ width:100%;
+ }
+
.source {
.no-details {
color: #bdc9d5;
- padding-left: 10px;
}
.resource-wrap {
@@ -34,7 +37,6 @@
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
- padding-left: 10px;
.detailed-link {
color: #35afd5;
@@ -109,23 +111,23 @@
}
}
}
- @media screen and (max-width: 1520px) {
- .resources,
- managment {
- .source {
- .resource-wrap {
- .resource-name {
- width: 42%;
- }
-
- .resource-status {
- width: 43%;
- }
-
- .resource-actions {
- width: 15%;
- }
- }
- }
- }
- }
+ //@media screen and (max-width: 1520px) {
+ // .resources,
+ // managment {
+ // .source {
+ // .resource-wrap {
+ // .resource-name {
+ // width: 42%;
+ // }
+ //
+ // .resource-status {
+ // width: 43%;
+ // }
+ //
+ // .resource-actions {
+ // width: 15%;
+ // }
+ // }
+ // }
+ // }
+ //}
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/ami-create-dialog/ami-create-dialog.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/ami-create-dialog/ami-create-dialog.component.ts
index e783951..92362f7 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/ami-create-dialog/ami-create-dialog.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/ami-create-dialog/ami-create-dialog.component.ts
@@ -57,7 +57,7 @@
public assignChanges(data) {
this._userResource.createAMI(data).subscribe(
- response => response.status === HTTP_STATUS_CODES.ACCEPTED && this.dialogRef.close(),
+ response => response.status === HTTP_STATUS_CODES.ACCEPTED && this.dialogRef.close(true),
error => this.toastr.error(error.message || `Image creation failed!`, 'Oops!'));
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/cost-details-dialog/cost-details-dialog.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/cost-details-dialog/cost-details-dialog.component.html
index 17fe71a..d916d94 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/cost-details-dialog/cost-details-dialog.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/cost-details-dialog/cost-details-dialog.component.html
@@ -33,7 +33,7 @@
</table>
<div class="billing-detail content-box">
<mat-list>
- <mat-list-item class="list-header">
+ <mat-list-item class="list-header" [ngClass]="{'pr-3': notebook.billing.report_lines.length > 6}">
<div class="resource-name ellipsis" [ngClass]="{ 'wide-name-field' : provider === 'azure' }">Name</div>
<div class="service">Product</div>
<!-- <div class="resource-type" *ngIf="provider === 'aws'">Type</div>-->
@@ -55,6 +55,7 @@
<div class="cost-currency">{{ item.cost }} {{ item.currency }}</div>
</mat-list-item>
</div>
+
</mat-list>
<div class="total">
<strong>Total: </strong>{{ notebook.cost }} {{ notebook.currency_code }}</div>
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/cost-details-dialog/cost-details-dialog.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/cost-details-dialog/cost-details-dialog.component.scss
index 18998ea..a9d081a 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/cost-details-dialog/cost-details-dialog.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/cost-details-dialog/cost-details-dialog.component.scss
@@ -67,14 +67,13 @@
}
}
-
.scrolling-content {
max-height: 285px;
overflow-y: auto;
}
.mat-list-item-content {
- font-size: 15px !important;
+ font-size: 14px !important;
justify-content: space-between;
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.html
index 5d53b59..654f29b 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.html
@@ -28,13 +28,14 @@
<p class=" message">Cannot install libraries: Exploratory
<strong>{{ notebook?.name }}</strong> is not running</p>
</div>
- <div class="loading-block" *ngIf="!libs_uploaded && uploading && data.status === 'running'">
+ <div *ngIf="notebook?.status === 'running'" class="top-wrapper">
+ <div class="loading-block" *ngIf="!libs_uploaded && uploading && data.status === 'running'">
<div class="uploading">
<p>Please wait until DLab loads full list of available libraries for you...</p>
<img src="assets/img/gif-spinner.gif" alt="loading">
</div>
</div>
- <div *ngIf="notebook?.status === 'running' && !uploading" class="lib-view-wrap">
+ <div *ngIf="notebook?.status === 'running' && !uploading" class="lib-view-wrap">
<div class="search-box">
<div class="search-form">
<div>
@@ -48,65 +49,127 @@
<label class="label">Select group</label>
<div class="control">
<dropdown-list #groupSelect (selectedItem)="onUpdate($event)" (emitClick)="emitClick()"></dropdown-list>
- <span class="error-message" *ngIf="!group && libSearch.value">Group field is required. Please choose appropriate group.</span>
+ <span class="error-message" *ngIf="!group && libSearch?.value">Group field is required. Please choose appropriate group.</span>
</div>
</div>
</div>
- <p class="other-message">
- <span *ngIf="group === 'others'">Other group can include libs from Python 2 and Python 3 groups</span>
- </p>
- <div class="search">
- <mat-form-field class="chip-list">
- <input
- type="text"
- [placeholder]="group === 'java' ?
- 'Enter library name in <groupId>:<artifactId>:<versionId> format' :
- 'Enter library name in <name>:<version> format(version is not required)'"
- matInput
- #trigger="matAutocompleteTrigger"
- [formControl]="libSearch"
- [value]="query"
- [matAutocomplete]="auto"
- >
-<!-- <span class="add-icon" [matTooltip]="(isInSelectedList || isInstalled) ? 'Current library dosen\'t exist' : 'You have already added or installed current library'"-->
-<!-- matTooltipPosition="above"-->
-<!-- [matTooltipDisabled] = "isLibExist && (isInSelectedList || isInstalled)"-->
- <span class="add-icon">
- <button mat-icon-button class="btn" [disabled]="!isLibExist || query.length < 1 ||
- isDuplicated({name: query.slice(0, query.indexOf(':')), version: query.slice(query.indexOf(':') + 1) || 'N/A'})" (click)="addLibrary(query);$event.stopPropagation()">
- <mat-icon matSuffix >add</mat-icon>
- </button>
- </span>
-
+ <div class="m-top-20" *ngIf="group !== 'java'; else javaGroup">
+ <div class="control-group constol-select">
+ <label class="label">Library name</label>
+ <div class="control control-relative">
+ <span class="other-message" *ngIf="group === 'others'">Other group can include libs from Python 2 and Python 3 groups</span>
+ <input
+ type="text" [placeholder]="'Enter library name'"
+ [disabled]="!group"
+ [matAutocomplete]="auto"
+ [formControl]="libSearch"
+ #trigger="matAutocompleteTrigger"
+ (keyup.enter)="addLibrary(lib)"
+ class="library-input"
+ >
+ </div>
<mat-autocomplete #auto="matAutocomplete" class="suggestions" >
- <ng-template ngFor let-item [ngForOf]="filteredList" let-i="index" *ngIf="query.indexOf(':') === -1">
- <mat-option [ngClass]="{ 'not-allowed': isDuplicated(item) }">
- <div class="option" (click)="selectLibrary(item)">
- <a *ngIf="!isDuplicated(item)">
- <span [innerHTML]="item.name | highlight:query"></span>
-<!-- <span *ngIf="item.version && item.version !== 'N/A'">{{ item.version }}</span>-->
+ <ng-template ngFor let-item [ngForOf]="filteredList" let-i="index">
+ <mat-option>
+ <div class="option" (click)="selectLibrary(item);$event.stopPropagation()" [ngClass]="{'not-allow': item.isInSelectedList}">
+ <a *ngIf="!item.isInSelectedList">
+ <span [innerHTML]="item.name | highlight:lib.name"></span>
</a>
- <span *ngIf="isInSelectedList || isInstalled">{{ item.name }}
- <span *ngIf="item.version && item.version !== 'N/A'">{{ item.version }}</span>
- </span>
-
- <strong *ngIf="isInSelectedList">selected
+ <span *ngIf="item.isInSelectedList">{{ item.name }}</span>
+ <strong *ngIf="item.isInSelectedList">selected
<i class="material-icons">done</i>
</strong>
- <strong *ngIf="isInstalled">installed
+ <strong *ngIf="item.isInstalled && !item.isInSelectedList">installed
<i class="material-icons">done</i>
</strong>
</div>
</mat-option>
</ng-template>
- <mat-option *ngIf="model.isEmpty(filteredList) && !validity_format && query.indexOf(':') === -1">
+ <mat-option *ngIf="model.isEmpty(filteredList) && !validity_format">
<span class="configuring">No matches found</span>
</mat-option>
<mat-option *ngIf="validity_format?.length > 0">
- <span class="configuring" *ngIf="query.indexOf(':') === -1">{{ validity_format }}</span >
+ <span class="configuring" >{{ validity_format }}</span >
</mat-option>
</mat-autocomplete>
- </mat-form-field>
+ </div>
+ <div class="control-group control-select">
+ <label class="label">Library version</label>
+ <div class="control control-relative">
+ <input
+ type="text"
+ class="library-input"
+ [placeholder]="'Enter library version (optional)'"
+ [(ngModel)]="lib.version"
+ [disabled]="!lib.name"
+ (keyup.enter)="addLibrary(lib)"
+ >
+ <span class="plus-icon"
+ [ngClass]="{'not-allow': !this.selectedLib || this.selectedLib?.isInSelectedList}"
+ matTooltip="Library is in selected list" matTooltipPosition="above" [matTooltipDisabled]="!this.selectedLib?.isInSelectedList"
+ >
+ <mat-icon (click)="addLibrary(lib)" [ngClass]="{'not-allowed': !this.selectedLib || this.selectedLib?.isInSelectedList }">add</mat-icon>
+ </span>
+ </div>
+ </div>
+ </div>
+
+ <ng-template #javaGroup>
+ <div class="m-top-20">
+ <div class="control-group constol-select java-library-search">
+ <label class="label">Library</label>
+ <div class="control control-relative">
+<!-- <span class="other-message" *ngIf="lib.name?.length && !this.selectedLib">groupId:artifactId:versionId</span>-->
+ <input
+ type="text" [placeholder]="'Enter library name in <groupId>:<artifactId>:<versionId> format'"
+ class="library-input"
+ [disabled]="!group"
+ [matAutocomplete]="auto"
+ [formControl]="libSearch"
+ #trigger="matAutocompleteTrigger"
+ (keyup.enter)="addLibrary(lib)"
+ >
+ <span
+ class="plus-icon"
+ [ngClass]="{'not-allow': !this.selectedLib || this.selectedLib?.isInSelectedList}"
+ matTooltip="Library is in selected list" matTooltipPosition="above" [matTooltipDisabled]="!this.selectedLib?.isInSelectedList"
+ >
+ <mat-icon (click)="addLibrary(lib)" (keyup.enter)="addLibrary(lib)" [ngClass]="{'not-allowed': !this.selectedLib || this.selectedLib?.isInSelectedList}">add</mat-icon>
+ </span>
+ </div>
+ <mat-autocomplete #auto="matAutocomplete" class="suggestions">
+ <ng-template ngFor let-item [ngForOf]="filteredList" let-i="index">
+ <mat-option >
+ <div class="option" (click)="selectLibrary(item);$event.stopPropagation()" [ngClass]="{'not-allow': item.isInSelectedList}">
+ <a *ngIf="!item.isInSelectedList">
+ <span [innerHTML]="item.name + ':' + item.version | highlight:item.name">
+ <span>{{ item.version }}</span>
+ </span>
+ </a>
+ <span *ngIf="item.isInSelectedList">{{ item.name }}
+ <span *ngIf="item.version && item.version !== 'N/A'">{{ item.version }}</span>
+ </span>
+ <strong *ngIf="item.isInSelectedList">selected
+ <i class="material-icons">done</i>
+ </strong>
+ <strong *ngIf="item.isInstalled && !item.isInSelectedList">installed
+ <i class="material-icons">done</i>
+ </strong>
+ </div>
+ </mat-option>
+ </ng-template>
+ <mat-option *ngIf="model.isEmpty(filteredList) && !validity_format">
+ <span class="configuring">No matches found</span>
+ </mat-option>
+ <mat-option *ngIf="validity_format?.length > 0">
+ <span class="configuring" >{{ validity_format }}</span >
+ </mat-option>
+ </mat-autocomplete>
+ </div>
+ </div>
+ </ng-template>
+
+ <div class="search">
<div class="list-selected list-container" id='scrolling'>
<mat-chip-list *ngIf="model.selectedLibs.length && libs_uploaded">
<mat-chip *ngFor="let item of model.selectedLibs">
@@ -121,6 +184,8 @@
</div>
</div>
</div>
+ </div>
+
<div class="libs-info">
<mat-list>
<mat-list-item class="list-header">
@@ -161,11 +226,17 @@
</mat-list-item>
<ng-container *ngIf="filtered" >
- <mat-list-item class="lib-col filter-row">
- <th class="lib-name lib-input">
- <input placeholder="Filter by library name" [value]="filterModel.name" (input)="filterModel.name = $event.target['value']" type="text" class="form-control filter-field "/>
+ <mat-list-item class="filter-row">
+ <th class="lib-name filter-col">
+ <input
+ placeholder="Filter by library name"
+ [value]="filterModel.name"
+ (input)="filterModel.name = $event.target['value']"
+ type="text"
+ class="form-control filter-field"
+ />
</th>
- <th class="lib-group lib-col">
+ <th class="lib-group filter-col">
<multi-select-dropdown
(selectionChange)="onFilterUpdate($event)"
[items]="this.filterConfiguration.group"
@@ -174,7 +245,7 @@
>
</multi-select-dropdown>
</th>
- <th class="lib-destination lib-col">
+ <th class="lib-destination filter-col">
<multi-select-dropdown
(selectionChange)="onFilterUpdate($event)"
[items]="this.filterConfiguration.resource"
@@ -183,7 +254,7 @@
>
</multi-select-dropdown>
</th>
- <th class="lib-resource-type lib-col">
+ <th class="lib-resource-type filter-col">
<multi-select-dropdown
(selectionChange)="onFilterUpdate($event)"
[items]="this.filterConfiguration.resourceType"
@@ -192,12 +263,13 @@
>
</multi-select-dropdown>
</th>
- <th class="lib-status lib-col">
+ <th class="lib-status filter-col">
<multi-select-dropdown
(selectionChange)="onFilterUpdate($event)"
[items]="this.filterConfiguration.status"
[type]="'status'"
- [model]="this.filterModel.status">
+ [model]="this.filterModel.status"
+ >
</multi-select-dropdown>
</th>
<ng-container matColumnDef="action-filter" stickyEnd>
@@ -208,7 +280,7 @@
</button>
<button mat-icon-button class="btn apply" (click)="filterLibs()">
- <i class="material-icons" [ngClass]="{'not-allowed': filterModel.length === 0}">done</i>
+ <i class="material-icons" [ngClass]="{'not-allowed': filterModel['length'] === 0}">done</i>
</button>
</div>
</th>
@@ -222,9 +294,11 @@
<!-- </div>-->
<ng-container *ngFor="let lib of filtredNotebookLibs">
<mat-list-item class="table-item">
- <div class="lib-name ellipsis">
- <strong>{{ lib.name }}</strong>
- <span *ngIf="lib.version && lib.version !== 'N/A'">{{ lib.version }}</span>
+ <div class="lib-name lib-name-col ellipsis" >
+ <span [matTooltip]="lib.name + ' ' + lib.version" matTooltipPosition="above" class="lib-name-wrapper">
+ <span class="stong" >{{ lib.name }}</span>
+ <span *ngIf="lib.version && lib.version !== 'N/A'">{{ lib.version }}</span>
+ </span>
</div>
<div class="lib-group-col">{{ groupsListMap[lib.group] }}</div>
<div class="st-group">
@@ -232,62 +306,40 @@
<div class="wrap-col">
<div class="lib-destination-col">{{ item.resource }}</div>
<div class="lib-resource-type-col">{{ item.resourceType }}</div>
- <div class="lib-status-col" ngClass="{{ item.status.toLowerCase() || 'failed' }}">{{ item.status }}
- <div class="warn-action" *ngIf="(item.status === 'failed' || item.status === 'invalid version') && notebook?.status === 'running'">
+ <div class="lib-status-col" ngClass="{{ item.status.toLowerCase() || 'installation_error' }}">{{ item.status.replace('_', ' ') }}
+ <div class="warn-action" *ngIf="(item.status === 'installation_error' || item.status.toLowerCase() === 'invalid_version' || item.add_pkgs?.length) && notebook?.status === 'running'">
<div *ngIf="!item.available_versions">
- <span *ngIf="!installingInProgress" (click)="reinstallLibrary(item, lib)" matTooltip="Retry installation" matTooltipPosition="above">
+ <span *ngIf="!installingInProgress && item.status === 'installation_error'" (click)="reinstallLibrary(item, lib)" matTooltip="Retry installation" matTooltipPosition="above">
<i class="material-icons">replay</i>
</span>
- <span class="not-allowed" *ngIf="installingInProgress" matTooltip="You can't reinstall library until previous process will be completed"
+ <span class="not-allow" *ngIf="installingInProgress && item.status === 'installation_error'" matTooltip="Please wait until lib installation completes"
matTooltipPosition="above">
- <i class="material-icons">replay</i>
+ <i class="material-icons not-allowed">replay</i>
</span>
</div>
- <div *ngIf="item.status === 'failed' && item.error" class="lib-error" (click)="showErrorMessage(item)">
- <i class="material-icons">error_outline</i>
+ <div *ngIf="item.status === 'installation_error' && item.error" class="lib-error" (click)="showErrorMessage(item)" matTooltip="Show error message" matTooltipPosition="above">
+ <i class="material-icons terminated">error_outline</i>
</div>
<div class="lib-error"
- *ngIf="item.status === 'invalid version' && item.available_versions?.length" class="lib-error"
+ *ngIf="item.status.toLowerCase() === 'invalid_version' && item.available_versions?.length"
(click)="openLibInfo(item, 'available');$event.stopPropagation()"
matTooltip="Show available version" matTooltipPosition="above"
>
- <i class="material-icons terminated">error_outline</i>
+ <i class="material-icons">error_outline</i>
</div>
- </div>
- <div class="warn-action" matTooltip="Show installed dependency" matTooltipPosition="above" *ngIf="item.add_pkgs?.length">
+ <div matTooltip="Show installed dependency" matTooltipPosition="above" *ngIf="item.add_pkgs?.length">
<span class="info-icon" (click)="openLibInfo(item, 'added');$event.stopPropagation() ">
<i class="material-icons">info</i>
</span>
+ </div>
</div>
+
</div>
</div>
</ng-template>
</div>
</mat-list-item>
-
-<!-- <mat-list-item *ngIf="isLibInfoOpened[lib.name]">-->
-<!-- <div class="lib-info">-->
-<!-- <ul class="libs-version">-->
-
-<!-- <li class="dependency-list-header">-->
-<!-- List of available version:-->
-<!-- </li>-->
-
-<!--<!– <div class="scrolling-content delete-list" id="scrolling">–>-->
-
-<!-- <li *ngFor="let object of [1,2,3]" class="delete-item list-item">-->
-<!-- <!– <div class="object">–>-->
-<!-- {{lib.name+lib.version}}-->
-<!-- <!– </div>–>-->
-<!-- <!– <div class="size">v2.3.4</div>–>-->
-<!-- <button mat-raised-button type="button" class="butt action">Install</button>-->
-<!-- </li>-->
-
-<!--<!– </div>–>-->
-<!-- </ul>-->
-<!-- </div>-->
-<!-- </mat-list-item>-->
</ng-container>
<div *ngIf="!filtredNotebookLibs.length && notebookLibs?.length" class="scrollingList info message">
<p>No matches found</p>
@@ -299,8 +351,16 @@
</mat-list>
</div>
<div class="m-top-15 actions" *ngIf="!uploading && notebook?.status === 'running'">
- <button mat-raised-button type="button" class="butt action" (click)="dialogRef.close()">Close</button>
- <button mat-raised-button type="submit" class="butt butt-success action" (click)="model.confirmAction()" [disabled]="!model.selectedLibs.length || installingInProgress || !destination">Install</button>
+ <button mat-raised-button type="button" class="butt action close-btn" (click)="dialogRef.close()">Close</button>
+ <span matTooltip="Please wait until lib installation completes" [matTooltipDisabled]="!installingInProgress" matTooltipPosition="above">
+ <button mat-raised-button type="submit"
+ class="butt butt-success action install-btn"
+ (click)="model.confirmAction()"
+ [disabled]="!model.selectedLibs.length || installingInProgress || !destination"
+ >
+ Install
+ </button>
+ </span>
</div>
</div>
</div>
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.scss
index fd769f0..2b95c0b 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.scss
@@ -65,6 +65,10 @@
height: 30%;
}
+.top-wrapper{
+ height: 285px;
+}
+
.install-libraries {
height: 100%;
padding-bottom: 130px;
@@ -78,7 +82,6 @@
}
.info {
- height: 40%;
display: flex;
flex-direction: row;
align-items: center;
@@ -87,19 +90,21 @@
.mat-list-item {
height: auto !important;
+ font-family: "Open Sans", sans-serif;
+ font-weight: 400;
.mat-list-item-content {
height: auto !important;
min-height: 54px !important;
border-bottom: 1px solid #edf1f5;
padding-right: 10px;
+ padding-left: 0;
}
}
.lib-view-wrap {
display: flex;
flex-direction: column;
- height: 40%;
}
.error {
@@ -109,17 +114,34 @@
.uploading {
margin: 0 auto;
}
+
+ .list-selected {
+ padding: 10px;
+ font-family: 'Open Sans', sans-serif;
+ height: 130px;
+ overflow-y: auto;
+
+ h4 {
+ margin-bottom: 20px;
+ font-size: 14px;
+ text-align: center;
+ font-weight: 400;
+ color: #718ba6;
+ }
+
+ mat-chip-list .mat-chip-list-wrapper {
+ overflow-y: auto;
+ padding: 3px;
+ }
+ }
}
+
.list-item{
display: flex;
width: 100%;
padding-left: 20px;
}
-.mat-list-base {
- //padding: 40px 30px;
-}
-
.object {
width: 70%;
display: flex;
@@ -130,6 +152,7 @@
.size {
width: 30%;
}
+
.scrolling-content.delete-list {
max-height: 200px;
overflow-y: auto;
@@ -140,7 +163,7 @@
width: 100%;
justify-content: center;
color: #35afd5;
- padding: 15px;
+ padding: 14px;
}
ul.resources{
@@ -148,8 +171,6 @@
}
.dependency-list-header {
- //border-top: 1px solid #edf1f5;
- //border-bottom: 1px solid #edf1f5;
color: #577289;
width: 100%;
padding: 15px 0 5px 0;
@@ -184,27 +205,43 @@
width: 50%;
padding-bottom: 0;
+ &.java-library-search{
+ width: 100%;
+
+ .label{
+ width: 10%;
+ }
+
+ .control{
+ width: 85%;
+ }
+ }
+
+ .control{
+ width: 70%;
+
+ input{
+ font-size: 15px;
+ padding-left: 15px;
+ }
+
+ .dropdown-list button {
+ font-size: 14px;
+ padding-top: 0;
+ }
+ }
+
.label {
width: 20%;
}
}
- .other-message{
- height: 22px;
- display: flex;
- align-items: center;
-
- span{
- font-size: 12px;
- color: $link-color;
- }
- }
-
.search {
flex-grow: 1;
padding-bottom: 0;
flex-direction: column;
box-shadow: 0 3px 1px -2px rgba(0, 0, 0, .2), 0 2px 2px 0 rgba(0, 0, 0, .14), 0 1px 5px 0 rgba(0, 0, 0, .12);
+ margin-top: 25px;
.mat-form-field-flex {
padding-left: 15px;
@@ -214,9 +251,13 @@
width: 100%;
overflow-y: auto;
- .mat-form-field {
+
+ &.mat-form-field {
width: 100%;
- padding: 5px 20px;
+
+ .mat-form-field-infix{
+ display: flex;
+ }
}
.mat-input-flex {
@@ -282,29 +323,9 @@
}
}
-.list-selected {
- padding: 0 5px;
- font-family: 'Open Sans', sans-serif;
- height: 130px;
- overflow-y: auto;
-
- h4 {
- margin-bottom: 20px;
- font-size: 14px;
- text-align: center;
- font-weight: 400;
- color: #718ba6;
- }
-
- mat-chip-list .mat-chip-list-wrapper {
- overflow-y: auto;
- padding: 3px;
- }
-}
-
.mat-list-item {
color: #718ba6 !important;
- font-size: 14px;
+ font-size: 13px !important;
font-weight: 300;
}
@@ -319,10 +340,6 @@
line-height: 40px;
}
-.list-header+div{
- padding-left: 5px;
-}
-
.mat-dialog-container {
position: relative;
}
@@ -331,8 +348,20 @@
padding: 0 20px;
display: flex;
flex: 1 1 auto;
- min-height: 0px;
- height: 50%;
+ min-height: 0;
+
+ .filter-row {
+ .filter-col{
+ padding-left: 0;
+ &.lib-name{
+ padding-left: 5px;
+ .filter-field{
+ padding-left: 15px;
+ }
+ }
+ }
+ }
+
.mat-list {
width: 100%;
@@ -341,7 +370,7 @@
max-height: 300px;
height: 80%;
overflow-y: auto;
- overflow-x: hidden;
+ overflow-x: overlay;
.info {
p {
@@ -351,18 +380,20 @@
}
}
}
- .lib-col{
- padding-left: 4px;
- }
.lib-name {
width: 27%;
- &.lib-input{
+ padding-right: 10px;
+ padding-left: 20px;
+ &-col{
+ display: flex;
}
.lib-name-wrapper{
+ overflow: hidden;
display: block;
+ text-overflow: ellipsis;
}
strong {
@@ -373,21 +404,26 @@
.lib-group,
.lib-destination {
width: 17%;
- padding-left: 6px;
+ padding-left: 15px;
+ padding-right: 10px;
}
.lib-status {
width: 17%;
- padding-left: 6px;
+ padding-left: 15px;
+ padding-right: 10px;
}
.lib-resource-type {
width: 17%;
- padding-left: 6px;
+ padding-left: 15px;
+ padding-right: 10px;
}
+
.lib-group-col {
width: 17%;
- padding-left: 8px;
+ padding-left: 17px;
+ padding-right: 10px;
}
.st-group {
@@ -401,20 +437,19 @@
.lib-destination-col {
width: 33.3%;
- padding-left: 8px;
+ padding-left: 15px;
}
.lib-resource-type-col {
width: 33.3%;
color: #36afd5;
- padding-left: 8px;
+ padding-left: 15px;
}
.lib-status-col {
position: relative;
width: 33.3%;
- padding-left: 8px;
-
+ padding-left: 15px;
.warn-action {
position: absolute;
@@ -457,15 +492,18 @@
padding-bottom: 3px;
}
-.mat-dialog-container.mat-dialog-container .install-libraries#dialog-box {
+.mat-dialog-container.mat-dialog-container .install-libraries#dialog-box {
.mat-header-cell{
padding: 0;
border: none;
+ position: absolute;
+ right: 10px;
}
.filter-actions {
display: flex;
margin-left: 6px;
+
.btn {
padding: 6px;
height: auto;
@@ -476,6 +514,7 @@
display: flex;
}
}
+
.reset{
&:hover {
border-color: #f1696e;
@@ -483,6 +522,7 @@
color: #f1696e;
}
}
+
.apply:hover {
border-color: #49af38;
background: #f9fafb;
@@ -492,8 +532,10 @@
}
.install-libraries .dropdown-multiselect .list-menu li {
+
a{
font-size: 13px;
+
&.list-item{
color: #4a5c89 !important;
}
@@ -532,12 +574,14 @@
.lib-info{
width: 100%;
+
.delete-item {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
padding: 5px 10px;
+
.butt.action{
line-height: 26px;
}
@@ -546,7 +590,37 @@
.btn{
line-height: 26px;
+
+ &.install-btn{
+ margin-left: 0;
+ }
}
+
+.control-relative{
+ position: relative;
+
+ .plus-icon {
+ position: absolute;
+ right: -40px;
+ top: 5px;
+ color: #35afd5;
+ font-size: 27px;
+ cursor: pointer;
+
+ &.not-allow {
+ color: lightgray;
+ }
+ }
+
+ .other-message{
+ position: absolute;
+ font-size: 12px;
+ color: $link-color;
+ top: 40px;
+ left: 12px;
+ }
+}
+
@media screen and (min-width: 1281px) {
.libs-info {
height: 60%;
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.ts
index 2f22fb9..94c7009 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.component.ts
@@ -22,12 +22,13 @@
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { FormControl } from '@angular/forms';
import { ToastrService } from 'ngx-toastr';
-import { debounceTime } from 'rxjs/operators';
+import {debounceTime, take, takeUntil} from 'rxjs/operators';
import { InstallLibrariesModel } from './install-libraries.model';
import { LibrariesInstallationService } from '../../../core/services';
import { SortUtils, HTTP_STATUS_CODES } from '../../../core/util';
import {FilterLibsModel} from './filter-libs.model';
+import {Subject} from 'rxjs';
interface Library {
name: string;
@@ -42,22 +43,18 @@
encapsulation: ViewEncapsulation.None
})
export class InstallLibrariesComponent implements OnInit, OnDestroy {
-
+ private unsubscribe$ = new Subject();
public model: InstallLibrariesModel;
public notebook: any;
- public filteredList: any;
+ public filteredList: any = [];
public groupsList: Array<string>;
public notebookLibs: Array<any> = [];
- public notebookFailedLibs: Array<any> = [];
public loadLibsTimer: any;
-
- public query: string = '';
public group: string;
public destination: any;
public uploading: boolean = false;
public libs_uploaded: boolean = false;
public validity_format: string = '';
-
public isInstalled: boolean = false;
public isInSelectedList: boolean = false;
public installingInProgress: boolean = false;
@@ -82,8 +79,9 @@
@ViewChild('groupSelect', { static: false }) group_select;
@ViewChild('resourceSelect', { static: false }) resource_select;
@ViewChild('trigger', { static: false }) matAutoComplete;
- public isLibInfoOpened = { };
private isLibExist: boolean;
+ public lib: Library = {name: '', version: ''};
+ private selectedLib: any = null;
constructor(
@Inject(MAT_DIALOG_DATA) public data: any,
@@ -98,10 +96,14 @@
ngOnInit() {
this.open(this.data);
- this.libSearch.valueChanges.pipe(
- debounceTime(1000))
- .subscribe(newValue => {
- this.query = newValue || '';
+ this.libSearch.valueChanges
+ .pipe(
+ debounceTime(1000),
+ takeUntil(this.unsubscribe$)
+ )
+ .subscribe(value => {
+ this.lib.name = value;
+ this.isDuplicated(this.lib);
this.filterList();
});
}
@@ -109,12 +111,17 @@
ngOnDestroy() {
window.clearTimeout(this.loadLibsTimer);
window.clearTimeout(this.clear);
+ this.unsubscribe$.next();
+ this.unsubscribe$.complete();
}
uploadLibGroups(): void {
this.libs_uploaded = false;
this.uploading = true;
this.librariesInstallationService.getGroupsList(this.notebook.project, this.notebook.name, this.model.computational_name)
+ .pipe(
+ takeUntil(this.unsubscribe$)
+ )
.subscribe(
response => {
this.libsUploadingStatus(response);
@@ -145,7 +152,7 @@
public filterList(): void {
this.validity_format = '';
- (this.query.length >= 2 && this.group) ? this.getFilteredList() : this.filteredList = null;
+ (this.lib.name && this.lib.name.length >= 2 && this.group ) ? this.getFilteredList() : this.filteredList = null;
}
public filterGroups(groupsList) {
@@ -160,6 +167,10 @@
public onUpdate($event) {
if ($event.model.type === 'group_lib') {
this.group = $event.model.value;
+ if (this.group) {
+ this.libSearch.enable();
+ }
+ this.lib = {name: '', version: ''};
} else if ($event.model.type === 'destination') {
this.resetDialog();
this.destination = $event.model.value;
@@ -168,6 +179,7 @@
: this.model.computational_name = null;
this.uploadLibGroups();
this.getInstalledLibsByResource();
+ this.libSearch.disable();
}
this.filterList();
}
@@ -177,37 +189,52 @@
}
public isDuplicated(item) {
- const select = { group: this.group, name: item.name, version: item.version };
-
- this.isInSelectedList = this.model.selectedLibs.filter(el => JSON.stringify(el) === JSON.stringify(select)).length > 0;
-
- if (this.destination && this.destination.libs)
- this.isInstalled = this.destination.libs.findIndex(libr => {
- return select.group !== 'java'
- ? select.name === libr.name && select.group === libr.group && select.version === libr.version
- : select.name === libr.name && select.group === libr.group;
- }) >= 0;
-
- return this.isInSelectedList || this.isInstalled;
+ if (this.filteredList) {
+ if (this.group !== 'java') {
+ this.selectedLib = this.filteredList.find(lib => lib.name.toLowerCase() === item.name.toLowerCase());
+ } else {
+ this.selectedLib = this.filteredList.find(lib => {
+ return lib.name.toLowerCase() === item.name.substring(0, item.name.lastIndexOf(':')).toLowerCase();
+ });
+ }
+ } else {
+ this.selectedLib = null;
+ }
}
public addLibrary(item): void {
- const lib = item.split(':').filter(v => !!v);
- this.model.selectedLibs.push({ group: this.group, name: lib[0], version: lib[1] || 'N/A' });
- this.query = '';
- this.libSearch.setValue('');
- this.filteredList = null;
+ if (this.selectedLib && !this.selectedLib.isInSelectedList) {
+ if (this.group !== 'java') {
+ this.model.selectedLibs.push({ group: this.group, name: item.name, version: item.version || 'N/A' });
+ } else {
+ this.model.selectedLibs.push({
+ group: this.group, name: item.name.substring(0, item.name.lastIndexOf(':')),
+ version: item.name.substring(item.name.lastIndexOf(':') + 1) || 'N/A'
+ });
+ }
+ this.libSearch.setValue('');
+ this.lib = {name: '', version: ''};
+ this.filteredList = null;
+ }
}
public selectLibrary(item): void {
- // this.model.selectedLibs.push({ group: this.group, name: item.name, version: item.version });
- // this.query = '';
- this.libSearch.setValue(item.name + ':');
- this.filteredList = null;
+ if (item.isInSelectedList) {
+ return;
+ }
+ if (this.group === 'java') {
+ this.libSearch.setValue(item.name + ':' + item.version);
+ this.lib.name = item.name + ':' + item.version;
+ } else {
+ this.libSearch.setValue(item.name);
+ this.lib.name = item.name;
+ }
+ this.matAutoComplete.closePanel();
}
public removeSelectedLibrary(item): void {
this.model.selectedLibs.splice(this.model.selectedLibs.indexOf(item), 1);
+ this.getMatchedLibs();
}
public open(notebook): void {
@@ -220,7 +247,7 @@
this.resetDialog();
}
},
- error => this.toastr.error(error.message || 'Library installation failed!', 'Oops!'),
+ error => this.toastr.error(error.message || 'Library installation error!', 'Oops!'),
() => {
this.getInstalledLibrariesList(true);
this.changeDetector.detectChanges();
@@ -237,7 +264,7 @@
public isInstallingInProgress(): void {
this.installingInProgress = this.notebookLibs.some(lib => lib.filteredStatus.some(status => status.status === 'installing'));
if (this.installingInProgress) {
- clearTimeout(this.loadLibsTimer);
+ window.clearTimeout(this.loadLibsTimer);
this.loadLibsTimer = window.setTimeout(() => this.getInstalledLibrariesList(), 10000);
}
}
@@ -254,6 +281,9 @@
private getInstalledLibrariesList(init?: boolean) {
this.model.getInstalledLibrariesList(this.notebook)
+ .pipe(
+ takeUntil(this.unsubscribe$)
+ )
.subscribe((data: any) => {
if ( !this.filtredNotebookLibs.length || data.length !== this.notebookLibs.length) {
this.filtredNotebookLibs = [...data];
@@ -285,6 +315,9 @@
private getInstalledLibsByResource() {
this.librariesInstallationService.getInstalledLibsByResource(this.notebook.project, this.notebook.name, this.model.computational_name)
+ .pipe(
+ takeUntil(this.unsubscribe$)
+ )
.subscribe((data: any) => this.destination.libs = data);
}
@@ -302,45 +335,81 @@
private getFilteredList(): void {
this.validity_format = '';
-
- if (this.group === 'java') {
- this.model.getDependencies(this.query)
- .subscribe(
- lib => this.filteredList = [lib],
- error => {
- if (error.status === HTTP_STATUS_CODES.NOT_FOUND
- || error.status === HTTP_STATUS_CODES.BAD_REQUEST
- || error.status === HTTP_STATUS_CODES.INTERNAL_SERVER_ERROR) {
- this.validity_format = error.message;
- this.filteredList = null;
- }
- });
- } else {
- this.model.getLibrariesList(this.group, this.query)
- .subscribe((libs: Library[]) => {
- console.log('libs', libs);
- console.log(this.query.slice(0, this.query.indexOf(':')));
- this.isLibExist = libs.some(v => v.name === this.query.slice(0, this.query.indexOf(':')));
- this.filteredList = libs;
- });
+ if (this.lib.name.length > 1) {
+ if (this.group === 'java') {
+ this.model.getDependencies(this.lib.name)
+ .pipe(
+ takeUntil(this.unsubscribe$)
+ )
+ .subscribe(
+ libs => {
+ this.filteredList = [libs];
+ this.filteredList.forEach(lib => {
+ lib.isInSelectedList = this.model.selectedLibs.some(el => lib.name.toLowerCase() === el.name.substring(0, el.name.lastIndexOf(':')).toLowerCase());
+ lib.isInstalled = this.notebookLibs.some(libr => {
+ return lib.name.toLowerCase() === libr.name.substring(0, libr.name.lastIndexOf(':')).toLowerCase() &&
+ this.group === libr.group &&
+ libr.status.some(res => res.resource === this.destination.name);
+ }
+ );
+ });
+ this.isDuplicated(this.lib);
+ },
+ error => {
+ if (error.status === HTTP_STATUS_CODES.NOT_FOUND
+ || error.status === HTTP_STATUS_CODES.BAD_REQUEST
+ || error.status === HTTP_STATUS_CODES.INTERNAL_SERVER_ERROR) {
+ this.validity_format = error.message;
+ if (error.message.indexOf('query param artifact') !== -1) {
+ this.validity_format = 'Wrong library name format. Should be <groupId>:<artifactId>:<versionId>.';
+ }
+ if (error.message.indexOf('not found') !== -1) {
+ this.validity_format = 'No matches found.';
+ }
+ this.filteredList = null;
+ }
+ });
+ } else {
+ this.getMatchedLibs();
+ }
}
}
+ private getMatchedLibs() {
+ this.model.getLibrariesList(this.group, this.lib.name.toLowerCase())
+ .pipe(
+ takeUntil(this.unsubscribe$)
+ )
+ .subscribe((libs: Library[]) => {
+ this.isLibExist = libs.some(v => v.name.toLowerCase() === this.lib.name.toLowerCase());
+ this.filteredList = libs;
+ this.filteredList.forEach(lib => {
+ lib.isInSelectedList = this.model.selectedLibs.some(el => el.name.toLowerCase() === lib.name.toLowerCase());
+ lib.isInstalled = this.notebookLibs.some(libr => lib.name === libr.name &&
+ this.group === libr.group &&
+ libr.status.some(res => res.resource === this.destination.name));
+ });
+ this.isDuplicated(this.lib);
+ });
+
+ }
+
private selectorsReset(): void {
this.destination = this.getResourcesList()[0];
this.uploadLibGroups();
this.getInstalledLibsByResource();
+ this.libSearch.disable();
}
private resetDialog(): void {
this.group = '';
- this.query = '';
+ this.lib.name = '';
this.libSearch.setValue('');
this.isInstalled = false;
this.isInSelectedList = false;
this.uploading = false;
this.model.selectedLibs = [];
- this.filteredList = null;
+ this.filteredList = [];
this.groupsList = [];
clearTimeout(this.clear);
@@ -417,7 +486,7 @@
template: `
<div class="dialog-header">
<h4 class="modal-title" *ngIf="data.type === 'added'">Installed dependency</h4>
- <h4 class="modal-title" *ngIf="data.type === 'available'">Library installation error</h4>
+ <h4 class="modal-title" *ngIf="data.type === 'available'">Version is not available</h4>
<button type="button" class="close" (click)="dialogRef.close()">×</button>
</div>
<!-- <mat-list class="resources">-->
@@ -440,54 +509,16 @@
<!-- </mat-list>-->
<div class="lib-list" *ngIf="data.type === 'added'">
- <span class="strong">Dependency: </span>{{data.lib.add_pkgs.join(', ')}}
+ <span class="strong dependency-title">Dependency: </span><span class="packeges" *ngFor="let pack of data.lib.add_pkgs; index as i">{{pack + (i !== data.lib.add_pkgs.length - 1 ? ', ' : '')}}</span>
</div>
<div class="lib-list" *ngIf="data.type === 'available'">
- <p class="terminated">Version is not available</p>
<span class="strong">Available versions: </span>{{data.lib.available_versions.join(', ')}}
</div>
-<!-- <div class="text-center">-->
-<!-- <button type="button" class="butt" mat-raised-button (click)="dialogRef.close()">Close</button>-->
-<!-- </div>-->
`,
styles: [ `
.lib-list { max-height: 200px; overflow-x: auto; word-break: break-all; padding: 20px 30px !important; margin: 20px 0; color: #577289;}
- .terminated{padding-bottom: 15px;}
-
- .mat-list-base {
- padding: 40px 30px;
- }
-
- .object {
- width: 70%;
- display: flex;
- align-items: center;
- padding-right: 10px;
- }
-
- .size {
- width: 30%;
- }
- .scrolling-content.delete-list {
- max-height: 200px;
- overflow-y: auto;
- padding-top: 11px;
- }
-
- .empty-list {
- display: flex;
- width: 100%;
- justify-content: center;
- color: #35afd5;
- padding: 15px;
- }
-
- .list-header {
- border-top: 1px solid #edf1f5;
- border-bottom: 1px solid #edf1f5;
- color: #577289;
- width: 100%;
- }
+ .packeges { word-spacing: 5px; line-height: 23px;}
+ .dependency-title{ line-height: 23px; }
`
]
})
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.model.ts b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.model.ts
index 65896d3..b201904 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.model.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/exploratory/install-libraries/install-libraries.model.ts
@@ -60,7 +60,7 @@
project_name: this.notebook.project,
exploratory_name: this.notebook.name,
group: group,
- start_with: query.slice(0, query.indexOf(':'))
+ start_with: query
};
if (this.computational_name)
lib_query.computational_name = this.computational_name;
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.html
index d45e10b..afa556c 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.html
@@ -19,7 +19,7 @@
<section class="table-wrapper">
<table mat-table [dataSource]="filteredEnvironments" multiTemplateDataRows
- class="data-grid resources mat-elevation-z6">
+ class="data-grid resources mat-elevation-z6" [trackBy]="trackBy">
<ng-container matColumnDef="project">
<td mat-cell *matCellDef="let element" [attr.colspan]="8" class="project-name"> {{ element.project }} </td>
@@ -74,11 +74,16 @@
<ng-container matColumnDef="tag">
<th mat-header-cell *matHeaderCellDef class="tag-col label-header">
<span class="label"> Tags </span>
+ <button mat-icon-button aria-label="More" class="ar" (click)="toggleFilterRow()">
+ <i class="material-icons">
+ <span>more_vert</span>
+ </i>
+ </button>
</th>
</ng-container>
<ng-container matColumnDef="resources">
<th mat-header-cell *matHeaderCellDef class="resources-col label-header">
- <span class="label"> Computational resources </span>
+ <span class="label"> Compute </span>
<button mat-icon-button aria-label="More" class="ar" (click)="toggleFilterRow()">
<i class="material-icons">
<span *ngIf="filtering && filterForm.resources.length > 0 && !collapseFilterRow">filter_list</span>
@@ -90,10 +95,15 @@
<ng-container matColumnDef="cost">
<th mat-header-cell *matHeaderCellDef class="cost-col label-header">
<span class="label"> Cost </span>
+ <button mat-icon-button aria-label="More" class="ar" (click)="toggleFilterRow()">
+ <i class="material-icons">
+ <span>more_vert</span>
+ </i>
+ </button>
</th>
</ng-container>
<ng-container matColumnDef="actions" stickyEnd>
- <th mat-header-cell *matHeaderCellDef class="actions-col label-header">
+ <th mat-header-cell *matHeaderCellDef class="settings label-header">
<span class="label"> Actions </span>
</th>
</ng-container>
@@ -101,8 +111,8 @@
<!-- ----------------------------------------------------- -->
<ng-container matColumnDef="expandedDetail">
- <td mat-cell *matCellDef="let element" class="exploratory" [attr.colspan]="8"
- [@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'" sticky>
+ <td mat-cell *matCellDef="let element" class="exploratory" [attr.colspan]="8" sticky>
+<!-- [@detailExpand]="element == expandedElement ? 'expanded' : 'collapsed'" -->
<tr *ngFor="let element of element.exploratory; let i = index" class="element-row mat-row">
<td class="name-col highlight" (click)="printDetailEnvironmentModal(element)">
@@ -247,8 +257,10 @@
<!-- FILTER START -->
<ng-container matColumnDef="name-filter" sticky>
<th mat-header-cell *matHeaderCellDef class="name-col filter-row-item">
- <input placeholder="Filter by environment name" type="text" class="form-control filter-field"
- [value]="filterForm.name" (input)="filterForm.name = $event.target['value']" />
+ <div class="input-wrapper">
+ <input placeholder="Filter by environment name" type="text" class="form-control filter-field"
+ [value]="filterForm.name" (input)="filterForm.name = $event.target['value']" />
+ </div>
</th>
</ng-container>
<ng-container matColumnDef="status-filter">
@@ -312,9 +324,9 @@
<tr [hidden]="!collapseFilterRow" mat-header-row *matHeaderRowDef="displayedFilterColumns; sticky: true"
class="filter-row"></tr>
- <tr mat-row *matRowDef="let element; columns: ['project']" class="element-row"
- [class.expanded-row]="expandedElement === element"
- (click)="expandedElement = expandedElement === element ? null : element">
+ <tr mat-row *matRowDef="let element; columns: ['project']" class="element-row">
+<!-- [class.expanded-row]="expandedElement === element"-->
+<!-- (click)="expandedElement = expandedElement === element ? null : element">-->
</tr>
<tr mat-row *matRowDef="let row; columns: ['expandedDetail']" class="detail-row"></tr>
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.scss b/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.scss
index 9f8d9f9..fac9b18 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.scss
@@ -17,11 +17,13 @@
* under the License.
*/
+@import "variables";
+
.data-table {
width: 100%;
}
-table {
+table.resources {
width: 100%;
.header-row {
@@ -29,17 +31,26 @@
background-clip:padding-box;
th {
padding: 5px;
+ padding-left: 20px;
+
+ .mat-icon-button{
+ line-height: 45px;
+ }
}
.label {
display: inline-block;
- padding-top: 10px;
+ padding-top: 14px;
vertical-align: super !important;
- padding-left: 5px;
- font-size: 12px;
+ font-size: 13px;
}
}
+ .filter-field{
+ font-size: 13px;
+ padding-left: 10px;
+ }
+
.exploratory {
padding: 0;
@@ -50,13 +61,17 @@
td {
padding: 5px;
+ padding-left: 20px;
+ display: flex;
+ align-items: center;
&.name-col {
padding-right: 5px;
- padding-left: 24px;
+ padding-left: 21px;
cursor: pointer;
overflow: hidden;
text-overflow: ellipsis;
+ //min-width: 187px;
}
&.resources-col {
@@ -78,12 +93,13 @@
}
.filter-row {
- height: 0 !important;
background-clip:padding-box;
th {
padding: 5px;
background-clip: padding-box;
+
+
&:last-child {
padding-right: 6px;
}
@@ -91,39 +107,35 @@
}
.name-col {
- width: 15%;
+ width: 17%;
padding-right: 5px;
padding-left: 24px;
background-color: inherit;
- &.notebook-name{
-
- }
- .label{
- padding-top: 14px;
- }
+ //min-width: 187px;
}
.project-name{
font-weight: 600;
color: #577289;
+ padding-left: 21px;
}
+
.status-col,
.shape-col {
- width: 12%;
- .label{
- padding-top: 14px;
- }
+ width: 11%;
+ //min-width: 105px;
}
.shape-col{
color: #577289;
.label{
- color: rgba(0,0,0,.54);
+ color: $table-header-color;
}
}
.tag-col {
width: 13%;
+ //min-width: 95px;
mat-chip {
min-height: 20px;
@@ -140,157 +152,201 @@
.resources-col {
width: 32%;
- .label{
- padding-top: 14px;
- }
+ //min-width: 420px;
}
.cost-col {
width: 10%;
- text-align: center;
+ //min-width: 95px;
+ justify-content: space-between;
+ }
+
+ .label-header{
+ &.cost-col{
+ z-index: 6 !important;
+ }
+
+ &.status-col{
+ z-index: 10 !important;
+ }
+
+ &.resources-col {
+ z-index: 7 !important;
+ }
+
+ &.tag-col {
+ z-index: 8 !important;
+ }
+
+ &.shape-col {
+ z-index: 9 !important;
+ }
+
+ &.settings {
+ z-index: 5 !important;
+ }
}
.actions-col {
- width: 10%;
+ //width: 10%;
padding-right: 24px;
text-align: right;
background-color: inherit;
+ z-index: 5 !important;
.label{
padding-right: 5px;
}
}
-}
-
-tr.detail-row {
- height: 0;
-}
+ tr.detail-row {
+ height: 0;
+ }
-.element-diagram {
- min-width: 80px;
- border: 2px solid black;
- padding: 8px;
- font-weight: lighter;
- margin: 8px 0;
- height: 104px;
-}
+ .element-diagram {
+ min-width: 80px;
+ border: 2px solid black;
+ padding: 8px;
+ font-weight: lighter;
+ margin: 8px 0;
+ height: 104px;
+ }
-.element-symbol {
- font-weight: bold;
- font-size: 40px;
- line-height: normal;
-}
+ .element-symbol {
+ font-weight: bold;
+ font-size: 40px;
+ line-height: normal;
+ }
-.element-description {
- padding: 16px;
-}
+ .element-description {
+ padding: 16px;
+ }
-.element-description-attribution {
- opacity: 0.5;
-}
+ .element-description-attribution {
+ opacity: 0.5;
+ }
-.dashboard_table {
- width: 100%;
- table-layout: fixed;
-}
+ .dashboard_table {
+ width: 100%;
+ table-layout: fixed;
+ }
-.dashboard_table tr {
- vertical-align: top;
-}
+ .dashboard_table tr {
+ vertical-align: top;
+ }
-.dashboard_table tr th span {
- width: 50px;
- text-align: center;
- height: 100%;
- line-height: 40px;
-}
+ .dashboard_table tr th span {
+ width: 50px;
+ text-align: center;
+ height: 100%;
+ line-height: 40px;
+ }
-.dashboard_table tr td {
- font-size: 14px;
- padding: 20px 15px 16px;
-}
+ .dashboard_table tr td {
+ font-size: 13px;
+ padding: 20px 15px 16px;
+ }
-.dashboard_table tr td,
-.dashboard_table tr th {
- border: 1px solid #d5dfea;
- text-align: left;
-}
+ .dashboard_table tr td,
+ .dashboard_table tr th {
+ border: 1px solid #d5dfea;
+ text-align: left;
+ }
-.dashboard_table tr td:last-child {
- text-align: center;
-}
+ .dashboard_table tr td:last-child {
+ text-align: center;
+ }
-.dashboard_table_body td:first-child {
- background: #f3fbfd;
- color: #455c74;
- font-weight: 600;
- font-size: 16px;
- cursor: pointer;
- overflow: hidden;
- text-overflow: ellipsis;
-}
+ .dashboard_table_body td:first-child {
+ background: #f3fbfd;
+ color: #455c74;
+ font-weight: 600;
+ font-size: 16px;
+ cursor: pointer;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
-.dashboard_table tr:nth-child(2n + 1) {
- background: #f9fafb;
-}
+ .dashboard_table tr:nth-child(2n + 1) {
+ background: #f9fafb;
+ }
-.dashboard_table tr.filter-row td {
- padding: 10px;
-}
+ .dashboard_table tr.filter-row td {
+ padding: 10px;
+ }
-.dashboard_table tr.filter-row td:first-child {
- font-weight: 400;
-}
+ .dashboard_table tr.filter-row td:first-child {
+ font-weight: 400;
+ }
-.dashboard_table tr.filter-row td:last-child {
- padding: 10px 0;
-}
+ .dashboard_table tr.filter-row td:last-child {
+ padding: 10px 0;
+ }
-.filter-row .actions {
- text-align: right;
- display: flex;
- justify-content: flex-end;
-}
+ .dashboard_table tr:nth-child(2n + 1) td:first-child {
+ background: #edf6f9;
+ }
-.filter-row .actions button {
- background: #fff;
- border-color: #35afd5;
- color: #35afd5;
- outline: none;
-}
+ .dashboard_table th {
+ background: #a1b7d1;
+ color: #fff;
+ font-weight: 600;
+ line-height: 40px;
+ text-transform: uppercase;
+ padding-left: 12px;
+ font-size: 13px;
+ }
-.filter-row .actions .reset:hover {
- border-color: #f1696e;
- background: #f9fafb;
- color: #f1696e;
-}
+ &.data-grid .status {
+ text-transform: capitalize;
+ }
-.filter-row .actions .apply:hover {
- border-color: #49af38;
- background: #f9fafb;
- color: #49af38;
-}
+ .message_block td {
+ text-align: left !important;
+ }
-.dashboard_table tr:nth-child(2n + 1) td:first-child {
- background: #edf6f9;
-}
+ &.data-grid .total_cost {
+ float: left;
+ display: inline-block;
+ color: #455c74;
+ }
-.dashboard_table th {
- background: #a1b7d1;
- color: #fff;
- font-weight: 600;
- line-height: 40px;
- text-transform: uppercase;
- padding-left: 12px;
- font-size: 12px;
-}
+ .currency_details {
+ color: #35afd5;
+ cursor: pointer;
+ transition: all 0.45s ease-in-out;
+ padding-left: 10px;
+ }
-.data-grid .status {
- text-transform: capitalize;
+ .currency_details:hover {
+ color: #3392b0;
+ }
+
+ .currency_details .material-icons {
+ font-size: 18px;
+ }
+
+ .mat-icon-button .mat-icon,
+ .mat-icon-button i {
+ line-height: 42px;
+ font-size: 18px;
+ }
+
+ .info {
+ padding: 40px;
+ text-align: center;
+ }
+
+ .content-row{
+ background-clip: padding-box;
+ }
+
+ .not-allow{
+ cursor: not-allowed !important;
+ }
}
.data-grid .list-menu {
@@ -299,7 +355,7 @@
right: 15px;
padding: 10px 15px;
box-shadow: 0 5px 5px -3px rgba(0, 0, 0, 0.2),
- 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12);
+ 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12);
border: none;
min-width: 190px;
}
@@ -307,8 +363,9 @@
.settings {
position: relative;
text-align: right;
- min-width: 7%;
+ width: 6%;
padding-right: 15px !important;
+ justify-content: flex-end;
.actions {
background-image: url(../../../assets/svg/settings_icon.svg);
@@ -328,7 +385,7 @@
.data-grid .list-menu li {
- font-size: 14px;
+ font-size: 13px;
border-bottom: 1px solid #edf1f5;
padding-bottom: 5px;
cursor: pointer;
@@ -374,46 +431,13 @@
background: #edf6f9;
}
-.message_block td {
- text-align: left !important;
+@media screen and (max-width: 1400px) {
+ table.resources {
+ .settings {
+ width: 7%;
+ }
+ }
}
-.data-grid .total_cost {
- display: inline-block;
- width: 70%;
- color: #455c74;
-}
-.currency_details {
- float: right;
- color: #35afd5;
- cursor: pointer;
- transition: all 0.45s ease-in-out;
-}
-.currency_details:hover {
- color: #3392b0;
-}
-
-.currency_details .material-icons {
- font-size: 18px;
-}
-
-.mat-icon-button .mat-icon,
-.mat-icon-button i {
- line-height: 42px;
- font-size: 18px;
-}
-
-.info {
- padding: 40px;
- text-align: center;
-}
-
-.content-row{
- background-clip: padding-box;
-}
-
-.not-allow{
- cursor: not-allowed !important;
-}
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.ts
index 810304b..e4e5bf3 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/resources-grid/resources-grid.component.ts
@@ -18,7 +18,7 @@
*/
import {Project} from '../../administration/project/project.component';
-import {Component, Input, OnInit} from '@angular/core';
+import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import { animate, state, style, transition, trigger } from '@angular/animations';
import { ToastrService } from 'ngx-toastr';
import { MatDialog } from '@angular/material/dialog';
@@ -91,6 +91,7 @@
readonly DICTIONARY = DICTIONARY;
@Input() projects: Array<any>;
+ @Output() getEnvironments: EventEmitter<any> = new EventEmitter();
environments: Exploratory[];
@@ -119,8 +120,6 @@
public bucketsList: BucketList;
public activeProjectsList: any;
-
-
constructor(
public toastr: ToastrService,
private userResourceService: UserResourceService,
@@ -146,12 +145,13 @@
this.userResourceService.getUserProvisionedResources()
.subscribe((result: any) => {
this.environments = ExploratoryModel.loadEnvironments(result);
+ this.getEnvironments.emit(this.environments);
this.getBuckets();
this.getDefaultFilterConfiguration();
(this.environments.length) ? this.getUserPreferences() : this.filteredEnvironments = [];
this.healthStatus && !this.healthStatus.billingEnabled && this.modifyGrid();
this.progressBarService.stopProgressBar();
- }, () => this.progressBarService.stopProgressBar());
+ }, () => this.progressBarService.stopProgressBar());
}
public toggleFilterRow(): void {
@@ -225,7 +225,9 @@
if (action === 'deploy') {
this.dialog.open(ComputationalResourceCreateDialogComponent, { data: { notebook: resource, full_list: this.environments }, panelClass: 'modal-xxl' })
- .afterClosed().subscribe(() => this.buildGrid());
+ .afterClosed().subscribe((res) => {
+ res && this.buildGrid();
+ });
} else if (action === 'run') {
this.userResourceService
.runExploratoryEnvironment({ notebook_instance_name: data.name, project_name: data.project })
@@ -234,21 +236,22 @@
error => this.toastr.error(error.message || 'Exploratory starting failed!', 'Oops!'));
} else if (action === 'stop') {
this.dialog.open(ConfirmationDialogComponent, { data: { notebook: data, type: ConfirmationDialogType.StopExploratory }, panelClass: 'modal-sm' })
- .afterClosed().subscribe(() => this.buildGrid());
+ .afterClosed().subscribe((res) => {
+ res && this.buildGrid();
+ });
} else if (action === 'terminate') {
this.dialog.open(ConfirmationDialogComponent, { data:
{ notebook: data, type: ConfirmationDialogType.TerminateExploratory }, panelClass: 'modal-sm' })
- .afterClosed().subscribe(() => this.buildGrid());
+ .afterClosed().subscribe((res) => res && this.buildGrid());
} else if (action === 'install') {
this.dialog.open(InstallLibrariesComponent, { data: data, panelClass: 'modal-fullscreen' })
- .afterClosed().subscribe(() => this.buildGrid());
+ .afterClosed().subscribe((res) => res && this.buildGrid());
} else if (action === 'schedule') {
this.dialog.open(SchedulerComponent, { data: { notebook: data, type: 'EXPLORATORY' }, panelClass: 'modal-xl-s' })
- .afterClosed().subscribe(() => this.buildGrid());
+ .afterClosed().subscribe((res) => res && this.buildGrid());
} else if (action === 'ami') {
this.dialog.open(AmiCreateDialogComponent, { data: data, panelClass: 'modal-sm' })
-
- .afterClosed().subscribe(() => this.buildGrid());
+ .afterClosed().subscribe((res) => res && this.buildGrid());
}
}
@@ -260,11 +263,15 @@
if (endpoint.status === 'ACTIVE') {
const currEndpoint: SharedEndpoint = project.projectEndpoints[endpoint.name];
const edgeItem: BucketList = {name: `${project.project} (${endpoint.name})`, children: [], cloud: endpoint.cloudProvider};
- const projectBucket: string = currEndpoint.user_own_bicket_name
- || currEndpoint.user_own_bucket_name
- || currEndpoint.user_container_name ? currEndpoint.user_storage_account_name + '.' + currEndpoint.user_container_name : null;
- const sharedBucket: string = currEndpoint.shared_bucket_name ||
- currEndpoint.shared_container_name ? currEndpoint.shared_storage_account_name + '.' + currEndpoint.shared_container_name : null;
+ let projectBucket: string = currEndpoint.user_own_bicket_name
+ || currEndpoint.user_own_bucket_name;
+ if (currEndpoint.user_container_name) {
+ projectBucket = currEndpoint.user_storage_account_name + '.' + currEndpoint.user_container_name;
+ }
+ let sharedBucket: string = currEndpoint.shared_bucket_name;
+ if (currEndpoint.shared_container_name) {
+ sharedBucket = currEndpoint.shared_storage_account_name + '.' + currEndpoint.shared_container_name;
+ }
if (projectBucket && currEndpoint.status !== 'terminated'
&& currEndpoint.status !== 'terminating' && currEndpoint.status !== 'failed') {
edgeItem.children.push({name: projectBucket, endpoint: endpoint.name});
@@ -426,4 +433,8 @@
}).subscribe();
}
+ public trackBy(index, item) {
+ return null;
+ }
+
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/resources.component.html b/services/self-service/src/main/resources/webapp/src/app/resources/resources.component.html
index d47559f..ad6fc53 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/resources.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/resources.component.html
@@ -18,7 +18,7 @@
-->
<div class="base-retreat">
- <div class="sub-nav">
+ <div class="sub-nav resource-btns">
<div class="selection">
<span
matTooltip="{{!healthStatus?.projectAssigned ? 'You are not assigned to any project' : 'You have not any active project'}}"
@@ -26,22 +26,21 @@
[matTooltipClass]="'bucket-item-tooltip'"
[matTooltipDisabled]="healthStatus?.projectAssigned && resourcesGrid.activeProjectsList?.length !== 0"
>
- <span>{{resourcesGrid.activeProject}}</span>
<button mat-raised-button class="butt butt-create" (click)="createEnvironment()"
[disabled]="!healthStatus?.projectAssigned || !resourcesGrid.activeProjectsList?.length">
<i class="material-icons">add</i>Create new
</button>
</span>
<div class="mat-reset">
- <div class="control selector-wrapper" *ngIf="projects.length">
+ <div class="control selector-wrapper" *ngIf="projects?.length">
<mat-form-field>
- <mat-label>Select active project</mat-label>
+ <mat-label>Select project</mat-label>
<mat-select [(value)]="resourcesGrid.activeProject">
- <mat-option *ngIf="projects.length > 1" (click)="setActiveProject()">Show all</mat-option>
- <mat-option *ngFor="let project of projects" [value]="project.name"
- (click)="setActiveProject(project.name)">
- {{ project.name }}</mat-option>
- <mat-option *ngIf="!projects.length" class="multiple-select ml-10" disabled>Projects list is empty
+ <mat-option *ngIf="projects?.length > 1" (click)="setActiveProject('')">Show all</mat-option>
+ <mat-option *ngFor="let project of projects" [value]="project"
+ (click)="setActiveProject(project)">
+ {{ project }}</mat-option>
+ <mat-option *ngIf="!projects?.length" class="multiple-select ml-10" disabled>Projects list is empty
</mat-option>
</mat-select>
<button class="caret">
@@ -60,25 +59,31 @@
>
<button mat-raised-button class="butt butt-tool" (click)="bucketBrowser(this.bucketStatus?.view)"
[disabled]="!this.bucketStatus?.view || resourcesGrid.bucketsList?.length === 0">
- <i class="material-icons"></i>Bucket browser
- </button>
+ <i class="material-icons"></i>Bucket browser
+ </button>
</span>
- <button mat-raised-button class="butt butt-tool" (click)="manageUngit()">
- <i class="material-icons"></i>Git credentials
- </button>
- <button mat-raised-button class="butt butt-tool" (click)="toggleFiltering()">
- <span *ngIf="!resourcesGrid.activeFiltering">
- <i class="material-icons">visibility_off</i> Show active
- </span>
- <span *ngIf="resourcesGrid.activeFiltering">
- <i class="material-icons">visibility</i> Show all
- </span>
- </button>
- <button mat-raised-button class="butt" (click)="refreshGrid()">
- <i class="material-icons">autorenew</i>Refresh
- </button>
+ <span>
+ <button mat-raised-button class="butt butt-tool" (click)="manageUngit()">
+ <i class="material-icons"></i>Git credentials
+ </button>
+ </span>
+ <span>
+ <button mat-raised-button class="butt butt-tool show-all-btn" (click)="toggleFiltering()">
+ <span *ngIf="!resourcesGrid.activeFiltering">
+ <i class="material-icons">visibility_off</i> Show active
+ </span>
+ <span *ngIf="resourcesGrid.activeFiltering">
+ <i class="material-icons">visibility</i> Show all
+ </span>
+ </button>
+ </span>
+ <span>
+ <button mat-raised-button class="butt" (click)="refreshGrid()">
+ <i class="material-icons">autorenew</i>Refresh
+ </button>
+ </span>
</div>
</div>
<mat-divider></mat-divider>
- <resources-grid></resources-grid>
+ <resources-grid (getEnvironments)="getEnvironments($event)" ></resources-grid>
</div>
diff --git a/services/self-service/src/main/resources/webapp/src/app/resources/resources.component.ts b/services/self-service/src/main/resources/webapp/src/app/resources/resources.component.ts
index 301509d..3dadd70 100644
--- a/services/self-service/src/main/resources/webapp/src/app/resources/resources.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/resources/resources.component.ts
@@ -17,7 +17,7 @@
* under the License.
*/
-import { Component, OnInit, ViewChild } from '@angular/core';
+import {AfterViewInit, Component, OnInit, ViewChild} from '@angular/core';
import { ToastrService } from 'ngx-toastr';
import { MatDialog } from '@angular/material/dialog';
@@ -35,10 +35,10 @@
styleUrls: ['./resources.component.scss']
})
-export class ResourcesComponent implements OnInit {
+export class ResourcesComponent implements OnInit, AfterViewInit {
public exploratoryEnvironments: Exploratory[] = [];
public healthStatus: any;
- projects: Project[] = [];
+ projects = [];
@ViewChild(ResourcesGridComponent, { static: true }) resourcesGrid: ResourcesGridComponent;
@@ -52,7 +52,11 @@
ngOnInit() {
this.getEnvironmentHealthStatus();
- this.exploratoryEnvironments = this.resourcesGrid.environments;
+ this.projects = this.resourcesGrid.activeProjectsList;
+ }
+
+ ngAfterViewInit() {
+
}
public createEnvironment(): void {
@@ -82,6 +86,7 @@
}
public bucketBrowser(permition): void {
+ console.log(this.exploratoryEnvironments);
const defaultBucket = this.resourcesGrid.bucketsList[0].children[0];
permition && this.dialog.open(BucketBrowserComponent, { data:
{
@@ -112,6 +117,12 @@
}
+ public getEnvironments(environment) {
+ this.exploratoryEnvironments = environment;
+ this.projects = environment.map(env => env.project);
+ }
+
+
private getEnvironmentHealthStatus() {
this.healthStatusService.getEnvironmentHealthStatus().subscribe(
(result: any) => {
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/dropdowns.component.scss b/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/dropdowns.component.scss
index a177f5c..ad90694 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/dropdowns.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/dropdowns.component.scss
@@ -28,8 +28,9 @@
min-width: 100%;
background: #fff;
padding-left: 15px;
- font-size: 14px;
- // height: 34px;
+ font-size: 13px;
+ padding-top: 1px;
+ height: 34px;
text-align: left;
white-space: nowrap;
cursor: pointer;
@@ -68,7 +69,7 @@
span {
color: #999;
font-weight: 300;
- display: inline-block;
+ //display: inline-block;
max-width: 80%;
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/multi-level-select-dropdown/multi-level-select-dropdown.component.scss b/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/multi-level-select-dropdown/multi-level-select-dropdown.component.scss
index a066dd5..038b54c 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/multi-level-select-dropdown/multi-level-select-dropdown.component.scss
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/form-controls/multi-level-select-dropdown/multi-level-select-dropdown.component.scss
@@ -29,8 +29,8 @@
width: 100%;
background: #fff;
padding-left: 15px;
- font-size: 14px;
- // height: 34px;
+ font-size: 13px;
+ height: 34px;
text-align: left;
white-space: nowrap;
cursor: pointer;
@@ -76,6 +76,7 @@
.selected-items {
color: #4a5c89;
max-width: 477px;
+ padding-top: 5px;
}
}
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/confirmation-dialog/confirmation-dialog.component.ts b/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/confirmation-dialog/confirmation-dialog.component.ts
index b8a2cff..5d39c68 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/confirmation-dialog/confirmation-dialog.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/confirmation-dialog/confirmation-dialog.component.ts
@@ -60,12 +60,12 @@
}
ngOnInit() {
- if(this.data.type !== 5){
+ if (this.data.type !== 5) {
this.confirmationType = this.data.type;
this.notebook = this.data.notebook;
this.model = new ConfirmationDialogModel(this.confirmationType, this.notebook,
response => {
- if (response.status === HTTP_STATUS_CODES.OK) this.dialogRef.close();
+ if (response.status === HTTP_STATUS_CODES.OK) this.dialogRef.close(true);
},
error => this.toastr.error(error.message || 'Action failed!', 'Oops'),
this.data.manageAction,
@@ -75,7 +75,9 @@
if (!this.confirmationType) this.filterResourcesByType(this.notebook.resources);
this.isAliveResources = this.model.isAliveResources(this.notebook.resources);
- this.onlyKilled = this.notebook.resources ? !this.notebook.resources.some(el => el.status !== 'terminated' && el.status !== 'failed') : false;
+ this.onlyKilled = this.notebook.resources ?
+ !this.notebook.resources.some(el => el.status !== 'terminated' && el.status !== 'failed')
+ : false;
}
}
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/notification-dialog/notification-dialog.component.ts b/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/notification-dialog/notification-dialog.component.ts
index e185675..551e3e2 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/notification-dialog/notification-dialog.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/modal-dialog/notification-dialog/notification-dialog.component.ts
@@ -56,7 +56,9 @@
</div>
<span class="strong blue">by a schedule in less than 15 minutes.</span>
</div>
- <div *ngIf="data.type === 'message'"><span [innerHTML]="data.template"></span></div>
+ <div class="alert" *ngIf="data.type === 'message'">
+ <span [innerHTML]="data.template"></span>
+ </div>
<div *ngIf="data.type === 'confirmation'" class="confirm-dialog">
<p *ngIf="data.template; else label">
<span [innerHTML]="data.template"></span>
@@ -169,6 +171,7 @@
label{cursor: pointer}
.bottom-message{padding-top: 15px;}
.table-header{padding-bottom: 10px;}
+ .alert{text-align: left; line-height: 22px; padding-bottom: 25px;padding-top: 15px;}
`]
diff --git a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.ts b/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.ts
index e30f8db..7046696 100644
--- a/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.ts
+++ b/services/self-service/src/main/resources/webapp/src/app/shared/navbar/navbar.component.ts
@@ -38,9 +38,14 @@
animateChild,
state
} from '@angular/animations';
-import {skip} from 'rxjs/operators';
+import {skip, take} from 'rxjs/operators';
import {ProgressBarService} from '../../core/services/progress-bar.service';
+
+interface Quota {
+ projectQuotas: {};
+ totalQuotaUsed: number;
+}
@Component({
selector: 'dlab-navbar',
templateUrl: 'navbar.component.html',
@@ -110,7 +115,7 @@
if (this.isLoggedIn) {
this.subscriptions.add(this.healthStatusService.statusData.pipe(skip(1)).subscribe(result => {
this.healthStatus = result;
- result.status && this.checkQuoteUsed(this.healthStatus);
+ result.status && this.checkQuoteUsed();
result.status && !result.projectAssigned && !result.admin && this.checkAssignment(this.healthStatus);
}));
this.subscriptions.add(timer(0, this.CHECK_ACTIVE_SCHEDULE_TIMEOUT).subscribe(() => this.refreshSchedulerData()));
@@ -148,9 +153,9 @@
this.isExpanded = !this.isExpanded;
}
- public emitQuotes(alert, user_quota?, total_quota?): void {
+ public emitQuotes(alert, total_quota?, exideedProjects?, informProjects?): void {
const dialogRef: MatDialogRef<NotificationDialogComponent> = this.dialog.open(NotificationDialogComponent, {
- data: { template: this.selectAlert(alert, user_quota, total_quota), type: 'message' },
+ data: { template: this.selectAlert(alert, total_quota, exideedProjects, informProjects), type: 'message' },
width: '550px'
});
dialogRef.afterClosed().subscribe(() => {
@@ -158,17 +163,38 @@
});
}
- private checkQuoteUsed(params): void {
- if (!this.storage.getBillingQuoteUsed() && params) {
- let checkQuotaAlert = '';
+ private checkQuoteUsed(): void {
+ if (!this.storage.getBillingQuoteUsed( )) {
+ this.healthStatusService.getQuotaStatus().pipe(take(1)).subscribe((params: Quota) => {
+ let checkQuotaAlert = '';
+ const exceedProjects = [], informProjects = [];
+ Object.keys(params.projectQuotas).forEach(key => {
+ if (params.projectQuotas[key] > this.quotesLimit && params.projectQuotas[key] < 100) {
+ informProjects.push(key);
+ } else if (params.projectQuotas[key] >= 100) {
+ exceedProjects.push(key);
+ }
+ });
- if (params.billingUserQuoteUsed >= this.quotesLimit && params.billingUserQuoteUsed < 100) checkQuotaAlert = 'user_quota';
- if (params.billingQuoteUsed >= this.quotesLimit && params.billingQuoteUsed < 100) checkQuotaAlert = 'total_quota';
- if (Number(params.billingUserQuoteUsed) >= 100) checkQuotaAlert = 'user_exceed';
- if (Number(params.billingQuoteUsed) >= 100) checkQuotaAlert = 'total_exceed';
+ if (informProjects.length > 0 && exceedProjects.length === 0) checkQuotaAlert = 'project_quota';
+ if (params.totalQuotaUsed >= this.quotesLimit && params.totalQuotaUsed < 100) checkQuotaAlert = 'total_quota';
+ if (exceedProjects.length > 0 && informProjects.length === 0) checkQuotaAlert = 'project_exceed';
+ if (informProjects.length > 0 && exceedProjects.length > 0) checkQuotaAlert = 'project_inform_and_exceed';
+ if (params.totalQuotaUsed >= this.quotesLimit && params.totalQuotaUsed < 100 && exceedProjects.length > 0) checkQuotaAlert = 'total_quota_and_project_exceed';
+ if (params.totalQuotaUsed >= this.quotesLimit && params.totalQuotaUsed < 100 && informProjects.length > 0 && exceedProjects.length > 0) checkQuotaAlert = 'total_quota_and_project_inform_and_exceed';
- if (this.dialog.openDialogs.length > 0 || this.dialog.openDialogs.length > 0) return;
- checkQuotaAlert && this.emitQuotes(checkQuotaAlert, params.billingUserQuoteUsed, params.billingQuoteUsed);
+
+ if (Number(params.totalQuotaUsed) >= 100) checkQuotaAlert = 'total_exceed';
+
+ if (checkQuotaAlert === '') {
+ this.storage.setBillingQuoteUsed('informed');
+ } else {
+ this.storage.setBillingQuoteUsed('');
+ }
+
+ if (this.dialog.openDialogs.length > 0 || this.dialog.openDialogs.length > 0) return;
+ checkQuotaAlert && this.emitQuotes(checkQuotaAlert, params.totalQuotaUsed, exceedProjects, informProjects);
+ });
}
}
@@ -206,25 +232,46 @@
});
}
- private selectAlert(type: string, user_quota?: number, total_quota?: number): string {
+ private selectAlert(type: string, total_quota?: number, exideedProjects?: string[], informProjects?: string[]): string {
const alerts = {
- user_exceed: `Dear <b>${this.currentUserName}</b>,<br />
- DLab cloud infrastructure usage quota associated with your user has been exceeded.
- All your analytical environment will be stopped. To proceed working with environment,
- request increase of user quota from DLab administrator.`,
- total_exceed: `Dear <b>${this.currentUserName}</b>,<br />
+ total_quota_and_project_inform_and_exceed: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
+ DLab cloud infrastructure usage quota has been used for <span class="strong">${total_quota}%</span>.
+ Once quota is depleted all your analytical environment will be stopped.<br /><br />
+ Quota associated with project(s) <span class="strong">${exideedProjects}</span> has been exceeded. All your analytical environment will be stopped.<br /><br />
+ Quota associated with project(s) <span class="strong">${informProjects}</span> has been used over <span class="strong">${this.quotesLimit}%</span>.
+ If quota is depleted all your analytical environment will be stopped.<br /><br />
+ To proceed working with environment you'll have to request increase of quota from DLab administrator. `,
+
+ total_quota_and_project_exceed: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
+ DLab cloud infrastructure usage quota has been used for <span class="strong">${total_quota}%</span>.
+ Once quota is depleted all your analytical environment will be stopped.<br /><br />
+ Quota associated with project(s) <span class="strong">${exideedProjects}</span> has been exceeded. All your analytical environment will be stopped.<br /><br />
+ To proceed working with environment you'll have to request increase of quota from DLab administrator. `,
+
+ project_inform_and_exceed: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
+ DLab cloud infrastructure usage quota associated with project(s) <span class="strong">${exideedProjects}</span> has been exceeded. All your analytical environment will be stopped.<br /><br />
+ Quota associated with project(s) <span class="strong">${informProjects}</span> has been used over <span class="strong">${this.quotesLimit}%</span>.
+ If quota is depleted all your analytical environment will be stopped.<br /><br />
+ To proceed working with environment, request increase of project quota from DLab administrator.`,
+ project_exceed: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
+ DLab cloud infrastructure usage quota associated with project(s) <span class="strong">${exideedProjects}</span> has been exceeded.
+ All your analytical environment will be stopped.<br /><br />
+ To proceed working with environment,
+ request increase of project(s) quota from DLab administrator.`,
+ total_exceed: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
DLab cloud infrastructure usage quota has been exceeded.
- All your analytical environment will be stopped. To proceed working with environment,
+ All your analytical environment will be stopped.<br /><br />
+ To proceed working with environment,
request increase application quota from DLab administrator.`,
- user_quota: `Dear <b>${this.currentUserName}</b>,<br />
- Cloud infrastructure usage quota associated with your user has been used for <b>${user_quota}%</b>.
- Once quota is depleted all your analytical environment will be stopped.
- To proceed working with environment you'll have to request increase of user quota from DLab administrator.`,
- total_quota: `Dear <b>${this.currentUserName}</b>,<br />
- DLab cloud infrastructure usage quota has been used for <b>${total_quota}%</b>.
- Once quota is depleted all your analytical environment will be stopped.
- To proceed working with environment you'll have to request increase of user quota from DLab administrator. `,
- permissions: `Dear <b>${this.currentUserName}</b>,<br />
+ project_quota: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
+ Cloud infrastructure usage quota associated with project(s) <span class="strong">${informProjects}</span> has been used over <span class="strong">${this.quotesLimit}%</span>.
+ Once quota is depleted all your analytical environment will be stopped.<br /><br />
+ To proceed working with environment you'll have to request increase of project(s) quota from DLab administrator.`,
+ total_quota: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
+ DLab cloud infrastructure usage quota has been used for <span class="strong">${total_quota}%</span>.
+ Once quota is depleted all your analytical environment will be stopped.<br /><br />
+ To proceed working with environment you'll have to request increase of total quota from DLab administrator. `,
+ permissions: `Dear <span class="strong">${this.currentUserName}</span>,<br /><br />
Currently, you are not assigned to any project. To start working with the environment
request permission from DLab administrator.`
};
diff --git a/services/self-service/src/main/resources/webapp/src/app/webterminal/webterminal.component.html b/services/self-service/src/main/resources/webapp/src/app/webterminal/webterminal.component.html
index 4aedd1c..6fe2d98 100644
--- a/services/self-service/src/main/resources/webapp/src/app/webterminal/webterminal.component.html
+++ b/services/self-service/src/main/resources/webapp/src/app/webterminal/webterminal.component.html
@@ -15,6 +15,6 @@
~ KIND, either express or implied. See the License for the
~ specific language governing permissions and limitations
~ under the License.
--->
+ -->
<div #terminal id="display" class="guac-display guac-loading"></div>
diff --git a/services/self-service/src/main/resources/webapp/src/assets/styles/_dialogs.scss b/services/self-service/src/main/resources/webapp/src/assets/styles/_dialogs.scss
index c00dd14..e4d0418 100644
--- a/services/self-service/src/main/resources/webapp/src/assets/styles/_dialogs.scss
+++ b/services/self-service/src/main/resources/webapp/src/assets/styles/_dialogs.scss
@@ -52,7 +52,8 @@
}
.modal-fullscreen {
- width: 100vw;
+ width: 90vw;
+ max-width: 90vw !important;
min-height: 80vh;
}
@@ -374,6 +375,11 @@
height: 30px;
}
+.mat-list-item{
+ font-family: "Open Sans", sans-serif;
+ font-weight: 400;
+}
+
.d-none{
display: none !important;
}
diff --git a/services/self-service/src/main/resources/webapp/src/assets/styles/_general.scss b/services/self-service/src/main/resources/webapp/src/assets/styles/_general.scss
index 121fe6e..50aeed8 100644
--- a/services/self-service/src/main/resources/webapp/src/assets/styles/_general.scss
+++ b/services/self-service/src/main/resources/webapp/src/assets/styles/_general.scss
@@ -30,11 +30,14 @@
}
.alignleft, .al {float: left}
-.alignright, .ar {float: right}
+.alignright, .ar {float: right; left: 26px; z-index: 1010}
.aligncenter, .ac {margin-left: auto;margin-right: auto}
.mt-5 {margin-top: 5px}
+
+.pr-3{padding-right: 3pxr7}
+
.pb-50 {padding-bottom: 50px;}
.txt-r {text-align: right }
@@ -174,3 +177,7 @@
input[type=file]::-webkit-file-upload-button {
cursor: pointer;
}
+
+.refresh-icon{
+ color: #35afd5;
+}
diff --git a/services/self-service/src/main/resources/webapp/src/assets/styles/_theme.scss b/services/self-service/src/main/resources/webapp/src/assets/styles/_theme.scss
index 2500caf..ee719c5 100644
--- a/services/self-service/src/main/resources/webapp/src/assets/styles/_theme.scss
+++ b/services/self-service/src/main/resources/webapp/src/assets/styles/_theme.scss
@@ -28,6 +28,9 @@
font-size: 15px;
font-family: 'Open Sans', sans-serif;
color: #577289;
+ &[disabled]{
+ box-shadow: 0 3px 1px -2px rgba(0,0,0,.2), 0 2px 2px 0 rgba(0,0,0,.14), 0 1px 5px 0 rgba(0,0,0,.12);
+ }
i {
margin: 0 5px 0 0;
@@ -49,6 +52,14 @@
&.action {
width: 140px;
+
+ &.install-btn{
+ margin-left: 0;
+ }
+
+ &.close-btn{
+ margin-right: 25px;
+ }
}
&.butt-success {
@@ -466,7 +477,7 @@
position: relative;
cursor: pointer;
&.header-checkbox{
- margin-top: 13px;
+ margin-top: 7px;
float: left;
}
&.checked {
@@ -734,17 +745,32 @@
}
}
-.mat-table {
- .header-row {
- th.mat-header-cell {
+table.mat-table {
+ font-family: "Open Sans", sans-serif;
+ font-weight: 400;
+
+ .mat-cell{
+ font-size: 13px;
+ }
+ .header-row,
+ .mat-header-row{
+ .mat-header-cell {
font-family: 'Open Sans', sans-serif;
font-weight: 600;
+ font-size: 13px;
+ .label{
+ font-family: 'Open Sans', sans-serif;
+ font-weight: 600;
+ font-size: 13px;
+ }
}
.mat-cell {
word-break: break-all;
vertical-align: top;
padding: 15px 5px 10px 5px;
+ font-size: 13px;
+ font-family: "Open Sans", sans-serif;
td {
vertical-align: baseline;
@@ -787,5 +813,175 @@
.filter-row-item, .label-header{
box-shadow: inset 0 -1px 0 lightgrey;
border-bottom: none !important;
+ multi-select-dropdown, .input-wrapper{
+ position: absolute;
+ top: 10px;
+ left: 5px;
+ right: 5px;
+ }
+
+ .input-wrapper{
+ left: 10px;
+ right: 4px;
+ }
}
+/* daterangepicker themes */
+#range-picker {
+ display: flex;
+ justify-content: center;
+}
+
+#range-picker path#Shape {
+ fill: #36afd5;
+}
+
+#range-picker .ng-daterangepicker,
+ {
+ border: none;
+ border-radius: 0;
+ box-shadow: none;
+}
+
+#range-picker .ng-daterangepicker .calendar {
+ z-index: 102;
+ border: 1px solid rgba(234, 234, 234, 0.64);
+ border-radius: 0;
+ box-shadow: 0 3px 1px -2px rgba(0, 0, 0, 0.2),
+ 0 2px 2px 0 rgba(0, 0, 0, 0.14),
+ 0 1px 5px 0 rgba(0, 0, 0, 0.12);
+
+ &.is-to:after {
+ left: 250px;
+ }
+}
+
+#range-picker .ng-daterangepicker .calendar::after {
+ border-top: 1px solid rgba(234, 234, 234, 0.64);
+ border-left: 1px solid rgba(234, 234, 234, 0.64);
+}
+
+#range-picker .ng-daterangepicker .calendar .side-container .side-button {
+ background: #fff;
+ color: #718ba6;
+ border: none;
+ border-radius: 0px;
+}
+
+#range-picker .ng-daterangepicker .calendar .side-container .side-button.is-active,
+#range-picker .ng-daterangepicker .input-section .label-txt {
+ color: #35afd5;
+ display: unset;
+ font-size: 13px;
+}
+
+#range-picker .ng-daterangepicker .calendar .side-container .side-button.is-active {
+ color: #fff;
+ background: #35afd5;
+ border-radius: 10px;
+}
+
+#range-picker .ng-daterangepicker .calendar .calendar-container .day-num.is-active,
+#range-picker .ng-daterangepicker .calendar .calendar-container .days .day-num:hover {
+ background: #35afd5;
+ background-clip: padding-box;
+
+}
+
+#range-picker .ng-daterangepicker .calendar .calendar-container .day-names,
+#range-picker .ng-daterangepicker .calendar .calendar-container .days {
+ width: 310px;
+}
+
+#range-picker .ng-daterangepicker .calendar .day.is-within-range.is-first-weekday,
+#range-picker .ng-daterangepicker .calendar .day.is-within-range.is-last-weekday {
+ background-clip: padding-box;
+}
+
+#range-picker .ng-daterangepicker .calendar .calendar-container .day.is-within-range {
+ background: #e9f8fc
+}
+
+#range-picker .ng-daterangepicker .input-section .cal-icon svg path {
+ fill: #35afd5;
+}
+
+#range-picker .ng-daterangepicker .input-section .value-txt {
+ color: #718ba6;
+ display: unset;
+ padding-left: 5px;
+}
+
+#range-picker .ng-daterangepicker .input-section .value-txt.untouched,
+#range-picker .ng-daterangepicker .input-section .label-txt.untouched {
+ color: #fff;
+}
+
+//#range-picker .ng-daterangepicker .input-section .value-txt.untouched::after {
+// content: 'date';
+// position: absolute;
+// top: 9px;
+// left: 61px;
+// color: #718ba6;
+//}
+
+.filter-row .actions {
+ text-align: right;
+ display: flex;
+ justify-content: flex-end;
+}
+
+.filter-row .actions button {
+ background: #fff;
+ border-color: #35afd5;
+ color: #35afd5;
+ outline: none;
+}
+
+.filter-row .actions .reset:hover {
+ border-color: #f1696e;
+ background: #f9fafb;
+ color: #f1696e;
+}
+
+.filter-row .actions .apply:hover {
+ border-color: #49af38;
+ background: #f9fafb;
+ color: #49af38;
+}
+
+#range-picker .ng-daterangepicker {
+ height: 37px;
+ width: 360px;
+ display: flex;
+ justify-content: space-between;
+
+
+ .d-none{
+ display: none;
+ }
+
+ .input-section {
+ height: 37px;
+ padding-right: 30px;
+ width: 175px;
+ box-shadow: 0 3px 1px -2px rgba(0,0,0,.2), 0 2px 2px 0 rgba(0,0,0,.14), 0 1px 5px 0 rgba(0,0,0,.12);
+ }
+}
+
+.show-all-btn.mat-raised-button .mat-button-wrapper > *{
+ vertical-align: baseline;
+}
+
+.resource-btns {
+ .mat-raised-button{
+ line-height: 38px;
+ }
+
+ .mat-select-value{
+ margin-top: 1px;
+ }
+}
+
+
+
diff --git a/services/self-service/src/main/resources/webapp/src/assets/styles/_variables.scss b/services/self-service/src/main/resources/webapp/src/assets/styles/_variables.scss
index ed038e7..e0d909d 100644
--- a/services/self-service/src/main/resources/webapp/src/assets/styles/_variables.scss
+++ b/services/self-service/src/main/resources/webapp/src/assets/styles/_variables.scss
@@ -20,6 +20,8 @@
$modal-text-color: #718aa5;
$modal-header-color: #f6fafe;
+$table-header-color: rgba(0,0,0,.54);
+
$brand-color: #4ab8dc;
$blue-grey-color: #718ba6;
$dark-grey-color: #455c74;
diff --git a/services/self-service/src/main/resources/webapp/src/styles.scss b/services/self-service/src/main/resources/webapp/src/styles.scss
index cc18983..a31908e 100644
--- a/services/self-service/src/main/resources/webapp/src/styles.scss
+++ b/services/self-service/src/main/resources/webapp/src/styles.scss
@@ -140,7 +140,9 @@
.terminating,
.failed,
.deleting,
-.deleted {
+.deleted,
+.invalid_version,
+.installation_error{
color: #f1696e;
}
@@ -174,6 +176,10 @@
font-size: 15px;
font-weight: 300;
color: #35afd5;
+ position: relative;
+ .buttons{
+ position: absolute;
+ }
}
.base-retreat {
@@ -371,6 +377,9 @@
text-align: center;
}
}
+#scrolling{
+ scrollbar-width: thin;
+}
#scrolling::-webkit-scrollbar,
.list-selected mat-chip-list .mat-chip-list-wrapper::-webkit-scrollbar {
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/KeycloakResourceTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/KeycloakResourceTest.java
index 37c4c5a..31ea3a3 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/KeycloakResourceTest.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/KeycloakResourceTest.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.resources;
import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
@@ -16,8 +35,12 @@
import javax.ws.rs.core.Response;
import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.*;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
public class KeycloakResourceTest extends TestBase {
private SecurityService securityService = mock(SecurityService.class);
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/LibExploratoryResourceTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/LibExploratoryResourceTest.java
index e0c7ed4..f1b9810 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/LibExploratoryResourceTest.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/LibExploratoryResourceTest.java
@@ -441,8 +441,7 @@
assertEquals(HttpStatus.SC_BAD_REQUEST, response.getStatus());
assertEquals(MediaType.APPLICATION_JSON, response.getHeaderString(HttpHeaders.CONTENT_TYPE));
- assertEquals("{\"errors\":[\"query param artifact Wrong library name format. Should be " +
- "<groupId>:<artifactId>:<versionId>. E.g. io.dropwizard:dropwizard-core:1.3.5\"]}",
+ assertEquals("{\"errors\":[\"query param artifact Wrong library name format. Should be <groupId>:<artifactId>:<versionId>\"]}",
response.readEntity(String.class));
verifyZeroInteractions(externalLibraryService);
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/ProjectResourceTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/ProjectResourceTest.java
index 7c78fed..1ea8115 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/ProjectResourceTest.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/ProjectResourceTest.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.resources;
import com.epam.dlab.auth.UserInfo;
@@ -31,81 +50,81 @@
public class ProjectResourceTest extends TestBase {
- private ProjectService projectService = mock(ProjectService.class);
- private AccessKeyService keyService = mock(AccessKeyService.class);
+ private ProjectService projectService = mock(ProjectService.class);
+ private AccessKeyService keyService = mock(AccessKeyService.class);
- @Rule
- public final ResourceTestRule resources = getResourceTestRuleInstance(
- new ProjectResource(projectService, keyService));
+ @Rule
+ public final ResourceTestRule resources = getResourceTestRuleInstance(
+ new ProjectResource(projectService, keyService));
- @Before
- public void setup() throws AuthenticationException {
- authSetup();
- }
+ @Before
+ public void setup() throws AuthenticationException {
+ authSetup();
+ }
- @Test
- public void stopProject() {
- final Response response = resources.getJerseyTest()
- .target("project/stop")
- .request()
- .header("Authorization", "Bearer " + TOKEN)
- .post(Entity.json(getProjectActionDTO()));
+ @Test
+ public void stopProject() {
+ final Response response = resources.getJerseyTest()
+ .target("project/stop")
+ .request()
+ .header("Authorization", "Bearer " + TOKEN)
+ .post(Entity.json(getProjectActionDTO()));
- assertEquals(HttpStatus.SC_ACCEPTED, response.getStatus());
- verify(projectService).stopWithResources(any(UserInfo.class), anyList(), anyString());
- verifyNoMoreInteractions(projectService);
- }
+ assertEquals(HttpStatus.SC_ACCEPTED, response.getStatus());
+ verify(projectService).stopWithResources(any(UserInfo.class), anyList(), anyString());
+ verifyNoMoreInteractions(projectService);
+ }
- @Test
- public void startProject() {
- final Response response = resources.getJerseyTest()
- .target("project/start")
- .request()
- .header("Authorization", "Bearer " + TOKEN)
- .post(Entity.json(getProjectActionDTO()));
+ @Test
+ public void startProject() {
+ final Response response = resources.getJerseyTest()
+ .target("project/start")
+ .request()
+ .header("Authorization", "Bearer " + TOKEN)
+ .post(Entity.json(getProjectActionDTO()));
- assertEquals(HttpStatus.SC_ACCEPTED, response.getStatus());
- verify(projectService).start(any(UserInfo.class), anyList(), anyString());
- verifyNoMoreInteractions(projectService);
- }
+ assertEquals(HttpStatus.SC_ACCEPTED, response.getStatus());
+ verify(projectService).start(any(UserInfo.class), anyList(), anyString());
+ verifyNoMoreInteractions(projectService);
+ }
- @Test
- public void generate() {
- when(keyService.generateKeys(any(UserInfo.class))).thenReturn(new KeysDTO("somePublicKey", "somePrivateKey",
- "user"));
+ @Test
+ public void generate() {
+ when(keyService.generateKeys(any(UserInfo.class))).thenReturn(new KeysDTO("somePublicKey", "somePrivateKey",
+ "user"));
- final Response response = resources.getJerseyTest()
- .target("/project/keys")
- .request()
- .header("Authorization", "Bearer " + TOKEN)
- .post(Entity.json(""));
+ final Response response = resources.getJerseyTest()
+ .target("/project/keys")
+ .request()
+ .header("Authorization", "Bearer " + TOKEN)
+ .post(Entity.json(""));
- assertEquals(HttpStatus.SC_OK, response.getStatus());
- assertEquals(MediaType.APPLICATION_JSON, response.getHeaderString(HttpHeaders.CONTENT_TYPE));
+ assertEquals(HttpStatus.SC_OK, response.getStatus());
+ assertEquals(MediaType.APPLICATION_JSON, response.getHeaderString(HttpHeaders.CONTENT_TYPE));
- verify(keyService).generateKeys(getUserInfo());
- verifyNoMoreInteractions(keyService);
- }
+ verify(keyService).generateKeys(getUserInfo());
+ verifyNoMoreInteractions(keyService);
+ }
- @Test
- public void generateKeysWithException() {
- doThrow(new DlabException("Can not generate private/public key pair due to"))
- .when(keyService).generateKeys(any(UserInfo.class));
+ @Test
+ public void generateKeysWithException() {
+ doThrow(new DlabException("Can not generate private/public key pair due to"))
+ .when(keyService).generateKeys(any(UserInfo.class));
- final Response response = resources.getJerseyTest()
- .target("/project/keys")
- .request()
- .header("Authorization", "Bearer " + TOKEN)
- .post(Entity.json(""));
+ final Response response = resources.getJerseyTest()
+ .target("/project/keys")
+ .request()
+ .header("Authorization", "Bearer " + TOKEN)
+ .post(Entity.json(""));
- assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, response.getStatus());
- assertEquals(MediaType.APPLICATION_JSON, response.getHeaderString(HttpHeaders.CONTENT_TYPE));
+ assertEquals(HttpStatus.SC_INTERNAL_SERVER_ERROR, response.getStatus());
+ assertEquals(MediaType.APPLICATION_JSON, response.getHeaderString(HttpHeaders.CONTENT_TYPE));
- verify(keyService).generateKeys(getUserInfo());
- verifyNoMoreInteractions(keyService);
- }
+ verify(keyService).generateKeys(getUserInfo());
+ verifyNoMoreInteractions(keyService);
+ }
- private ProjectActionFormDTO getProjectActionDTO() {
- return new ProjectActionFormDTO("DLAB", Collections.singletonList("https://localhost:8083/"));
- }
+ private ProjectActionFormDTO getProjectActionDTO() {
+ return new ProjectActionFormDTO("DLAB", Collections.singletonList("https://localhost:8083/"));
+ }
}
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/TestBase.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/TestBase.java
index ea6b9cc..37395a5 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/TestBase.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/resources/TestBase.java
@@ -20,8 +20,14 @@
package com.epam.dlab.backendapi.resources;
import com.epam.dlab.auth.UserInfo;
+import com.epam.dlab.backendapi.domain.EndpointDTO;
+import com.epam.dlab.cloud.CloudProvider;
import com.epam.dlab.rest.mappers.ResourceNotFoundExceptionMapper;
-import io.dropwizard.auth.*;
+import io.dropwizard.auth.AuthDynamicFeature;
+import io.dropwizard.auth.AuthValueFactoryProvider;
+import io.dropwizard.auth.AuthenticationException;
+import io.dropwizard.auth.Authenticator;
+import io.dropwizard.auth.Authorizer;
import io.dropwizard.auth.oauth.OAuthCredentialAuthFilter;
import io.dropwizard.testing.junit.ResourceTestRule;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
@@ -38,6 +44,11 @@
protected final String TOKEN = "TOKEN";
protected final String USER = "testUser";
+ protected final String ENDPOINT_NAME = "local";
+ protected final String ENDPOINT_URL = "http://localhost:8443/";
+ protected final String ENDPOINT_ACCOUNT = "account";
+ protected final String ENDPOINT_TAG = "tag";
+
@SuppressWarnings("unchecked")
private static Authenticator<String, UserInfo> authenticator = mock(Authenticator.class);
@SuppressWarnings("unchecked")
@@ -74,4 +85,8 @@
protected UserInfo getUserInfo() {
return new UserInfo(USER, TOKEN);
}
+
+ protected EndpointDTO getEndpointDTO() {
+ return new EndpointDTO(ENDPOINT_NAME, ENDPOINT_URL, ENDPOINT_ACCOUNT, ENDPOINT_TAG, EndpointDTO.EndpointStatus.ACTIVE, CloudProvider.AWS);
+ }
}
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/KeycloakServiceImplTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/KeycloakServiceImplTest.java
index 3c64dc6..d57efa2 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/KeycloakServiceImplTest.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/KeycloakServiceImplTest.java
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
package com.epam.dlab.backendapi.service;
import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
@@ -17,69 +36,73 @@
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class KeycloakServiceImplTest {
- private static final String ACCESS_TOKEN = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJNUC15QVpENFdJRzloa" +
- "np3R0RqQjdCeW9aNGpaV05QTjJ3X25uS1BkTnQ4In0.eyJqdGkiOiJlYTgzZTQ2OS0xNjFhLTQ1ZDUtYWI4YS1mZDUxYThmMzMwMzYiL" +
- "CJleHAiOjE1NzA0NDQ1NTQsIm5iZiI6MCwiaWF0IjoxNTcwNDQzMzU0LCJpc3MiOiJodHRwOi8vNTIuMTEuNDUuMTE6ODA4MC9hdXRoL" +
- "3JlYWxtcy9ETEFCX2JobGl2YSIsImF1ZCI6WyJwcm92aXNpb25pbmciLCJhY2NvdW50Il0sInN1YiI6ImRjNzczMThkLWYzN2UtNGNmO" +
- "S1iMDgwLTU2ZTRjMWUwNDVhNSIsInR5cCI6IkJlYXJlciIsImF6cCI6InNzcyIsImF1dGhfdGltZSI6MTU3MDQ0MzMyOSwic2Vzc2lvb" +
- "l9zdGF0ZSI6ImVkYTE3ODJjLTliZmItNDQ5Yy1hYWY1LWNhNzM5MDViMmI1NyIsImFjciI6IjEiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZ" +
- "XMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7InNzcyI6eyJyb2xlcyI6W" +
- "yJ0ZXN0Il19LCJwcm92aXNpb25pbmciOnsicm9sZXMiOlsidGVzdCJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3Vud" +
- "CIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSIsImVtY" +
- "WlsX3ZlcmlmaWVkIjpmYWxzZSwicHJlZmVycmVkX3VzZXJuYW1lIjoidGVzdCJ9.jXjqFP1xmG32NahYnw1spO7fhEyGiqeu0QdBYuo9" +
- "y6TI8xlAy5EFQ_5SrW6UuzpZUhgCjStH3Qkk_xgLlbZ9IqnxwOmx1i8arlurKf1mY_rm2_C5JBxHdHio8in8yEMls8t-wQOT46kMJNC7" +
- "4GUzuWWQxS1h6F1V6238rnT8_W27oFcG449ShOGOQ5Du4F9B4ur3Ns6j5oSduwUFlbY_rNpGurUmtFWXBaXM61CiezJPxXu5pHzWK6Xq" +
- "Z1IkuEUaDDJdBf1OGi13toq88V7C-Pr7YlnyWlbZ7bw2VXAs3NAgtn_30KlgYwR9YUJ_AB5TP3u8kK0jY0vLPosuBZgKeA";
- private static final String REFRESH_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImUyZjk0YjFmLTBhMjMtNGJi" +
- "OS05NDUwLTdjNDQ4MTdjY2RkMCJ9.eyJqdGkiOiI0NmNiMzczMy1mM2IzLTRiYjItYmQyZC02N2FjNzg5N2VmNTUiLCJleHAiOjE1NzA" +
- "0NDMzNTQsIm5iZiI6MCwiaWF0IjoxNTcwNDQzMzU0LCJpc3MiOiJodHRwOi8vNTIuMTEuNDUuMTE6ODA4MC9hdXRoL3JlYWxtcy9ETEF" +
- "CX2JobGl2YSIsImF1ZCI6Imh0dHA6Ly81Mi4xMS40NS4xMTo4MDgwL2F1dGgvcmVhbG1zL0RMQUJfYmhsaXZhIiwic3ViIjoiZGM3NzM" +
- "xOGQtZjM3ZS00Y2Y5LWIwODAtNTZlNGMxZTA0NWE1IiwidHlwIjoiUmVmcmVzaCIsImF6cCI6InNzcyIsImF1dGhfdGltZSI6MCwic2V" +
- "zc2lvbl9zdGF0ZSI6ImVkYTE3ODJjLTliZmItNDQ5Yy1hYWY1LWNhNzM5MDViMmI1NyIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJ" +
- "vZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsic3NzIjp7InJvbGVzIjpbInRlc3Q" +
- "iXX0sInByb3Zpc2lvbmluZyI6eyJyb2xlcyI6WyJ0ZXN0Il19LCJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWF" +
- "uYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIn0.rzkrAprIt0-" +
- "jD0h9ex3krzfu8UDcgnrRdocNFJmYa30";
- @Mock
- private Client httpClient;
- @Mock
- private SecurityDAO securityDAO;
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private SelfServiceApplicationConfiguration conf;
+ private static final String ACCESS_TOKEN = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJNUC15QVpENFdJRzloa" +
+ "np3R0RqQjdCeW9aNGpaV05QTjJ3X25uS1BkTnQ4In0.eyJqdGkiOiJlYTgzZTQ2OS0xNjFhLTQ1ZDUtYWI4YS1mZDUxYThmMzMwMzYiL" +
+ "CJleHAiOjE1NzA0NDQ1NTQsIm5iZiI6MCwiaWF0IjoxNTcwNDQzMzU0LCJpc3MiOiJodHRwOi8vNTIuMTEuNDUuMTE6ODA4MC9hdXRoL" +
+ "3JlYWxtcy9ETEFCX2JobGl2YSIsImF1ZCI6WyJwcm92aXNpb25pbmciLCJhY2NvdW50Il0sInN1YiI6ImRjNzczMThkLWYzN2UtNGNmO" +
+ "S1iMDgwLTU2ZTRjMWUwNDVhNSIsInR5cCI6IkJlYXJlciIsImF6cCI6InNzcyIsImF1dGhfdGltZSI6MTU3MDQ0MzMyOSwic2Vzc2lvb" +
+ "l9zdGF0ZSI6ImVkYTE3ODJjLTliZmItNDQ5Yy1hYWY1LWNhNzM5MDViMmI1NyIsImFjciI6IjEiLCJyZWFsbV9hY2Nlc3MiOnsicm9sZ" +
+ "XMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7InNzcyI6eyJyb2xlcyI6W" +
+ "yJ0ZXN0Il19LCJwcm92aXNpb25pbmciOnsicm9sZXMiOlsidGVzdCJdfSwiYWNjb3VudCI6eyJyb2xlcyI6WyJtYW5hZ2UtYWNjb3Vud" +
+ "CIsIm1hbmFnZS1hY2NvdW50LWxpbmtzIiwidmlldy1wcm9maWxlIl19fSwic2NvcGUiOiJvcGVuaWQgZW1haWwgcHJvZmlsZSIsImVtY" +
+ "WlsX3ZlcmlmaWVkIjpmYWxzZSwicHJlZmVycmVkX3VzZXJuYW1lIjoidGVzdCJ9.jXjqFP1xmG32NahYnw1spO7fhEyGiqeu0QdBYuo9" +
+ "y6TI8xlAy5EFQ_5SrW6UuzpZUhgCjStH3Qkk_xgLlbZ9IqnxwOmx1i8arlurKf1mY_rm2_C5JBxHdHio8in8yEMls8t-wQOT46kMJNC7" +
+ "4GUzuWWQxS1h6F1V6238rnT8_W27oFcG449ShOGOQ5Du4F9B4ur3Ns6j5oSduwUFlbY_rNpGurUmtFWXBaXM61CiezJPxXu5pHzWK6Xq" +
+ "Z1IkuEUaDDJdBf1OGi13toq88V7C-Pr7YlnyWlbZ7bw2VXAs3NAgtn_30KlgYwR9YUJ_AB5TP3u8kK0jY0vLPosuBZgKeA";
+ private static final String REFRESH_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImUyZjk0YjFmLTBhMjMtNGJi" +
+ "OS05NDUwLTdjNDQ4MTdjY2RkMCJ9.eyJqdGkiOiI0NmNiMzczMy1mM2IzLTRiYjItYmQyZC02N2FjNzg5N2VmNTUiLCJleHAiOjE1NzA" +
+ "0NDMzNTQsIm5iZiI6MCwiaWF0IjoxNTcwNDQzMzU0LCJpc3MiOiJodHRwOi8vNTIuMTEuNDUuMTE6ODA4MC9hdXRoL3JlYWxtcy9ETEF" +
+ "CX2JobGl2YSIsImF1ZCI6Imh0dHA6Ly81Mi4xMS40NS4xMTo4MDgwL2F1dGgvcmVhbG1zL0RMQUJfYmhsaXZhIiwic3ViIjoiZGM3NzM" +
+ "xOGQtZjM3ZS00Y2Y5LWIwODAtNTZlNGMxZTA0NWE1IiwidHlwIjoiUmVmcmVzaCIsImF6cCI6InNzcyIsImF1dGhfdGltZSI6MCwic2V" +
+ "zc2lvbl9zdGF0ZSI6ImVkYTE3ODJjLTliZmItNDQ5Yy1hYWY1LWNhNzM5MDViMmI1NyIsInJlYWxtX2FjY2VzcyI6eyJyb2xlcyI6WyJ" +
+ "vZmZsaW5lX2FjY2VzcyIsInVtYV9hdXRob3JpemF0aW9uIl19LCJyZXNvdXJjZV9hY2Nlc3MiOnsic3NzIjp7InJvbGVzIjpbInRlc3Q" +
+ "iXX0sInByb3Zpc2lvbmluZyI6eyJyb2xlcyI6WyJ0ZXN0Il19LCJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWF" +
+ "uYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6Im9wZW5pZCBlbWFpbCBwcm9maWxlIn0.rzkrAprIt0-" +
+ "jD0h9ex3krzfu8UDcgnrRdocNFJmYa30";
+ @Mock
+ private Client httpClient;
+ @Mock
+ private SecurityDAO securityDAO;
+ @Mock(answer = Answers.RETURNS_DEEP_STUBS)
+ private SelfServiceApplicationConfiguration conf;
- private KeycloakServiceImpl keycloakService;
+ private KeycloakServiceImpl keycloakService;
- @Before
- public void setUp() {
- keycloakService = new KeycloakServiceImpl(httpClient, conf, securityDAO);
- }
+ @Before
+ public void setUp() {
+ keycloakService = new KeycloakServiceImpl(httpClient, conf, securityDAO);
+ }
- @Test
- public void generateAccessToken() {
- WebTarget webTarget = mock(WebTarget.class);
- Invocation.Builder builder = mock(Invocation.Builder.class);
- Response response = mock(Response.class);
- Response.StatusType statusType = mock(Response.StatusType.class);
- AccessTokenResponse tokenResponse = mock(AccessTokenResponse.class);
+ @Test
+ public void generateAccessToken() {
+ WebTarget webTarget = mock(WebTarget.class);
+ Invocation.Builder builder = mock(Invocation.Builder.class);
+ Response response = mock(Response.class);
+ Response.StatusType statusType = mock(Response.StatusType.class);
+ AccessTokenResponse tokenResponse = mock(AccessTokenResponse.class);
- when(httpClient.target(anyString())).thenReturn(webTarget);
- when(webTarget.request()).thenReturn(builder);
- when(builder.header(any(), anyString())).thenReturn(builder);
- when(builder.post(any())).thenReturn(response);
- when(response.getStatusInfo()).thenReturn(statusType);
- when(response.readEntity(AccessTokenResponse.class)).thenReturn(tokenResponse);
- when(statusType.getFamily()).thenReturn(Response.Status.Family.SUCCESSFUL);
- when(tokenResponse.getToken()).thenReturn(ACCESS_TOKEN);
- doNothing().when(securityDAO).updateUser(anyString(), any(AccessTokenResponse.class));
+ when(httpClient.target(anyString())).thenReturn(webTarget);
+ when(webTarget.request()).thenReturn(builder);
+ when(builder.header(any(), anyString())).thenReturn(builder);
+ when(builder.post(any())).thenReturn(response);
+ when(response.getStatusInfo()).thenReturn(statusType);
+ when(response.readEntity(AccessTokenResponse.class)).thenReturn(tokenResponse);
+ when(statusType.getFamily()).thenReturn(Response.Status.Family.SUCCESSFUL);
+ when(tokenResponse.getToken()).thenReturn(ACCESS_TOKEN);
+ doNothing().when(securityDAO).updateUser(anyString(), any(AccessTokenResponse.class));
- keycloakService.generateAccessToken(REFRESH_TOKEN);
+ keycloakService.generateAccessToken(REFRESH_TOKEN);
- verify(httpClient).target(anyString());
- verify(securityDAO).updateUser("test", tokenResponse);
- verifyNoMoreInteractions(securityDAO, httpClient);
- }
+ verify(httpClient).target(anyString());
+ verify(securityDAO).updateUser("test", tokenResponse);
+ verifyNoMoreInteractions(securityDAO, httpClient);
+ }
}
\ No newline at end of file
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/ProjectServiceImplTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/ProjectServiceImplTest.java
new file mode 100644
index 0000000..a5c9ebf
--- /dev/null
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/ProjectServiceImplTest.java
@@ -0,0 +1,426 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.epam.dlab.backendapi.service;
+
+import com.epam.dlab.auth.UserInfo;
+import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
+import com.epam.dlab.backendapi.dao.ExploratoryDAO;
+import com.epam.dlab.backendapi.dao.ProjectDAO;
+import com.epam.dlab.backendapi.dao.UserGroupDAO;
+import com.epam.dlab.backendapi.domain.EndpointDTO;
+import com.epam.dlab.backendapi.domain.ProjectDTO;
+import com.epam.dlab.backendapi.domain.ProjectEndpointDTO;
+import com.epam.dlab.backendapi.domain.RequestId;
+import com.epam.dlab.backendapi.domain.UpdateProjectBudgetDTO;
+import com.epam.dlab.backendapi.resources.TestBase;
+import com.epam.dlab.backendapi.service.impl.ProjectServiceImpl;
+import com.epam.dlab.backendapi.util.RequestBuilder;
+import com.epam.dlab.dto.UserInstanceStatus;
+import com.epam.dlab.dto.project.ProjectActionDTO;
+import com.epam.dlab.dto.project.ProjectCreateDTO;
+import com.epam.dlab.exceptions.DlabException;
+import com.epam.dlab.exceptions.ResourceConflictException;
+import com.epam.dlab.exceptions.ResourceNotFoundException;
+import com.epam.dlab.rest.client.RESTService;
+import com.google.common.collect.Sets;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyBoolean;
+import static org.mockito.Matchers.anyListOf;
+import static org.mockito.Matchers.anySet;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ProjectServiceImplTest extends TestBase {
+ private static final String CREATE_PRJ_API = "infrastructure/project/create";
+ private static final String TERMINATE_PRJ_API = "infrastructure/project/terminate";
+ private static final String START_PRJ_API = "infrastructure/project/start";
+ private static final String STOP_PRJ_API = "infrastructure/project/stop";
+
+ private static final String NAME1 = "name1";
+ private static final String NAME2 = "name2";
+ private static final String GROUP1 = "group1";
+ private static final String GROUP2 = "group2";
+ private static final String UUID = "uuid";
+
+ private static final List<UserInstanceStatus> notebookStatuses = Arrays.asList(
+ UserInstanceStatus.CREATING, UserInstanceStatus.STARTING, UserInstanceStatus.CREATING_IMAGE,
+ UserInstanceStatus.CONFIGURING, UserInstanceStatus.RECONFIGURING, UserInstanceStatus.STOPPING,
+ UserInstanceStatus.TERMINATING);
+ private static final UserInstanceStatus[] computeStatuses = {UserInstanceStatus.CREATING, UserInstanceStatus.CONFIGURING, UserInstanceStatus.STARTING,
+ UserInstanceStatus.RECONFIGURING, UserInstanceStatus.CREATING_IMAGE, UserInstanceStatus.STOPPING,
+ UserInstanceStatus.TERMINATING};
+
+ @Mock
+ private ProjectDAO projectDAO;
+ @Mock
+ private EndpointService endpointService;
+ @Mock
+ private RESTService provisioningService;
+ @Mock
+ private RequestBuilder requestBuilder;
+ @Mock
+ private RequestId requestId;
+ @Mock
+ private ExploratoryService exploratoryService;
+ @Mock
+ private ExploratoryDAO exploratoryDAO;
+ @Mock
+ private UserGroupDAO userGroupDao;
+ @Mock
+ private SelfServiceApplicationConfiguration configuration;
+ @InjectMocks
+ private ProjectServiceImpl projectService;
+
+ @Test
+ public void getProjects() {
+ List<ProjectDTO> projectsMock = getProjectDTOs();
+ when(projectDAO.getProjects()).thenReturn(projectsMock);
+
+ List<ProjectDTO> projects = projectService.getProjects();
+
+ assertEquals(projects, projectsMock);
+ verify(projectDAO).getProjects();
+ verifyNoMoreInteractions(projectDAO);
+ }
+
+ @Test
+ public void testGetProjects() {
+ List<ProjectDTO> projectsMock = getProjectDTOs();
+ when(projectDAO.getProjects()).thenReturn(projectsMock);
+
+ projectService.getProjects(getUserInfo());
+
+ verify(projectDAO).getProjects();
+ verifyNoMoreInteractions(projectDAO);
+ }
+
+ @Test
+ public void getUserProjects() {
+ List<ProjectDTO> projectsMock = Collections.singletonList(getProjectCreatingDTO());
+ when(projectDAO.getUserProjects(any(UserInfo.class), anyBoolean())).thenReturn(projectsMock);
+
+ List<ProjectDTO> projects = projectService.getUserProjects(getUserInfo(), Boolean.TRUE);
+
+ assertEquals(projectsMock, projects);
+ verify(projectDAO).getUserProjects(getUserInfo(), Boolean.TRUE);
+ verifyNoMoreInteractions(projectDAO);
+ }
+
+ @Test
+ public void getProjectsByEndpoint() {
+ List<ProjectDTO> projectsMock = Collections.singletonList(getProjectCreatingDTO());
+ when(projectDAO.getProjectsByEndpoint(anyString())).thenReturn(projectsMock);
+
+ List<ProjectDTO> projects = projectService.getProjectsByEndpoint(ENDPOINT_NAME);
+
+ assertEquals(projectsMock, projects);
+ verify(projectDAO).getProjectsByEndpoint(ENDPOINT_NAME);
+ verifyNoMoreInteractions(projectDAO);
+ }
+
+ @Test
+ public void create() {
+ when(projectDAO.get(anyString())).thenReturn(Optional.empty());
+ when(endpointService.get(anyString())).thenReturn(getEndpointDTO());
+ when(provisioningService.post(anyString(), anyString(), any(), any())).thenReturn(UUID);
+ when(requestBuilder.newProjectCreate(any(UserInfo.class), any(ProjectDTO.class), any(EndpointDTO.class))).thenReturn(newProjectCreate());
+
+ ProjectDTO projectDTO = getProjectCreatingDTO();
+ projectService.create(getUserInfo(), projectDTO, projectDTO.getName());
+
+ verify(projectDAO).get(NAME1);
+ verify(projectDAO).create(projectDTO);
+ verify(endpointService).get(ENDPOINT_NAME);
+ verify(requestBuilder).newProjectCreate(getUserInfo(), projectDTO, getEndpointDTO());
+ verify(provisioningService).post(ENDPOINT_URL + CREATE_PRJ_API, TOKEN, newProjectCreate(), String.class);
+ verify(requestId).put(USER.toLowerCase(), UUID);
+ verifyNoMoreInteractions(projectDAO, endpointService, provisioningService, requestBuilder);
+ }
+
+ @Test(expected = ResourceConflictException.class)
+ public void createWithException() {
+ when(projectDAO.get(anyString())).thenReturn(Optional.of(getProjectCreatingDTO()));
+
+ ProjectDTO projectDTO = getProjectCreatingDTO();
+ projectService.create(getUserInfo(), projectDTO, projectDTO.getName());
+
+ verify(projectDAO).get(NAME1);
+ verifyNoMoreInteractions(projectDAO);
+ }
+
+ @Test
+ public void get() {
+ ProjectDTO projectMock = getProjectCreatingDTO();
+ when(projectDAO.get(anyString())).thenReturn(Optional.of(projectMock));
+
+ ProjectDTO project = projectService.get(NAME1);
+
+ assertEquals(projectMock, project);
+ verify(projectDAO).get(NAME1);
+ verifyNoMoreInteractions(projectDAO);
+ }
+
+ @Test(expected = ResourceNotFoundException.class)
+ public void getWithException() {
+ when(projectDAO.get(anyString())).thenReturn(Optional.empty());
+
+ projectService.get(NAME1);
+
+ verify(projectDAO).get(NAME1);
+ verifyNoMoreInteractions(projectDAO);
+ }
+
+ @Test
+ public void terminateEndpoint() {
+ when(endpointService.get(anyString())).thenReturn(getEndpointDTO());
+ when(provisioningService.post(anyString(), anyString(), any(), any())).thenReturn(UUID);
+ when(requestBuilder.newProjectAction(any(UserInfo.class), anyString(), any(EndpointDTO.class))).thenReturn(getProjectActionDTO());
+
+ projectService.terminateEndpoint(getUserInfo(), ENDPOINT_NAME, NAME1);
+
+ verify(exploratoryService).updateProjectExploratoryStatuses(getUserInfo(), NAME1, ENDPOINT_NAME, UserInstanceStatus.TERMINATING);
+ verify(projectDAO).updateEdgeStatus(NAME1, ENDPOINT_NAME, UserInstanceStatus.TERMINATING);
+ verify(endpointService).get(ENDPOINT_NAME);
+ verify(provisioningService).post(ENDPOINT_URL + TERMINATE_PRJ_API, TOKEN, getProjectActionDTO(), String.class);
+ verify(requestBuilder).newProjectAction(getUserInfo(), NAME1, getEndpointDTO());
+ verify(requestId).put(USER.toLowerCase(), UUID);
+ verifyNoMoreInteractions(projectDAO, endpointService, provisioningService, requestBuilder, exploratoryService);
+ }
+
+ @Test
+ public void terminateEndpointWithException() {
+ when(endpointService.get(anyString())).thenReturn(getEndpointDTO());
+ when(requestBuilder.newProjectAction(any(UserInfo.class), anyString(), any(EndpointDTO.class))).thenReturn(getProjectActionDTO());
+ when(provisioningService.post(anyString(), anyString(), any(), any())).thenThrow(new DlabException("Exception message"));
+
+ projectService.terminateEndpoint(getUserInfo(), ENDPOINT_NAME, NAME1);
+
+ verify(exploratoryService).updateProjectExploratoryStatuses(getUserInfo(), NAME1, ENDPOINT_NAME, UserInstanceStatus.TERMINATING);
+ verify(projectDAO).updateEdgeStatus(NAME1, ENDPOINT_NAME, UserInstanceStatus.TERMINATING);
+ verify(projectDAO).updateStatus(NAME1, ProjectDTO.Status.FAILED);
+ verify(endpointService).get(ENDPOINT_NAME);
+ verify(provisioningService).post(ENDPOINT_URL + TERMINATE_PRJ_API, TOKEN, getProjectActionDTO(), String.class);
+ verify(requestBuilder).newProjectAction(getUserInfo(), NAME1, getEndpointDTO());
+ verifyNoMoreInteractions(projectDAO, endpointService, provisioningService, requestBuilder, exploratoryService);
+ }
+
+ @Test
+ public void testTerminateEndpoint() {
+ when(endpointService.get(anyString())).thenReturn(getEndpointDTO());
+ when(provisioningService.post(anyString(), anyString(), any(), any())).thenReturn(UUID);
+ when(requestBuilder.newProjectAction(any(UserInfo.class), anyString(), any(EndpointDTO.class))).thenReturn(getProjectActionDTO());
+ when(projectDAO.get(anyString())).thenReturn(Optional.of(getProjectRunningDTO()));
+ when(exploratoryDAO.fetchProjectEndpointExploratoriesWhereStatusIn(anyString(), anyListOf(String.class), anyListOf(UserInstanceStatus.class)))
+ .thenReturn(Collections.emptyList());
+
+ projectService.terminateEndpoint(getUserInfo(), Collections.singletonList(ENDPOINT_NAME), NAME1);
+
+ verify(projectDAO).get(NAME1);
+ verify(exploratoryDAO).fetchProjectEndpointExploratoriesWhereStatusIn(NAME1, Collections.singletonList(ENDPOINT_NAME), notebookStatuses, computeStatuses);
+ verify(exploratoryService).updateProjectExploratoryStatuses(getUserInfo(), NAME1, ENDPOINT_NAME, UserInstanceStatus.TERMINATING);
+ verify(projectDAO).updateEdgeStatus(NAME1, ENDPOINT_NAME, UserInstanceStatus.TERMINATING);
+ verify(endpointService).get(ENDPOINT_NAME);
+ verify(provisioningService).post(ENDPOINT_URL + TERMINATE_PRJ_API, TOKEN, getProjectActionDTO(), String.class);
+ verify(requestBuilder).newProjectAction(getUserInfo(), NAME1, getEndpointDTO());
+ verify(requestId).put(USER.toLowerCase(), UUID);
+ verifyNoMoreInteractions(projectDAO, endpointService, provisioningService, requestBuilder, exploratoryDAO);
+ }
+
+ @Test(expected = ResourceConflictException.class)
+ public void testTerminateEndpointWithException1() {
+ when(projectDAO.get(anyString())).thenReturn(Optional.of(getProjectCreatingDTO()));
+
+ projectService.terminateEndpoint(getUserInfo(), Collections.singletonList(ENDPOINT_NAME), NAME1);
+
+ verify(projectDAO).get(NAME1);
+ verifyNoMoreInteractions(projectDAO);
+ }
+
+ @Test
+ public void start() {
+ when(endpointService.get(anyString())).thenReturn(getEndpointDTO());
+ when(provisioningService.post(anyString(), anyString(), any(), any())).thenReturn(UUID);
+ when(requestBuilder.newProjectAction(any(UserInfo.class), anyString(), any(EndpointDTO.class))).thenReturn(getProjectActionDTO());
+
+ projectService.start(getUserInfo(), ENDPOINT_NAME, NAME1);
+
+ verify(projectDAO).updateEdgeStatus(NAME1, ENDPOINT_NAME, UserInstanceStatus.STARTING);
+ verify(endpointService).get(ENDPOINT_NAME);
+ verify(provisioningService).post(ENDPOINT_URL + START_PRJ_API, TOKEN, getProjectActionDTO(), String.class);
+ verify(requestBuilder).newProjectAction(getUserInfo(), NAME1, getEndpointDTO());
+ verify(requestId).put(USER.toLowerCase(), UUID);
+ verifyNoMoreInteractions(projectDAO, endpointService, provisioningService, requestBuilder, requestId);
+ }
+
+ @Test
+ public void testStart() {
+ when(endpointService.get(anyString())).thenReturn(getEndpointDTO());
+ when(provisioningService.post(anyString(), anyString(), any(), any())).thenReturn(UUID);
+ when(requestBuilder.newProjectAction(any(UserInfo.class), anyString(), any(EndpointDTO.class))).thenReturn(getProjectActionDTO());
+
+ projectService.start(getUserInfo(), Collections.singletonList(ENDPOINT_NAME), NAME1);
+
+ verify(projectDAO).updateEdgeStatus(NAME1, ENDPOINT_NAME, UserInstanceStatus.STARTING);
+ verify(endpointService).get(ENDPOINT_NAME);
+ verify(provisioningService).post(ENDPOINT_URL + START_PRJ_API, TOKEN, getProjectActionDTO(), String.class);
+ verify(requestBuilder).newProjectAction(getUserInfo(), NAME1, getEndpointDTO());
+ verify(requestId).put(USER.toLowerCase(), UUID);
+ verifyNoMoreInteractions(projectDAO, endpointService, provisioningService, requestBuilder, requestId);
+ }
+
+ @Test
+ public void stop() {
+ when(endpointService.get(anyString())).thenReturn(getEndpointDTO());
+ when(provisioningService.post(anyString(), anyString(), any(), any())).thenReturn(UUID);
+ when(requestBuilder.newProjectAction(any(UserInfo.class), anyString(), any(EndpointDTO.class))).thenReturn(getProjectActionDTO());
+
+ projectService.stop(getUserInfo(), ENDPOINT_NAME, NAME1, null);
+
+ verify(projectDAO).updateEdgeStatus(NAME1, ENDPOINT_NAME, UserInstanceStatus.STOPPING);
+ verify(endpointService).get(ENDPOINT_NAME);
+ verify(provisioningService).post(ENDPOINT_URL + STOP_PRJ_API, TOKEN, getProjectActionDTO(), String.class);
+ verify(requestBuilder).newProjectAction(getUserInfo(), NAME1, getEndpointDTO());
+ verify(requestId).put(USER.toLowerCase(), UUID);
+ verifyNoMoreInteractions(projectDAO, endpointService, provisioningService, requestBuilder, requestId);
+ }
+
+ @Test
+ public void stopWithResources() {
+ when(endpointService.get(anyString())).thenReturn(getEndpointDTO());
+ when(provisioningService.post(anyString(), anyString(), any(), any())).thenReturn(UUID);
+ when(requestBuilder.newProjectAction(any(UserInfo.class), anyString(), any(EndpointDTO.class))).thenReturn(getProjectActionDTO());
+ when(projectDAO.get(anyString())).thenReturn(Optional.of(getProjectRunningDTO()));
+ when(exploratoryDAO.fetchProjectEndpointExploratoriesWhereStatusIn(anyString(), anyListOf(String.class), anyListOf(UserInstanceStatus.class)))
+ .thenReturn(Collections.emptyList());
+
+ projectService.stopWithResources(getUserInfo(), Collections.singletonList(ENDPOINT_NAME), NAME1);
+
+ verify(projectDAO).get(NAME1);
+ verify(exploratoryDAO).fetchProjectEndpointExploratoriesWhereStatusIn(NAME1, Collections.singletonList(ENDPOINT_NAME), notebookStatuses, computeStatuses);
+ verify(projectDAO).updateEdgeStatus(NAME1, ENDPOINT_NAME, UserInstanceStatus.STOPPING);
+ verify(endpointService).get(ENDPOINT_NAME);
+ verify(provisioningService).post(ENDPOINT_URL + STOP_PRJ_API, TOKEN, getProjectActionDTO(), String.class);
+ verify(requestBuilder).newProjectAction(getUserInfo(), NAME1, getEndpointDTO());
+ verify(requestId).put(USER.toLowerCase(), UUID);
+ verifyNoMoreInteractions(projectDAO, endpointService, provisioningService, requestBuilder, requestId);
+ }
+
+ @Test
+ public void update() {
+ }
+
+ @Test
+ public void updateBudget() {
+ projectService.updateBudget(getUserInfo(), Collections.singletonList(getUpdateProjectBudgetDTO()));
+
+ verify(projectDAO).updateBudget(NAME1, 10, true);
+ verifyNoMoreInteractions(projectDAO);
+ }
+
+ @Test
+ public void isAnyProjectAssigned() {
+ when(userGroupDao.getUserGroups(anyString())).thenReturn(Sets.newHashSet(GROUP1));
+ when(projectDAO.isAnyProjectAssigned(anySet())).thenReturn(Boolean.TRUE);
+
+ final boolean anyProjectAssigned = projectService.isAnyProjectAssigned(getUserInfo());
+
+ assertEquals(anyProjectAssigned, Boolean.TRUE);
+ verify(userGroupDao).getUserGroups(USER.toLowerCase());
+ verify(projectDAO).isAnyProjectAssigned(Sets.newHashSet(GROUP1));
+ verifyNoMoreInteractions(userGroupDao, projectDAO);
+ }
+
+ @Test
+ public void checkExploratoriesAndComputationalProgress() {
+ when(exploratoryDAO.fetchProjectEndpointExploratoriesWhereStatusIn(anyString(), anyListOf(String.class), anyListOf(UserInstanceStatus.class)))
+ .thenReturn(Collections.emptyList());
+
+ final boolean b = projectService.checkExploratoriesAndComputationalProgress(NAME1, Collections.singletonList(ENDPOINT_NAME));
+
+ assertEquals(b, Boolean.TRUE);
+ verify(exploratoryDAO).fetchProjectEndpointExploratoriesWhereStatusIn(NAME1, Collections.singletonList(ENDPOINT_NAME), notebookStatuses, computeStatuses);
+ verifyNoMoreInteractions(exploratoryDAO);
+ }
+
+ private List<ProjectDTO> getProjectDTOs() {
+ ProjectDTO project1 = ProjectDTO.builder()
+ .name(NAME1)
+ .groups(getGroup(GROUP1))
+ .build();
+ ProjectDTO project2 = ProjectDTO.builder()
+ .name(NAME2)
+ .groups(getGroup(GROUP2))
+ .build();
+ return Arrays.asList(project1, project2);
+ }
+
+ private ProjectDTO getProjectCreatingDTO() {
+ ProjectEndpointDTO projectEndpointDTO = new ProjectEndpointDTO(ENDPOINT_NAME, UserInstanceStatus.CREATING, null);
+ return ProjectDTO.builder()
+ .name(NAME1)
+ .groups(getGroup(GROUP1))
+ .endpoints(Collections.singletonList(projectEndpointDTO))
+ .build();
+ }
+
+ private ProjectDTO getProjectRunningDTO() {
+ ProjectEndpointDTO projectEndpointDTO = new ProjectEndpointDTO(ENDPOINT_NAME, UserInstanceStatus.RUNNING, null);
+ return ProjectDTO.builder()
+ .name(NAME1)
+ .groups(getGroup(GROUP1))
+ .endpoints(Collections.singletonList(projectEndpointDTO))
+ .build();
+ }
+
+ private Set<String> getGroup(String group) {
+ return Collections.singleton(group);
+ }
+
+ private ProjectCreateDTO newProjectCreate() {
+ return ProjectCreateDTO.builder()
+ .name(NAME1)
+ .endpoint(ENDPOINT_NAME)
+ .build();
+ }
+
+ private ProjectActionDTO getProjectActionDTO() {
+ return new ProjectActionDTO(NAME1, ENDPOINT_NAME);
+ }
+
+ private UpdateProjectBudgetDTO getUpdateProjectBudgetDTO() {
+ return new UpdateProjectBudgetDTO(NAME1, 10, true);
+ }
+}
\ No newline at end of file
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/UserRoleServiceImplTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/UserRoleServiceImplTest.java
index 883630c..ef7ac34 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/UserRoleServiceImplTest.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/UserRoleServiceImplTest.java
@@ -18,7 +18,7 @@
*/
package com.epam.dlab.backendapi.service;
-import com.epam.dlab.backendapi.dao.UserRoleDao;
+import com.epam.dlab.backendapi.dao.UserRoleDAO;
import com.epam.dlab.backendapi.resources.TestBase;
import com.epam.dlab.backendapi.resources.dto.UserRoleDto;
import com.epam.dlab.exceptions.ResourceNotFoundException;
@@ -39,15 +39,15 @@
@RunWith(MockitoJUnitRunner.class)
public class UserRoleServiceImplTest extends TestBase {
- private static final String ROLE_ID = "roleId";
- @Mock
- private UserRoleDao dao;
- @InjectMocks
- private UserRoleServiceImpl userRoleService;
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
+ private static final String ROLE_ID = "roleId";
+ @Mock
+ private UserRoleDAO dao;
+ @InjectMocks
+ private UserRoleServiceImpl userRoleService;
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
- @Test
+ @Test
public void createRole() {
userRoleService.createRole(getUserRole());
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/AccessKeyServiceImplTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/AccessKeyServiceImplTest.java
new file mode 100644
index 0000000..f064c42
--- /dev/null
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/AccessKeyServiceImplTest.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.epam.dlab.backendapi.service.impl;
+
+import com.epam.dlab.auth.UserInfo;
+import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
+import com.epam.dlab.backendapi.resources.TestBase;
+import com.epam.dlab.backendapi.resources.dto.KeysDTO;
+import com.epam.dlab.exceptions.DlabException;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AccessKeyServiceImplTest extends TestBase {
+
+ @Mock
+ private SelfServiceApplicationConfiguration conf;
+
+ @InjectMocks
+ private AccessKeyServiceImpl accessKeyService;
+
+
+ @Test
+ public void generateKeys() {
+ UserInfo userInfo = getUserInfo();
+ when(conf.getPrivateKeySize()).thenReturn(2048);
+
+ KeysDTO keysDTO = accessKeyService.generateKeys(userInfo);
+
+ assertEquals("Usernames are not equal", USER.toLowerCase(), keysDTO.getUsername());
+ assertNotNull("Public key is null", keysDTO.getPublicKey());
+ assertNotNull("Private key is null", keysDTO.getPrivateKey());
+ }
+
+ @Test(expected = DlabException.class)
+ public void generateKeysWithException() {
+ UserInfo userInfo = getUserInfo();
+ when(conf.getPrivateKeySize()).thenReturn(0);
+
+ accessKeyService.generateKeys(userInfo);
+ }
+}
\ No newline at end of file
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/AuditServiceImplTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/AuditServiceImplTest.java
new file mode 100644
index 0000000..da0c002
--- /dev/null
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/AuditServiceImplTest.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.epam.dlab.backendapi.service.impl;
+
+import com.epam.dlab.backendapi.dao.AuditDAO;
+import com.epam.dlab.backendapi.domain.AuditActionEnum;
+import com.epam.dlab.backendapi.domain.AuditCreateDTO;
+import com.epam.dlab.backendapi.domain.AuditDTO;
+import com.epam.dlab.backendapi.domain.AuditResourceTypeEnum;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.refEq;
+import static org.mockito.Mockito.verify;
+
+@RunWith(MockitoJUnitRunner.class)
+public class AuditServiceImplTest {
+ private static final String USER = "user";
+ private static final String PROJECT = "project";
+ private static final String RESOURCE_NAME = "resourceName";
+ private static final String INFO = "info";
+
+ @Mock
+ private AuditDAO auditDAO;
+ @InjectMocks
+ private AuditServiceImpl auditService;
+
+ @Test
+ public void save() {
+ AuditDTO auditDTO = getAuditDTO();
+
+ auditService.save(auditDTO);
+
+ verify(auditDAO).save(refEq(auditDTO));
+ }
+
+ @Test
+ public void testSave() {
+ AuditCreateDTO auditCreateDTO = getAuditCreateDTO();
+
+ auditService.save(USER, auditCreateDTO);
+
+ verify(auditDAO).save(eq(getAuditDTO(USER, auditCreateDTO)));
+ }
+
+ @Test
+ public void getAudit() {
+ List<String> users = new ArrayList<>();
+ List<String> projects = new ArrayList<>();
+ List<String> resourceNames = new ArrayList<>();
+ List<String> resourceTypes = new ArrayList<>();
+ String dateStart = "";
+ String dateEnd = "";
+ int pageNumber = 1;
+ int pageSize = 10;
+
+ auditService.getAudit(users, projects, resourceNames, resourceTypes, dateStart, dateEnd, pageNumber, pageSize);
+
+ verify(auditDAO).getAudit(refEq(users), refEq(projects), refEq(resourceNames), refEq(resourceTypes), eq(dateStart), eq(dateEnd), eq(pageNumber), eq(pageSize));
+ }
+
+ private AuditDTO getAuditDTO() {
+ return AuditDTO.builder()
+ .user(USER)
+ .project(PROJECT)
+ .build();
+ }
+
+ private AuditDTO getAuditDTO(String user, AuditCreateDTO auditCreateDTO) {
+ return AuditDTO.builder()
+ .user(user)
+ .resourceName(auditCreateDTO.getResourceName())
+ .info(auditCreateDTO.getInfo())
+ .type(auditCreateDTO.getType())
+ .action(AuditActionEnum.FOLLOW_LINK)
+ .build();
+ }
+
+ private AuditCreateDTO getAuditCreateDTO() {
+ return new AuditCreateDTO(RESOURCE_NAME, INFO, AuditResourceTypeEnum.COMPUTE);
+ }
+}
\ No newline at end of file
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/BackupServiceImplTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/BackupServiceImplTest.java
index 4a27bb5..e8916e8 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/BackupServiceImplTest.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/BackupServiceImplTest.java
@@ -20,7 +20,7 @@
package com.epam.dlab.backendapi.service.impl;
import com.epam.dlab.auth.UserInfo;
-import com.epam.dlab.backendapi.dao.BackupDao;
+import com.epam.dlab.backendapi.dao.BackupDAO;
import com.epam.dlab.backendapi.resources.dto.BackupInfoRecord;
import com.epam.dlab.dto.backup.EnvBackupDTO;
import com.epam.dlab.dto.backup.EnvBackupStatus;
@@ -41,7 +41,16 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.refEq;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class BackupServiceImplTest {
@@ -51,7 +60,7 @@
@Mock
private RESTService provisioningService;
@Mock
- private BackupDao backupDao;
+ private BackupDAO backupDao;
@InjectMocks
private BackupServiceImpl backupService;
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/BucketServiceImplTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/BucketServiceImplTest.java
new file mode 100644
index 0000000..641100d
--- /dev/null
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/BucketServiceImplTest.java
@@ -0,0 +1,262 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package com.epam.dlab.backendapi.service.impl;
+
+import com.epam.dlab.backendapi.domain.EndpointDTO;
+import com.epam.dlab.backendapi.resources.TestBase;
+import com.epam.dlab.backendapi.service.EndpointService;
+import com.epam.dlab.dto.bucket.BucketDTO;
+import com.epam.dlab.dto.bucket.BucketDeleteDTO;
+import com.epam.dlab.dto.bucket.FolderUploadDTO;
+import com.epam.dlab.exceptions.DlabException;
+import com.epam.dlab.rest.client.RESTService;
+import org.apache.http.HttpStatus;
+import org.glassfish.jersey.media.multipart.FormDataMultiPart;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import javax.ws.rs.core.GenericType;
+import javax.ws.rs.core.Response;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collections;
+import java.util.List;
+
+import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
+import static javax.ws.rs.core.MediaType.APPLICATION_OCTET_STREAM;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.when;
+
+@RunWith(MockitoJUnitRunner.class)
+public class BucketServiceImplTest extends TestBase {
+ private static final String BUCKET_GET_OBJECTS = "%sbucket/%s";
+ private static final String BUCKET_UPLOAD_OBJECT = "%sbucket/upload";
+ private static final String BUCKET_UPLOAD_FOLDER = "%sbucket/folder/upload";
+ private static final String BUCKET_DOWNLOAD_OBJECT = "%sbucket/%s/object/%s/download";
+ private static final String BUCKET_DELETE_OBJECT = "%sbucket/objects/delete";
+ private static final String BUCKET = "bucket";
+ private static final String OBJECT = "object";
+ private static final String SIZE = "size";
+ private static final String DATE = "date";
+ private static final String FOLDER = "folder/";
+
+ @Mock
+ private EndpointService endpointService;
+ @Mock
+ private RESTService provisioningService;
+ @InjectMocks
+ private BucketServiceImpl bucketService;
+
+ @Test
+ public void getObjects() {
+ EndpointDTO endpointDTO = getEndpointDTO();
+ List<BucketDTO> objects = getBucketList();
+ when(endpointService.get(anyString())).thenReturn(endpointDTO);
+ when(provisioningService.get(anyString(), anyString(), any(GenericType.class))).thenReturn(objects);
+
+ List<BucketDTO> actualObjects = bucketService.getObjects(getUserInfo(), BUCKET, ENDPOINT_NAME);
+
+ assertEquals("lists should be equal", objects, actualObjects);
+ verify(endpointService).get(ENDPOINT_NAME);
+ verify(provisioningService).get(String.format(BUCKET_GET_OBJECTS, ENDPOINT_URL, BUCKET), TOKEN, new GenericType<List<BucketDTO>>() {
+ });
+ verifyNoMoreInteractions(endpointService, provisioningService);
+ }
+
+ @Test(expected = DlabException.class)
+ public void getObjectsWithException() {
+ EndpointDTO endpointDTO = getEndpointDTO();
+ when(endpointService.get(anyString())).thenReturn(endpointDTO);
+ when(provisioningService.get(anyString(), anyString(), any(GenericType.class))).thenThrow(new DlabException("Exception message"));
+
+ bucketService.getObjects(getUserInfo(), BUCKET, ENDPOINT_NAME);
+
+ verify(endpointService).get(ENDPOINT_NAME);
+ verify(provisioningService).get(String.format(BUCKET_GET_OBJECTS, ENDPOINT_URL, BUCKET), TOKEN, new GenericType<List<BucketDTO>>() {
+ });
+
+ verifyNoMoreInteractions(endpointService, provisioningService);
+ }
+
+ @Test
+ public void uploadObject() {
+ EndpointDTO endpointDTO = getEndpointDTO();
+ Response response = Response.ok().build();
+ when(endpointService.get(anyString())).thenReturn(endpointDTO);
+ when(provisioningService.postForm(anyString(), anyString(), any(FormDataMultiPart.class), any())).thenReturn(response);
+
+ bucketService.uploadObject(getUserInfo(), BUCKET, OBJECT, ENDPOINT_NAME, getInputStream(), APPLICATION_JSON, 0, null);
+
+ verify(endpointService).get(ENDPOINT_NAME);
+ verify(provisioningService).postForm(eq(String.format(BUCKET_UPLOAD_OBJECT, ENDPOINT_URL)), eq(TOKEN), any(FormDataMultiPart.class), eq(Response.class));
+ verifyNoMoreInteractions(endpointService, provisioningService);
+ }
+
+ @Test(expected = DlabException.class)
+ public void uploadObjectWithException1() {
+ EndpointDTO endpointDTO = getEndpointDTO();
+ Response response = Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).build();
+ when(endpointService.get(anyString())).thenReturn(endpointDTO);
+ when(provisioningService.postForm(anyString(), anyString(), any(FormDataMultiPart.class), any())).thenReturn(response);
+
+ bucketService.uploadObject(getUserInfo(), BUCKET, OBJECT, ENDPOINT_NAME, getInputStream(), APPLICATION_JSON, 0, null);
+
+ verify(endpointService).get(ENDPOINT_NAME);
+ verify(provisioningService).postForm(eq(String.format(BUCKET_UPLOAD_OBJECT, ENDPOINT_URL)), eq(TOKEN), any(FormDataMultiPart.class), eq(Response.class));
+ verifyNoMoreInteractions(endpointService, provisioningService);
+ }
+
+ @Test(expected = DlabException.class)
+ public void uploadObjectWithException2() {
+ EndpointDTO endpointDTO = getEndpointDTO();
+ when(endpointService.get(anyString())).thenReturn(endpointDTO);
+
+ bucketService.uploadObject(getUserInfo(), BUCKET, OBJECT, ENDPOINT_NAME, null, APPLICATION_JSON, 0, null);
+
+ verify(endpointService).get(ENDPOINT_NAME);
+ verifyNoMoreInteractions(endpointService, provisioningService);
+ }
+
+ @Test
+ public void uploadFolder() {
+ EndpointDTO endpointDTO = getEndpointDTO();
+ Response response = Response.ok().build();
+ when(endpointService.get(anyString())).thenReturn(endpointDTO);
+ when(provisioningService.post(anyString(), anyString(), any(FolderUploadDTO.class), any())).thenReturn(response);
+
+ bucketService.uploadFolder(getUserInfo(), BUCKET, FOLDER, ENDPOINT_NAME, null);
+
+ verify(endpointService).get(ENDPOINT_NAME);
+ verify(provisioningService).post(eq(String.format(BUCKET_UPLOAD_FOLDER, ENDPOINT_URL)), eq(TOKEN), eq(getFolderUploadDTO()), eq(Response.class));
+ verifyNoMoreInteractions(endpointService, provisioningService);
+ }
+
+ @Test(expected = DlabException.class)
+ public void uploadFolderWithException1() {
+ EndpointDTO endpointDTO = getEndpointDTO();
+ Response response = Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).build();
+ when(endpointService.get(anyString())).thenReturn(endpointDTO);
+ when(provisioningService.post(anyString(), anyString(), any(FolderUploadDTO.class), any())).thenReturn(response);
+
+ bucketService.uploadFolder(getUserInfo(), BUCKET, FOLDER, ENDPOINT_NAME, null);
+
+ verify(endpointService).get(ENDPOINT_NAME);
+ verify(provisioningService).post(eq(String.format(BUCKET_UPLOAD_FOLDER, ENDPOINT_URL)), eq(TOKEN), eq(getFolderUploadDTO()), eq(Response.class));
+ verifyNoMoreInteractions(endpointService, provisioningService);
+ }
+
+ @Test(expected = DlabException.class)
+ public void uploadFolderWithException2() {
+ bucketService.uploadFolder(getUserInfo(), BUCKET, "folder_name_without_slash", ENDPOINT_NAME, null);
+ }
+
+ @Test
+ public void downloadObject() throws IOException {
+ EndpointDTO endpointDTO = getEndpointDTO();
+ HttpServletResponse response = mock(HttpServletResponse.class);
+ ServletOutputStream outputStream = mock(ServletOutputStream.class);
+ when(endpointService.get(anyString())).thenReturn(endpointDTO);
+ when(provisioningService.getWithMediaTypes(anyString(), anyString(), any(), anyString(), anyString())).thenReturn(getInputStream());
+ when(response.getOutputStream()).thenReturn(outputStream);
+
+ bucketService.downloadObject(getUserInfo(), BUCKET, OBJECT, ENDPOINT_NAME, response, null);
+
+ verify(endpointService).get(ENDPOINT_NAME);
+ verify(provisioningService).getWithMediaTypes(eq(String.format(BUCKET_DOWNLOAD_OBJECT, ENDPOINT_URL, BUCKET, OBJECT)), eq(TOKEN), eq(InputStream.class),
+ eq(APPLICATION_JSON), eq(APPLICATION_OCTET_STREAM));
+ verifyNoMoreInteractions(endpointService, provisioningService);
+ }
+
+ @Test(expected = DlabException.class)
+ public void downloadObjectWithException() {
+ EndpointDTO endpointDTO = getEndpointDTO();
+ HttpServletResponse response = mock(HttpServletResponse.class);
+ when(endpointService.get(anyString())).thenReturn(endpointDTO);
+ when(provisioningService.getWithMediaTypes(anyString(), anyString(), any(), anyString(), anyString())).thenThrow(new DlabException("Exception message"));
+
+ bucketService.downloadObject(getUserInfo(), BUCKET, OBJECT, ENDPOINT_NAME, response, null);
+
+ verify(endpointService).get(ENDPOINT_NAME);
+ verify(provisioningService).getWithMediaTypes(eq(String.format(BUCKET_DOWNLOAD_OBJECT, ENDPOINT_URL, BUCKET, OBJECT)), eq(TOKEN), eq(InputStream.class),
+ eq(APPLICATION_JSON), eq(APPLICATION_OCTET_STREAM));
+ verifyNoMoreInteractions(endpointService, provisioningService);
+ }
+
+ @Test
+ public void deleteObjects() {
+ EndpointDTO endpointDTO = getEndpointDTO();
+ Response response = Response.ok().build();
+ when(endpointService.get(anyString())).thenReturn(endpointDTO);
+ when(provisioningService.post(anyString(), anyString(), any(BucketDeleteDTO.class), any())).thenReturn(response);
+
+ bucketService.deleteObjects(getUserInfo(), BUCKET, Collections.singletonList(OBJECT), ENDPOINT_NAME, null);
+
+ verify(endpointService).get(ENDPOINT_NAME);
+ verify(provisioningService).post(eq(String.format(BUCKET_DELETE_OBJECT, ENDPOINT_URL)), eq(TOKEN), eq(getBucketDeleteDTO()), eq(Response.class));
+ verifyNoMoreInteractions(endpointService, provisioningService);
+ }
+
+ @Test(expected = DlabException.class)
+ public void deleteObjectsWithException() {
+ EndpointDTO endpointDTO = getEndpointDTO();
+ Response response = Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).build();
+ when(endpointService.get(anyString())).thenReturn(endpointDTO);
+ when(provisioningService.post(anyString(), anyString(), any(BucketDeleteDTO.class), any())).thenReturn(response);
+
+ bucketService.deleteObjects(getUserInfo(), BUCKET, Collections.singletonList(OBJECT), ENDPOINT_NAME, null);
+
+ verify(endpointService).get(ENDPOINT_NAME);
+ verify(provisioningService).post(eq(String.format(BUCKET_DELETE_OBJECT, ENDPOINT_URL)), eq(TOKEN), eq(getBucketDeleteDTO()), eq(Response.class));
+ verifyNoMoreInteractions(endpointService, provisioningService);
+ }
+
+ private List<BucketDTO> getBucketList() {
+ return Collections.singletonList(BucketDTO.builder()
+ .bucket(BUCKET)
+ .object(OBJECT)
+ .size(SIZE)
+ .lastModifiedDate(DATE)
+ .build());
+ }
+
+ private FolderUploadDTO getFolderUploadDTO() {
+ return new FolderUploadDTO(BUCKET, FOLDER);
+ }
+
+ private BucketDeleteDTO getBucketDeleteDTO() {
+ return new BucketDeleteDTO(BUCKET, Collections.singletonList(OBJECT));
+ }
+
+ private ByteArrayInputStream getInputStream() {
+ return new ByteArrayInputStream("input stream".getBytes());
+ }
+}
\ No newline at end of file
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/ImageExploratoryServiceImplTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/ImageExploratoryServiceImplTest.java
index 85d6015..ded7347 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/ImageExploratoryServiceImplTest.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/ImageExploratoryServiceImplTest.java
@@ -22,7 +22,7 @@
import com.epam.dlab.auth.UserInfo;
import com.epam.dlab.backendapi.dao.ExploratoryDAO;
import com.epam.dlab.backendapi.dao.ExploratoryLibDAO;
-import com.epam.dlab.backendapi.dao.ImageExploratoryDao;
+import com.epam.dlab.backendapi.dao.ImageExploratoryDAO;
import com.epam.dlab.backendapi.domain.EndpointDTO;
import com.epam.dlab.backendapi.domain.ProjectDTO;
import com.epam.dlab.backendapi.resources.dto.ImageInfoRecord;
@@ -84,7 +84,7 @@
@Mock
private ExploratoryDAO exploratoryDAO;
@Mock
- private ImageExploratoryDao imageExploratoryDao;
+ private ImageExploratoryDAO imageExploratoryDao;
@Mock
private ExploratoryLibDAO libDAO;
@Mock
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/InfrastructureTemplateServiceBaseTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/InfrastructureTemplateServiceBaseTest.java
index 97079e3..769b0de 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/InfrastructureTemplateServiceBaseTest.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/InfrastructureTemplateServiceBaseTest.java
@@ -23,7 +23,7 @@
import com.epam.dlab.backendapi.conf.SelfServiceApplicationConfiguration;
import com.epam.dlab.backendapi.dao.ProjectDAO;
import com.epam.dlab.backendapi.dao.SettingsDAO;
-import com.epam.dlab.backendapi.dao.UserGroupDao;
+import com.epam.dlab.backendapi.dao.UserGroupDAO;
import com.epam.dlab.backendapi.domain.EndpointDTO;
import com.epam.dlab.backendapi.domain.ProjectDTO;
import com.epam.dlab.backendapi.service.EndpointService;
@@ -71,7 +71,7 @@
@Mock
private EndpointService endpointService;
@Mock
- private UserGroupDao userGroupDao;
+ private UserGroupDAO userGroupDao;
@Mock
private SelfServiceApplicationConfiguration configuration;
diff --git a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/UserGroupServiceImplTest.java b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/UserGroupServiceImplTest.java
index 0e4b3d2..3b3e901 100644
--- a/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/UserGroupServiceImplTest.java
+++ b/services/self-service/src/test/java/com/epam/dlab/backendapi/service/impl/UserGroupServiceImplTest.java
@@ -20,8 +20,8 @@
package com.epam.dlab.backendapi.service.impl;
import com.epam.dlab.backendapi.dao.ProjectDAO;
-import com.epam.dlab.backendapi.dao.UserGroupDao;
-import com.epam.dlab.backendapi.dao.UserRoleDao;
+import com.epam.dlab.backendapi.dao.UserGroupDAO;
+import com.epam.dlab.backendapi.dao.UserRoleDAO;
import com.epam.dlab.backendapi.domain.ProjectDTO;
import com.epam.dlab.backendapi.resources.TestBase;
import com.epam.dlab.backendapi.resources.dto.UserGroupDto;
@@ -54,25 +54,25 @@
@RunWith(MockitoJUnitRunner.class)
public class UserGroupServiceImplTest extends TestBase {
- private static final String ROLE_ID = "Role id";
- private static final String USER = "test";
- private static final String GROUP = "admin";
- @Mock
- private UserRoleDao userRoleDao;
- @Mock
- private UserGroupDao userGroupDao;
- @Mock
- private ProjectDAO projectDAO;
- @InjectMocks
- private UserGroupServiceImpl userGroupService;
+ private static final String ROLE_ID = "Role id";
+ private static final String USER = "test";
+ private static final String GROUP = "admin";
+ @Mock
+ private UserRoleDAO userRoleDao;
+ @Mock
+ private UserGroupDAO userGroupDao;
+ @Mock
+ private ProjectDAO projectDAO;
+ @InjectMocks
+ private UserGroupServiceImpl userGroupService;
- @Rule
- public ExpectedException expectedException = ExpectedException.none();
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
- @Before
- public void setup() throws AuthenticationException {
- authSetup();
- }
+ @Before
+ public void setup() throws AuthenticationException {
+ authSetup();
+ }
@Test
public void createGroup() {