diff options
-rw-r--r-- | kud/deployment_infra/playbooks/configure-onap4k8s.yml | 8 | ||||
-rw-r--r-- | kud/hosting_providers/containerized/README.md | 2 | ||||
-rwxr-xr-x | kud/hosting_providers/containerized/installer.sh | 36 | ||||
-rwxr-xr-x | kud/hosting_providers/vagrant/installer.sh | 23 | ||||
-rw-r--r-- | src/k8splugin/Makefile | 6 | ||||
-rw-r--r-- | src/k8splugin/api/instancehandler.go | 62 | ||||
-rw-r--r-- | src/k8splugin/go.mod | 1 | ||||
-rw-r--r-- | src/k8splugin/internal/app/client.go | 40 | ||||
-rw-r--r-- | src/k8splugin/internal/logutils/logger.go | 28 |
9 files changed, 173 insertions, 33 deletions
diff --git a/kud/deployment_infra/playbooks/configure-onap4k8s.yml b/kud/deployment_infra/playbooks/configure-onap4k8s.yml index cacb41c9..11729171 100644 --- a/kud/deployment_infra/playbooks/configure-onap4k8s.yml +++ b/kud/deployment_infra/playbooks/configure-onap4k8s.yml @@ -19,6 +19,14 @@ repo: 'https://github.com/onap/multicloud-k8s.git' dest: /opt/multicloud + - name: install make package for ubuntu systems + apt: name=make state=present update_cache=yes + when: ansible_distribution == "Ubuntu" + + - name: install make package for centos systems + yum: name=make state=present update_cache=yes + when: ansible_distribution == "CentOS" + - name: Change the onap4k8s directory and run the command make repo command: /usr/bin/make repo register: make_repo diff --git a/kud/hosting_providers/containerized/README.md b/kud/hosting_providers/containerized/README.md index 4119ca78..d1659629 100644 --- a/kud/hosting_providers/containerized/README.md +++ b/kud/hosting_providers/containerized/README.md @@ -100,7 +100,7 @@ spec: - name: secret-volume mountPath: "/.ssh" command: ["/bin/sh","-c"] - args: ["cp -r /.ssh /root/; chmod -R 600 /root/.ssh; ./installer --cluster $CLUSTER_NAME"] + args: ["cp -r /.ssh /root/; chmod -R 600 /root/.ssh; ./installer --cluster $CLUSTER_NAME --plugins onap4k8s"] securityContext: privileged: true volumes: diff --git a/kud/hosting_providers/containerized/installer.sh b/kud/hosting_providers/containerized/installer.sh index 52fe6279..ad44dc56 100755 --- a/kud/hosting_providers/containerized/installer.sh +++ b/kud/hosting_providers/containerized/installer.sh @@ -20,7 +20,7 @@ function install_prerequisites { apt-get update apt-get install -y curl vim wget git \ software-properties-common python-pip - add-apt-repository ppa:longsleep/golang-backports + add-apt-repository -y ppa:longsleep/golang-backports apt-get update apt-get install -y golang-go rsync } @@ -100,7 +100,14 @@ function install_k8s { # install_addons() - Install Kubenertes AddOns function install_addons { - local plugins_name=$1 + if [ ${1:+1} ]; then + local plugins_name="$1" + echo "additional addons plugins $1" + else + local plugins_name="" + echo "no additional addons pluigns" + fi + source /etc/environment echo "Installing Kubernetes AddOns" ansible-galaxy install $verbose -r \ @@ -109,17 +116,22 @@ function install_addons { ansible-playbook $verbose -i \ $kud_inventory $kud_playbooks/configure-kud.yml | \ tee $cluster_log/setup-kud.log - for addon in ${KUD_ADDONS:-virtlet ovn4nfv nfd $plugins_name}; do + for addon in ${KUD_ADDONS:-virtlet ovn4nfv nfd sriov $plugins_name}; do echo "Deploying $addon using configure-$addon.yml playbook.." ansible-playbook $verbose -i \ $kud_inventory $kud_playbooks/configure-${addon}.yml | \ tee $cluster_log/setup-${addon}.log - if [[ "${testing_enabled}" == "true" ]]; then + done + + echo "Run the test cases if testing_enabled is set to true." + if [[ "${testing_enabled}" == "true" ]]; then + for addon in ${KUD_ADDONS:-virtlet ovn4nfv nfd sriov $plugins_name}; do pushd $kud_tests bash ${addon}.sh popd - fi - done + done + fi + echo "Add-ons deployment complete..." } # install_plugin() - Install ONAP Multicloud Kubernetes plugin @@ -189,7 +201,13 @@ function install_pkg { function install_cluster { install_k8s $1 - install_addons $2 + if [ ${2:+1} ]; then + echo "install default addons and $2" + install_addons "$2" + else + install_addons + fi + echo "installed the addons" if ${KUD_PLUGIN_ENABLED:-false}; then install_plugin @@ -254,7 +272,7 @@ if [ "$1" == "--cluster" ]; then cp $kud_multi_cluster_path/$cluster_name/hosts.ini $kud_inventory_folder/ cp -rf $kud_folder/inventory/group_vars $kud_inventory_folder/ - if [ -n "$3" ]; then + if [ ${3:+1} ]; then if [ "$3" == "--plugins" ]; then if [ -z "${4-}" ]; then echo "Error: plugins arguments is null; Refer the usage" @@ -262,7 +280,7 @@ if [ "$1" == "--cluster" ]; then exit 1 fi plugins_name=${@:4:$#} - install_cluster $cluster_name $plugins_name + install_cluster $cluster_name "$plugins_name" exit 0 else echo "Error: cluster argument should have plugins; \ diff --git a/kud/hosting_providers/vagrant/installer.sh b/kud/hosting_providers/vagrant/installer.sh index 5cc701db..235736e1 100755 --- a/kud/hosting_providers/vagrant/installer.sh +++ b/kud/hosting_providers/vagrant/installer.sh @@ -21,6 +21,11 @@ function _install_go { version=$(grep "go_version" ${kud_playbooks}/kud-vars.yml | awk -F "'" '{print $2}') local tarball=go$version.linux-amd64.tar.gz + #gcc is required for go apps compilation + if ! which gcc; then + sudo apt-get install -y gcc + fi + if $(go version &>/dev/null); then return fi @@ -149,23 +154,19 @@ function install_addons { echo "Installing Kubernetes AddOns" _install_ansible sudo ansible-galaxy install $verbose -r $kud_infra_folder/galaxy-requirements.yml --ignore-errors - ansible-playbook $verbose -i $kud_inventory $kud_playbooks/configure-kud.yml | sudo tee $log_folder/setup-kud.log - for addon in ${KUD_ADDONS:-virtlet ovn4nfv nfd}; do + for addon in ${KUD_ADDONS:-virtlet ovn4nfv nfd sriov}; do echo "Deploying $addon using configure-$addon.yml playbook.." ansible-playbook $verbose -i $kud_inventory $kud_playbooks/configure-${addon}.yml | sudo tee $log_folder/setup-${addon}.log - if [[ "${testing_enabled}" == "true" ]]; then - pushd $kud_tests - bash ${addon}.sh - popd - fi done - ansible-playbook $verbose -i $kud_inventory $kud_playbooks/configure-sriov.yml | sudo tee $log_folder/setup-sriov.log - if [[ "${testing_enabled}" == "true" ]]; then + echo "Run the test cases if testing_enabled is set to true." + if [[ "${testing_enabled}" == "true" ]]; then + for addon in ${KUD_ADDONS:-virtlet ovn4nfv nfd sriov}; do pushd $kud_tests - bash sriov.sh + bash ${addon}.sh popd - fi + done + fi echo "Add-ons deployment complete..." } diff --git a/src/k8splugin/Makefile b/src/k8splugin/Makefile index 7d41158c..77196afa 100644 --- a/src/k8splugin/Makefile +++ b/src/k8splugin/Makefile @@ -25,8 +25,8 @@ deploy: build .PHONY: test test: clean - @go build -buildmode=plugin -o ./mock_files/mock_plugins/mockplugin.so ./mock_files/mock_plugins/mockplugin.go - @go test -v ./... + @go build -race -buildmode=plugin -o ./mock_files/mock_plugins/mockplugin.so ./mock_files/mock_plugins/mockplugin.go + @go test -race ./... format: @go fmt ./... @@ -40,5 +40,5 @@ clean: .PHONY: cover cover: - @go test ./... -coverprofile=coverage.out + @go test -race ./... -coverprofile=coverage.out @go tool cover -html=coverage.out -o coverage.html diff --git a/src/k8splugin/api/instancehandler.go b/src/k8splugin/api/instancehandler.go index ab98e4be..b0437426 100644 --- a/src/k8splugin/api/instancehandler.go +++ b/src/k8splugin/api/instancehandler.go @@ -20,6 +20,7 @@ import ( "net/http" "github.com/onap/multicloud-k8s/src/k8splugin/internal/app" + log "github.com/onap/multicloud-k8s/src/k8splugin/internal/logutils" "github.com/gorilla/mux" pkgerrors "github.com/pkg/errors" @@ -36,14 +37,25 @@ func (i instanceHandler) validateBody(body interface{}) error { switch b := body.(type) { case app.InstanceRequest: if b.CloudRegion == "" { + log.Error("CreateVnfRequest Bad Request", log.Fields{ + "cloudRegion": "Missing CloudRegion in POST request", + }) werr := pkgerrors.Wrap(errors.New("Invalid/Missing CloudRegion in POST request"), "CreateVnfRequest bad request") return werr } if b.RBName == "" || b.RBVersion == "" { + log.Error("CreateVnfRequest Bad Request", log.Fields{ + "message": "One of RBName, RBVersion is missing", + "RBName": b.RBName, + "RBVersion": b.RBVersion, + }) werr := pkgerrors.Wrap(errors.New("Invalid/Missing resource bundle parameters in POST request"), "CreateVnfRequest bad request") return werr } if b.ProfileName == "" { + log.Error("CreateVnfRequest bad request", log.Fields{ + "ProfileName": "Missing profile name in POST request", + }) werr := pkgerrors.Wrap(errors.New("Invalid/Missing profile name in POST request"), "CreateVnfRequest bad request") return werr } @@ -57,9 +69,15 @@ func (i instanceHandler) createHandler(w http.ResponseWriter, r *http.Request) { err := json.NewDecoder(r.Body).Decode(&resource) switch { case err == io.EOF: + log.Error("Body Empty", log.Fields{ + "error": io.EOF, + }) http.Error(w, "Body empty", http.StatusBadRequest) return case err != nil: + log.Error("Error unmarshaling Body", log.Fields{ + "error": err, + }) http.Error(w, err.Error(), http.StatusUnprocessableEntity) return } @@ -67,12 +85,19 @@ func (i instanceHandler) createHandler(w http.ResponseWriter, r *http.Request) { // Check body for expected parameters err = i.validateBody(resource) if err != nil { + log.Error("Invalid Parameters in Body", log.Fields{ + "error": err, + }) http.Error(w, err.Error(), http.StatusUnprocessableEntity) return } resp, err := i.client.Create(resource) if err != nil { + log.Error("Error Creating Resource", log.Fields{ + "error": err, + "resource": resource, + }) http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -81,6 +106,10 @@ func (i instanceHandler) createHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) err = json.NewEncoder(w).Encode(resp) if err != nil { + log.Error("Error Marshaling Response", log.Fields{ + "error": err, + "response": resp, + }) http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -93,6 +122,10 @@ func (i instanceHandler) getHandler(w http.ResponseWriter, r *http.Request) { resp, err := i.client.Get(id) if err != nil { + log.Error("Error getting Instance", log.Fields{ + "error": err, + "id": id, + }) http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -101,6 +134,10 @@ func (i instanceHandler) getHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) err = json.NewEncoder(w).Encode(resp) if err != nil { + log.Error("Error Marshaling Response", log.Fields{ + "error": err, + "response": resp, + }) http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -113,6 +150,10 @@ func (i instanceHandler) statusHandler(w http.ResponseWriter, r *http.Request) { resp, err := i.client.Status(id) if err != nil { + log.Error("Error getting Status", log.Fields{ + "error": err, + "id": id, + }) http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -121,6 +162,10 @@ func (i instanceHandler) statusHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) err = json.NewEncoder(w).Encode(resp) if err != nil { + log.Error("Error Marshaling Response", log.Fields{ + "error": err, + "response": resp, + }) http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -133,10 +178,16 @@ func (i instanceHandler) listHandler(w http.ResponseWriter, r *http.Request) { //Which will list all instances rbName := r.FormValue("rb-name") rbVersion := r.FormValue("rb-version") - ProfileName := r.FormValue("profile-name") + profileName := r.FormValue("profile-name") - resp, err := i.client.List(rbName, rbVersion, ProfileName) + resp, err := i.client.List(rbName, rbVersion, profileName) if err != nil { + log.Error("Error listing instances", log.Fields{ + "error": err, + "rb-name": rbName, + "rb-version": rbVersion, + "profile-name": profileName, + }) http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -145,6 +196,10 @@ func (i instanceHandler) listHandler(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) err = json.NewEncoder(w).Encode(resp) if err != nil { + log.Error("Error Marshaling Response", log.Fields{ + "error": err, + "response": resp, + }) http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -157,6 +212,9 @@ func (i instanceHandler) deleteHandler(w http.ResponseWriter, r *http.Request) { err := i.client.Delete(id) if err != nil { + log.Error("Error Deleting Instance", log.Fields{ + "error": err, + }) http.Error(w, err.Error(), http.StatusInternalServerError) return } diff --git a/src/k8splugin/go.mod b/src/k8splugin/go.mod index aab4cd2f..f924828d 100644 --- a/src/k8splugin/go.mod +++ b/src/k8splugin/go.mod @@ -63,6 +63,7 @@ require ( github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pkg/errors v0.8.1 github.com/rubenv/sql-migrate v0.0.0-20190902133344-8926f37f0bc1 // indirect + github.com/sirupsen/logrus v1.4.2 github.com/soheilhy/cmux v0.1.4 // indirect github.com/technosophos/moniker v0.0.0-20180509230615-a5dbd03a2245 // indirect github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51 // indirect diff --git a/src/k8splugin/internal/app/client.go b/src/k8splugin/internal/app/client.go index e52225d4..78477a82 100644 --- a/src/k8splugin/internal/app/client.go +++ b/src/k8splugin/internal/app/client.go @@ -14,12 +14,12 @@ limitations under the License. package app import ( - "log" "os" "time" "github.com/onap/multicloud-k8s/src/k8splugin/internal/connection" "github.com/onap/multicloud-k8s/src/k8splugin/internal/helm" + log "github.com/onap/multicloud-k8s/src/k8splugin/internal/logutils" "github.com/onap/multicloud-k8s/src/k8splugin/internal/plugin" pkgerrors "github.com/pkg/errors" @@ -116,11 +116,25 @@ func (k *KubernetesClient) ensureNamespace(namespace string) error { }, }, namespace, k) + if err != nil { + log.Error("Error checking for namespace", log.Fields{ + "error": err, + "namespace": namespace, + }) + return pkgerrors.Wrap(err, "Error checking for namespace: "+namespace) + } + if ns == "" { - log.Println("Creating " + namespace + " namespace") + log.Info("Creating Namespace", log.Fields{ + "namespace": namespace, + }) _, err = pluginImpl.Create("", namespace, k) if err != nil { + log.Error("Error Creating Namespace", log.Fields{ + "error": err, + "namespace": namespace, + }) return pkgerrors.Wrap(err, "Error creating "+namespace+" namespace") } } @@ -134,7 +148,9 @@ func (k *KubernetesClient) createKind(resTempl helm.KubernetesResourceTemplate, return helm.KubernetesResource{}, pkgerrors.New("File " + resTempl.FilePath + "does not exists") } - log.Println("Processing file: " + resTempl.FilePath) + log.Info("Processing Kubernetes Resource", log.Fields{ + "filepath": resTempl.FilePath, + }) pluginImpl, err := plugin.GetPluginByKind(resTempl.GVK.Kind) if err != nil { @@ -143,11 +159,19 @@ func (k *KubernetesClient) createKind(resTempl helm.KubernetesResourceTemplate, createdResourceName, err := pluginImpl.Create(resTempl.FilePath, namespace, k) if err != nil { - log.Printf("Error: %s while creating: %s", err.Error(), resTempl.GVK.Kind) + log.Error("Error Creating Resource", log.Fields{ + "error": err, + "gvk": resTempl.GVK, + "filepath": resTempl.FilePath, + }) return helm.KubernetesResource{}, pkgerrors.Wrap(err, "Error in plugin "+resTempl.GVK.Kind+" plugin") } - log.Print(createdResourceName + " created") + log.Info("Created Kubernetes Resource", log.Fields{ + "resource": createdResourceName, + "gvk": resTempl.GVK, + }) + return helm.KubernetesResource{ GVK: resTempl.GVK, Name: createdResourceName, @@ -175,14 +199,16 @@ func (k *KubernetesClient) createResources(sortedTemplates []helm.KubernetesReso } func (k *KubernetesClient) deleteKind(resource helm.KubernetesResource, namespace string) error { - log.Println("Deleting Kind: " + resource.GVK.Kind) + log.Warn("Deleting Resource", log.Fields{ + "gvk": resource.GVK, + "resource": resource.Name, + }) pluginImpl, err := plugin.GetPluginByKind(resource.GVK.Kind) if err != nil { return pkgerrors.Wrap(err, "Error loading plugin") } - log.Println("Deleting resource: " + resource.Name) err = pluginImpl.Delete(resource, namespace, k) if err != nil { return pkgerrors.Wrap(err, "Error deleting "+resource.Name) diff --git a/src/k8splugin/internal/logutils/logger.go b/src/k8splugin/internal/logutils/logger.go new file mode 100644 index 00000000..2e8f9969 --- /dev/null +++ b/src/k8splugin/internal/logutils/logger.go @@ -0,0 +1,28 @@ +package logutils + +import ( + log "github.com/sirupsen/logrus" +) + +//Fields is type that will be used by the calling function +type Fields map[string]interface{} + +func init() { + // Log as JSON instead of the default ASCII formatter. + log.SetFormatter(&log.JSONFormatter{}) +} + +// Error uses the fields provided and logs +func Error(msg string, fields Fields) { + log.WithFields(log.Fields(fields)).Error(msg) +} + +// Warn uses the fields provided and logs +func Warn(msg string, fields Fields) { + log.WithFields(log.Fields(fields)).Warn(msg) +} + +// Info uses the fields provided and logs +func Info(msg string, fields Fields) { + log.WithFields(log.Fields(fields)).Info(msg) +} |