--- /dev/null
+# Copyright (c) 2019 AT&T Intellectual Property.
+# Copyright (c) 2019 Nokia.
+#
+# Licensed 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 ubuntu:16.04 as xapp-base
+
+RUN apt-get update -y && \
+ apt-get install -y wget
+
+RUN sed -i -e "s,http://archive.ubuntu.com/ubuntu,$(wget -qO - mirrors.ubuntu.com/mirrors.txt | head -1)," /etc/apt/sources.list
+RUN sed -i -e "s,http://security.ubuntu.com/ubuntu,$(wget -qO - mirrors.ubuntu.com/mirrors.txt | head -1)," /etc/apt/sources.list
+
+#
+# packages
+#
+RUN apt-get update -y && \
+ apt-get upgrade -y && \
+ apt-get install -y \
+ build-essential \
+ apt-utils \
+ cmake \
+ make \
+ autoconf \
+ autoconf-archive \
+ gawk \
+ libtool \
+ automake \
+ pkg-config \
+ sudo \
+ wget \
+ nano \
+ git \
+ jq
+
+
+#
+# go
+#
+RUN wget https://dl.google.com/go/go1.12.linux-amd64.tar.gz && \
+ tar -C /usr/local -xvf ./go1.12.linux-amd64.tar.gz
+
+ENV PATH="/usr/local/go/bin:${PATH}"
+
+#
+# rancodev libs
+#
+RUN mkdir -p /opt/build \
+ && cd /opt/build && git clone https://gerrit.oran-osc.org/r/com/log \
+ && cd log/ ; ./autogen.sh ; ./configure ; make ; make install \
+ && ldconfig
+
+COPY build/build_entrypoint.sh /
+COPY build/user_entrypoint.sh /
+
+RUN chmod +x /build_entrypoint.sh
+RUN chmod +x /user_entrypoint.sh
+
+RUN mkdir -p /ws
+WORKDIR "/ws"
+ENTRYPOINT ["/user_entrypoint.sh"]
+CMD ["/bin/bash"]
+
+#----------------------------------------------------------
+#
+#----------------------------------------------------------
+FROM xapp-base as appmgr-build
+
+ARG PACKAGEURL
+ARG PACKAGEREPO
+ARG SSH_PRIVATE_KEY
+ARG NETRC_CONFIG
+ARG HELMVERSION
+
+
+#
+# helm
+#
+RUN wget https://storage.googleapis.com/kubernetes-helm/helm-${HELMVERSION}-linux-amd64.tar.gz \
+ && tar -zxvf helm-${HELMVERSION}-linux-amd64.tar.gz \
+ && cp linux-amd64/helm /usr/bin/helm \
+ && rm -rf helm-${HELMVERSION}-linux-amd64.tar.gz \
+ && rm -rf linux-amd64
+
+# Install kubectl from Docker Hub.
+COPY --from=lachlanevenson/k8s-kubectl:v1.10.3 /usr/local/bin/kubectl /usr/local/bin/kubectl
+
+RUN mkdir -p /go/src/${PACKAGEURL}
+WORKDIR "/go/src/${PACKAGEURL}"
+ENV GOPATH="/go"
+
+# Module prepare (if go.mod/go.sum updated)
+COPY go.mod /go/src/${PACKAGEURL}
+COPY go.sum /go/src/${PACKAGEURL}
+RUN GO111MODULE=on /build_entrypoint.sh go mod download
+
+# build
+COPY . /go/src/${PACKAGEURL}
+RUN /build_entrypoint.sh make -C /go/src/${PACKAGEURL} build
+
+ENTRYPOINT ["/build_entrypoint.sh"]
+CMD ["/bin/bash"]
+
+
+#----------------------------------------------------------
+#
+#----------------------------------------------------------
+FROM appmgr-build as appmgr-test_unit
+ARG PACKAGEURL
+WORKDIR "/go/src/${PACKAGEURL}"
+CMD ["make","go-test"]
+
+
+#----------------------------------------------------------
+#
+#----------------------------------------------------------
+FROM appmgr-build as appmgr-test_fmt
+ARG PACKAGEURL
+WORKDIR "/go/src/${PACKAGEURL}"
+CMD ["make","go-test-fmt"]
+
+#----------------------------------------------------------
+#
+#----------------------------------------------------------
+FROM appmgr-build as appmgr-test_sanity
+ARG PACKAGEURL
+WORKDIR "/go/src/${PACKAGEURL}"
+CMD ["jq","-s",".", "api/appmgr_rest_api.json"]
+
+
+#----------------------------------------------------------
+#
+#----------------------------------------------------------
+FROM ubuntu:16.04 as appmgr
+ARG PACKAGEURL
+
+RUN apt-get update -y \
+ && apt-get install -y sudo openssl ca-certificates ca-cacert \
+ && apt-get clean
+
+
+#
+# libraries and helm
+#
+COPY --from=appmgr-build /usr/local/include/ /usr/local/include/
+COPY --from=appmgr-build /usr/local/lib/ /usr/local/lib/
+COPY --from=appmgr-build /usr/bin/helm /usr/bin/helm
+COPY --from=appmgr-build /usr/local/bin/kubectl /usr/bin/kubectl
+
+RUN ldconfig
+
+#
+# xApp
+#
+RUN mkdir -p /opt/xAppManager \
+ && chmod -R 755 /opt/xAppManager
+
+COPY --from=appmgr-build /go/src/${PACKAGEURL}/build/cache/cmd/appmgr /opt/xAppManager/appmgr
+#COPY --from=appmgr-build /go/src/${PACKAGEURL}/config/appmgr.yaml /opt/etc/xAppManager/config-file.yaml
+
+
+WORKDIR /opt/xAppManager
+
+COPY appmgr-entrypoint.sh /opt/xAppManager/
+ENTRYPOINT ["/opt/xAppManager/appmgr-entrypoint.sh"]
+
# Copyright (c) 2019 AT&T Intellectual Property.
# Copyright (c) 2019 Nokia.
#
# See the License for the specific language governing permissions and
# limitations under the License.
+.DEFAULT: go-build
-#------------------------------------------------------------------------------
-#
-#-------------------------------------------------------------------- ----------
-ROOT_DIR:=$(dir $(abspath $(lastword $(MAKEFILE_LIST))))
-BUILD_DIR:=$(abspath $(ROOT_DIR)/build)
-
-PACKAGEURL:="gerrit.oran-osc.org/r/ric-plt/appmgr"
-HELMVERSION:=v2.13.0-rc.1
-
-#------------------------------------------------------------------------------
-#
-#-------------------------------------------------------------------- ----------
-COVEROUT := $(abspath $(BUILD_DIR)/cover.out)
-COVERHTML := $(abspath $(BUILD_DIR)/cover.html)
-
-GOOS=$(shell go env GOOS)
-GOCMD=go
-GOBUILD=$(GOCMD) build -a -installsuffix cgo
-GORUN=$(GOCMD) run -a -installsuffix cgo
-GOCLEAN=$(GOCMD) clean
-GOTEST=$(GOCMD) test -v -coverprofile $(COVEROUT)
-GOGET=$(GOCMD) get
+default: go-build
-GOFILES := $(shell find $(ROOT_DIR) -name '*.go' -not -name '*_test.go') go.mod go.sum
-GOFILES_NO_VENDOR := $(shell find $(ROOT_DIR) -path ./vendor -prune -o -name "*.go" -not -name '*_test.go' -print)
+build: go-build
-CMDS:=$(BUILD_DIR)/appmgr
+test: go-test
#------------------------------------------------------------------------------
#
-#-------------------------------------------------------------------- ----------
- .DEFAULT: build
-
-default: build
-
-.PHONY: FORCE
-
-FORCE:
-
-#------------------------------------------------------------------------------
+# Build and test targets
#
#------------------------------------------------------------------------------
+ROOT_DIR:=$(dir $(abspath $(lastword $(MAKEFILE_LIST))))
+BUILD_DIR:=$(abspath $(ROOT_DIR)/build)
-$(CMDS): $(GOFILES)
- GO111MODULE=on GO_ENABLED=0 GOOS=linux $(GOBUILD) -o $@ ./cmd/$(shell basename "$@")
-
-
-$(addsuffix _test,$(CMDS)): $(GOFILES)
- GO111MODULE=on GO_ENABLED=0 GOOS=linux $(GOTEST) -c -o $@ ./cmd/$(patsubst %_test,%, $(shell basename "$@"))
- timeout -s KILL 5s $@ -test.coverprofile $(COVEROUT)
- go tool cover -html=$(COVEROUT) -o $(COVERHTML)
-
-
-build: $(CMDS)
-
-
-test: $(addsuffix _test,$(CMDS))
-
-
-test-fmt: $(GOFILES_NO_VENDOR)
- @(RESULT="$$(gofmt -l $^)"; test -z "$${RESULT}" || (echo -e "gofmt failed:\n$${RESULT}" && false) )
-
-
-fmt: $(GOFILES_NO_VENDOR)
- gofmt -w -s $^
+XAPP_NAME:=appmgr
+XAPP_ROOT:=cmd
+XAPP_TESTENV:="RMR_SEED_RT=config/uta_rtg.rt CFG_FILE=$(ROOT_DIR)helm_chart/uemgr/descriptors/config-file.json"
+include build/make.go.mk
-clean:
- @echo " > Cleaning build cache"
- @-rm -rf $(CMDS)* 2> /dev/null
- go clean 2> /dev/null
#------------------------------------------------------------------------------
#
+# DOCKER TARGETS
+#
#------------------------------------------------------------------------------
-BUILD_PREFIX?="${USER}-"
-
-DCKR_FILE:=docker/Dockerfile
-
-DCKR_NAME:=${BUILD_PREFIX}appmgr
-DCKR_NAME:=$(shell echo $(DCKR_NAME) | tr '[:upper:]' '[:lower:]')
-DCKR_NAME:=$(subst /,_,${DCKR_NAME})
-
-DCKR_BUILD_OPTS:=${DCKR_BUILD_OPTS} --network=host --build-arg HELMVERSION=${HELMVERSION} --build-arg PACKAGEURL=${PACKAGEURL}
-
-DCKR_RUN_OPTS:=${DCKR_RUN_OPTS} --rm -i
-DCKR_RUN_OPTS:=${DCKR_RUN_OPTS}$(shell test -t 0 && echo ' -t')
-DCKR_RUN_OPTS:=${DCKR_RUN_OPTS}$(shell test -e /etc/localtime && echo ' -v /etc/localtime:/etc/localtime:ro')
-DCKR_RUN_OPTS:=${DCKR_RUN_OPTS}$(shell test -e /var/run/docker.sock && echo ' -v /var/run/docker.sock:/var/run/docker.sock')
-
+HELMVERSION:=v2.13.0-rc.1
+DCKR_B_OPTS:=${DCKR_B_OPTS} --build-arg HELMVERSION=${HELMVERSION}
-#------------------------------------------------------------------------------
-#
-#------------------------------------------------------------------------------
-docker-name:
- @echo $(DCKR_NAME)
+PACKAGEURL:="gerrit.oran-osc.org/r/ric-plt/appmgr"
-docker-build:
- docker build --target release ${DCKR_BUILD_OPTS} -t $(DCKR_NAME) -f $(DCKR_FILE) .
+DCKR_NAME:=appmgr-test_unit
+include build/make.docker.mk
-docker-run:
- docker run ${DCKR_RUN_OPTS} -v /opt/ric:/opt/ric -p 8080:8080 $(DCKR_NAME)
+DCKR_NAME:=appmgr-test_fmt
+include build/make.docker.mk
-docker-clean:
- docker rmi $(DCKR_NAME)
+DCKR_NAME:=appmgr-test_sanity
+include build/make.docker.mk
+DCKR_NAME:=appmgr
+include build/make.docker.mk
-#------------------------------------------------------------------------------
-#
-#------------------------------------------------------------------------------
-docker-test-build:
- docker build --target test_unit ${DCKR_BUILD_OPTS} -t ${DCKR_NAME}-test_unit -f $(DCKR_FILE) .
- docker build --target test_sanity ${DCKR_BUILD_OPTS} -t ${DCKR_NAME}-test_sanity -f $(DCKR_FILE) .
- docker build --target test_fmt ${DCKR_BUILD_OPTS} -t ${DCKR_NAME}-test_fmt -f $(DCKR_FILE) .
-
-docker-test-run-unit:
- @( \
- RETVAL=0;\
- docker network create --driver bridge ${DCKR_NAME}-test_unit_network;\
- docker run ${DCKR_RUN_OPTS} -d --name ${DCKR_NAME}-test_unit_redis --network ${DCKR_NAME}-test_unit_network redis;\
- docker run ${DCKR_RUN_OPTS} --name ${DCKR_NAME}-test_unit_run --network ${DCKR_NAME}-test_unit_network -e DBAAS_SERVICE_HOST=${DCKR_NAME}-test_unit_redis ${DCKR_NAME}-test_unit;\
- RETVAL=$$?;\
- docker stop ${DCKR_NAME}-test_unit_redis;\
- docker network rm ${DCKR_NAME}-test_unit_network;\
- exit $${RETVAL};\
- )
-
-
-docker-test-run-fmt:
- docker run ${DCKR_RUN_OPTS} ${DCKR_NAME}-test_fmt
-
-docker-test-run-sanity:
- docker run ${DCKR_RUN_OPTS} ${DCKR_NAME}-test_sanity
-
-docker-test-clean:
- docker rmi -f ${DCKR_NAME}-test_unit
- docker rmi -f ${DCKR_NAME}-test_sanity
- docker rmi -f ${DCKR_NAME}-test_fmt
+docker-test: docker-run_appmgr-test_fmt docker-run_appmgr-test_sanity docker-run-redished_appmgr-test_unit
"swagger": "2.0",
"info": {
"description": "This is a draft API for RIC appmgr",
- "version": "0.0.10",
+ "version": "0.0.11",
"title": "RIC appmgr",
"license": {
"name": "Apache 2.0",
"enum": [
"created",
"deleted",
+ "updated",
"all"
]
}
"enum": [
"created",
"deleted",
+ "updated",
"all"
]
},
"description": "Event to be notified",
"enum": [
"created",
- "deleted"
+ "deleted",
+ "updated"
]
},
"xApps": {
--- /dev/null
+#!/bin/bash
+
+# Copyright (c) 2019 AT&T Intellectual Property.
+# Copyright (c) 2019 Nokia.
+#
+# Licensed 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.
+
+cp /opt/ric/config/appmgr.yaml /opt/xAppManager/config-file.yaml
+
+# Copy all certificates from mounted folder to root system
+cp /opt/ric/certificates/* /etc/ssl/certs
+
+# Start services, etc.
+/opt/xAppManager/appmgr -f /opt/xAppManager/config-file.yaml
--- /dev/null
+#!/bin/bash
+# Copyright (c) 2019 AT&T Intellectual Property.
+# Copyright (c) 2019 Nokia.
+#
+# Licensed 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.
+#
+
+#
+# SSH
+#
+if [ -n "${SSH_PRIVATE_KEY}" ] && [ -n "${PACKAGEREPO}" ] ; then
+
+ # ssh configs (no private key)
+ mkdir -p ${HOME}/.ssh
+ test -n "${PACKAGEREPO}" && ssh-keyscan -H ${PACKAGEREPO} >> ${HOME}/.ssh/known_hosts
+ echo -e "IdentityFile ~/.ssh/id_rsa\n" > ${HOME}/.ssh/config
+ echo -e "Host *\n\tStrictHostKeyChecking no\n\n" >> ${HOME}/.ssh/config
+ chmod -R go= ${HOME}/.ssh/
+ chmod -R u+rw ${HOME}/.ssh/
+
+ # gitconfig
+ test -n "${PACKAGEREPO}" && echo -e "[url \"ssh://git@${PACKAGEREPO}/\"]\n\tinsteadOf = https://${PACKAGEREPO}/" > ${HOME}/.gitconfig
+
+ # ssh agent
+ TEMPFILE=/dev/shm/deployment.key
+ echo "$SSH_PRIVATE_KEY" > $TEMPFILE
+ chmod 0600 $TEMPFILE
+ eval $(ssh-agent)
+ ssh-add $TEMPFILE
+ rm $TEMPFILE
+fi
+
+if [ -n "${NETRC_CONFIG}" ] ; then
+ echo "${NETRC_CONFIG}" > /root/.netrc
+fi
+
+
+exec $*
--- /dev/null
+# Copyright (c) 2019 AT&T Intellectual Property.
+# Copyright (c) 2019 Nokia.
+#
+# Licensed 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.
+
+#------------------------------------------------------------------------------
+#
+#------------------------------------------------------------------------------
+ifndef MAKE_DOCKER_TARGETS
+MAKE_DOCKER_TARGETS:=1
+
+.PHONY: docker-build docker-clean
+
+
+docker-name_%:
+ @echo $($*_DCKR_FULLNAME)
+
+docker-build_%:
+ @(\
+ test -z "$${SSH_PRIVATE_KEY}" && SSH_PRIVATE_KEY=$$(cat $${HOME}/.ssh/id_rsa);\
+ docker build --target $* $($*_DCKR_B_OPTS) --build-arg SSH_PRIVATE_KEY="$${SSH_PRIVATE_KEY}" -t $($*_DCKR_FULLNAME) -f $($*_DCKR_FILE) . ;\
+ )
+
+docker-irun_%:
+ docker run $($*_DCKR_R_OPTS) $($*_DCKR_FULLNAME) /bin/bash
+
+docker-irun-mounted_%:
+ docker run $($*_DCKR_R_OPTS) -v $(shell pwd):/ws/go/src/${PACKAGEURL} --workdir "/ws/go/src/${PACKAGEURL}" $($*_DCKR_FULLNAME) /bin/bash
+
+docker-run_%:
+ docker run $($*_DCKR_R_OPTS) $($*_DCKR_FULLNAME)
+
+docker-run-redished_%:
+ @( \
+ RETVAL=0;\
+ docker network create --driver bridge $($*_DCKR_FULLNAME)-run_network;\
+ docker run $($*_DCKR_R_OPTS) -d --name $($*_DCKR_FULLNAME)-run_redis --network $($*_DCKR_FULLNAME)-run_network redis;\
+ docker run $($*_DCKR_R_OPTS) --name $($*_DCKR_FULLNAME)-run_xapp --network $($*_DCKR_FULLNAME)-run_network -e DBAAS_SERVICE_HOST=$($*_DCKR_FULLNAME)-run_redis $($*_DCKR_FULLNAME);\
+ RETVAL=$$?;\
+ docker stop $($*_DCKR_FULLNAME)-run_redis;\
+ docker network rm $($*_DCKR_FULLNAME)-run_network;\
+ exit $${RETVAL};\
+ )
+
+docker-clean_%:
+ docker rmi $($*_DCKR_FULLNAME) || true
+
+
+.SECONDEXPANSION:
+docker-build: DCKR_TARGETS:=
+docker-build: $$(DCKR_TARGETS)
+
+.SECONDEXPANSION:
+docker-clean: DCKR_TARGETS:=
+docker-clean: $$(DCKR_TARGETS)
+
+endif
+
+#------------------------------------------------------------------------------
+#
+#------------------------------------------------------------------------------
+
+ifndef DCKR_FILE
+DCKR_FILE:="Dockerfile"
+endif
+
+ifndef BUILD_PREFIX
+BUILD_PREFIX:="${USER}-"
+endif
+
+
+#------------------------------------------------------------------------------
+#
+#------------------------------------------------------------------------------
+
+ifndef $(DCKR_NAME)_DCKR_B_PREFIX
+$(DCKR_NAME)_DCKR_B_PREFIX:=$(BUILD_PREFIX)
+endif
+
+ifndef $(DCKR_NAME)_DCKR_FILE
+$(DCKR_NAME)_DCKR_FILE:=$(DCKR_FILE)
+endif
+
+$(DCKR_NAME)_DCKR_B_PREFIX:=$(subst /,_,$(shell echo $($(DCKR_NAME)_DCKR_B_PREFIX) | tr '[:upper:]' '[:lower:]'))
+
+$(DCKR_NAME)_DCKR_FULLNAME:=$($(DCKR_NAME)_DCKR_B_PREFIX)$(DCKR_NAME)
+
+$(DCKR_NAME)_DCKR_B_OPTS:=${DCKR_B_OPTS}
+$(DCKR_NAME)_DCKR_B_OPTS:=$($(DCKR_NAME)_DCKR_B_OPTS) --network=host
+
+ifndef PACKAGEURL
+$(DCKR_NAME)_DCKR_B_OPTS:=$($(DCKR_NAME)_DCKR_B_OPTS) --build-arg PACKAGEURL=${PACKAGEURL}
+endif
+
+ifndef PACKAGEREPO
+$(DCKR_NAME)_DCKR_B_OPTS:=$($(DCKR_NAME)_DCKR_B_OPTS) --build-arg PACKAGEREPO=${PACKAGEREPO}
+endif
+
+ifndef BUILD_PREFIX
+$(DCKR_NAME)_DCKR_B_OPTS:=$($(DCKR_NAME)_DCKR_B_OPTS) --build-arg BUILD_PREFIX=${BUILD_PREFIX}
+endif
+
+
+$(DCKR_NAME)_DCKR_R_OPTS:=${DCKR_R_OPTS}
+$(DCKR_NAME)_DCKR_R_OPTS:=$($(DCKR_NAME)_DCKR_R_OPTS) --rm -i --net=host
+$(DCKR_NAME)_DCKR_R_OPTS:=$($(DCKR_NAME)_DCKR_R_OPTS)$(shell test -t 0 && echo ' -t')
+$(DCKR_NAME)_DCKR_R_OPTS:=$($(DCKR_NAME)_DCKR_R_OPTS)$(shell test -e /etc/localtime && echo ' -v /etc/localtime:/etc/localtime:ro')
+$(DCKR_NAME)_DCKR_R_OPTS:=$($(DCKR_NAME)_DCKR_R_OPTS)$(shell test -e /var/run/docker.sock && echo ' -v /var/run/docker.sock:/var/run/docker.sock')
+$(DCKR_NAME)_DCKR_R_OPTS:=$($(DCKR_NAME)_DCKR_R_OPTS)$(shell test -e ${HOME}/.docker && echo ' -v ${HOME}/.docker:/ws/.docker:ro')
+$(DCKR_NAME)_DCKR_R_OPTS:=$($(DCKR_NAME)_DCKR_R_OPTS)$(shell test -e ${HOME}/.netrc && echo ' -v ${HOME}/.netrc:/ws/.netrc:ro')
+$(DCKR_NAME)_DCKR_R_OPTS:=$($(DCKR_NAME)_DCKR_R_OPTS)$(shell test -e ${HOME}/.ssh && echo ' -v ${HOME}/.ssh:/ws/.ssh:ro')
+$(DCKR_NAME)_DCKR_R_OPTS:=$($(DCKR_NAME)_DCKR_R_OPTS)$(shell test -e ${HOME}/.gitconfig && echo ' -v ${HOME}/.gitconfig:/ws/.gitconfig:ro')
+
+
+docker-build: DCKR_TARGETS+=docker-build_$(DCKR_NAME)
+
+docker-clean: DCKR_TARGETS+=docker-clean_$(DCKR_NAME)
+
--- /dev/null
+# Copyright (c) 2019 AT&T Intellectual Property.
+# Copyright (c) 2019 Nokia.
+#
+# Licensed 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.
+
+
+#------------------------------------------------------------------------------
+#
+#------------------------------------------------------------------------------
+#ROOT_DIR:=$(dir $(abspath $(lastword $(MAKEFILE_LIST))))
+
+ifndef ROOT_DIR
+$(error ROOT_DIR NOT DEFINED)
+endif
+BUILD_DIR?=$(abspath $(ROOT_DIR)/build)
+CACHE_DIR?=$(abspath $(BUILD_DIR)/cache)
+
+
+#------------------------------------------------------------------------------
+#
+#-------------------------------------------------------------------- ----------
+ifndef MAKE_GO_TARGETS
+MAKE_GO_TARGETS:=1
+
+
+GOOS=$(shell go env GOOS)
+GOCMD=go
+GOBUILD=$(GOCMD) build -a -installsuffix cgo
+GORUN=$(GOCMD) run -a -installsuffix cgo
+GOCLEAN=$(GOCMD) clean
+GOTEST=$(GOCMD) test -v
+GOGET=$(GOCMD) get
+
+GOFILES:=$(shell find $(ROOT_DIR) -name '*.go' -not -name '*_test.go')
+GOALLFILES:=$(shell find $(ROOT_DIR) -name '*.go')
+GOMODFILES:=go.mod go.sum
+
+.PHONY: FORCE go-build go-test go-test-fmt go-fmt go-clean
+
+
+FORCE:
+
+
+$(CACHE_DIR)/%: $(GOFILES) $(GOMODFILES)
+ @echo "Building:\t$*"
+ GO111MODULE=on GO_ENABLED=0 GOOS=linux $(GOBUILD) -o $@ ./$*
+
+
+$(CACHE_DIR)/%_test: $(GOALLFILES) $(GOMODFILES)
+ @echo "Testing:\t$*"
+ GO111MODULE=on GO_ENABLED=0 GOOS=linux $(GOTEST) -coverprofile $(COVEROUT) -c -o $@ ./$*
+ test -e $@ && (eval $(TESTENV) $@ -test.coverprofile $(COVEROUT) || false) || true
+ test -e $@ && (go tool cover -html=$(COVEROUT) -o $(COVERHTML) || false) || true
+
+
+.SECONDEXPANSION:
+go-build: XAPP_TARGETS:=
+go-build: $$(XAPP_TARGETS)
+
+.SECONDEXPANSION:
+go-test: XAPP_TARGETS:=
+go-test: go-clean $$(XAPP_TARGETS)
+
+go-test-fmt: $(GOFILES)
+ @(RESULT="$$(gofmt -l $^)"; test -z "$${RESULT}" || (echo -e "gofmt failed:\n$${RESULT}" && false) )
+
+go-fmt: $(GOFILES)
+ gofmt -w -s $^
+
+go-clean: XAPP_TARGETS:=
+go-clean:
+ @echo " > Cleaning build cache"
+ @-rm -rf $(XAPP_TARGETS)* 2> /dev/null
+ go clean 2> /dev/null
+
+
+endif
+
+#------------------------------------------------------------------------------
+#
+#-------------------------------------------------------------------- ----------
+
+$(CACHE_DIR)/$(XAPP_ROOT)/$(XAPP_NAME)_test: COVEROUT:=$(abspath $(CACHE_DIR)/$(XAPP_ROOT)/$(XAPP_NAME)_cover.out)
+$(CACHE_DIR)/$(XAPP_ROOT)/$(XAPP_NAME)_test: COVERHTML:=$(abspath $(CACHE_DIR)/$(XAPP_ROOT)/$(XAPP_NAME)_cover.html)
+$(CACHE_DIR)/$(XAPP_ROOT)/$(XAPP_NAME)_test: TESTENV:=$(XAPP_TESTENV)
+
+go-build: XAPP_TARGETS+=$(CACHE_DIR)/$(XAPP_ROOT)/$(XAPP_NAME)
+go-test: XAPP_TARGETS+=$(CACHE_DIR)/$(XAPP_ROOT)/$(XAPP_NAME)_test
+go-clean: XAPP_TARGETS+=$(CACHE_DIR)/$(XAPP_ROOT)/$(XAPP_NAME) $(CACHE_DIR)/$(XAPP_ROOT)/$(XAPP_NAME)_test
+
--- /dev/null
+#!/bin/bash
+# Copyright (c) 2019 AT&T Intellectual Property.
+# Copyright (c) 2019 Nokia.
+#
+# Licensed 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.
+#
+
+source /etc/os-release
+
+if [ -z ${CONT_USER} ]; then CONT_USER=builder ; fi
+if [ -z ${CONT_UID} ]; then CONT_UID=$(stat -c "%u" $(readlink -f .) ); fi
+if [ -z ${CONT_GROUP} ]; then CONT_GROUP=builder; fi
+if [ -z ${CONT_GID} ]; then CONT_GID=$(stat -c "%g" $(readlink -f .) ); fi
+
+if [ $(id -u) -eq $CONT_UID ] || [ $(id -u) -ne 0 ] ; then
+ exec "$@"
+fi
+
+if [ $(getent group ${CONT_GROUP}) ] || [ $(getent group ${CONT_GID}) ] ; then
+ echo "group conflict"
+ exit 0
+fi
+if [ $(getent passwd ${CONT_USER}) ] || [ $(getent passwd ${CONT_UID}) ] ; then
+ echo "passwd conflict"
+ exit 0
+fi
+
+if [[ $ID == "ubuntu" ]] ; then
+ groupadd --gid ${CONT_GID} ${CONT_GROUP} || exit 10
+ useradd --shell /bin/bash --uid ${CONT_UID} --gid ${CONT_GID} -o -d /ws $(test -d /ws && echo "-M" || echo "-m") --groups $CONT_GID ${CONT_USER}|| exit 11
+fi
+if [[ $ID == "alpine" ]] ; then
+ addgroup -g ${CONT_GID} ${CONT_GROUP} || exit 10
+ adduser -s /bin/bash -u ${CONT_UID} -G ${CONT_GROUP} -h /ws $(test -d /ws && echo "-H") -D ${CONT_USER} ||Â exit 11
+fi
+
+chown ${CONT_UID}.${CONT_GID} /ws
+
+echo "${CONT_USER} ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
+
+DOCKER_SOCKET=/var/run/docker.sock
+if [ -S ${DOCKER_SOCKET} ]; then
+ DOCKER_GID=$(stat -c '%g' ${DOCKER_SOCKET})
+ if [ $(getent group ${DOCKER_GID}) ]; then
+ if [[ $ID == "ubuntu" ]] ; then
+ usermod -aG $(getent group ${DOCKER_GID} | cut -d: -f1) ${CONT_USER} || exit 12
+ fi
+ if [[ $ID == "alpine" ]] ; then
+ addgroup ${CONT_USER} $(getent group ${DOCKER_GID} | cut -d: -f1) || exit 12
+ fi
+ else
+ if [[ $ID == "ubuntu" ]] ; then
+ groupadd -for -g ${DOCKER_GID} docker_${CONT_USER} || exit 13
+ usermod -aG docker_${CONT_USER} ${CONT_USER} || exit 14
+ fi
+ if [[ $ID == "alpine" ]] ; then
+ addgroup -g ${DOCKER_GID} docker_${CONT_USER} || exit 13
+ addgroup ${CONT_USER} docker_${CONT_USER} || exit 14
+ fi
+ fi
+fi
+
+export USER=${CONT_USER}
+export HOME=/ws
+
+mkdir -p /ws/go
+chown -R ${CONT_UID}.${CONT_GID} /ws/go
+export GOPATH="/ws/go"
+
+sudo -E -s -u ${CONT_USER} env "PATH=$PATH" "$@"
import (
"encoding/json"
+ "errors"
"github.com/gorilla/mux"
"github.com/spf13/viper"
"log"
// API functions
func (m *XappManager) Initialize(h Helmer) {
- /*
- m.sd = SubscriptionDispatcher{}
- m.sd.Initialize()
- m.helm = h
- m.helm.Initialize()
- */
m.router = mux.NewRouter().StrictSlash(true)
resources := []Resource{
{"GET", "/ric/v1/subscriptions/{id}", m.getSubscription},
{"DELETE", "/ric/v1/subscriptions/{id}", m.deleteSubscription},
{"PUT", "/ric/v1/subscriptions/{id}", m.updateSubscription},
+
+ {"GET", "/ric/v1/config", m.getConfig},
+ {"POST", "/ric/v1/config", m.createConfig},
+ {"DELETE", "/ric/v1/config", m.deleteConfig},
}
for _, resource := range resources {
return
}
- var xapp Xapp
- if err := json.NewDecoder(r.Body).Decode(&xapp); err != nil {
+ var cm ConfigMetadata
+ if err := json.NewDecoder(r.Body).Decode(&cm); err != nil {
mdclog(MdclogErr, "Invalid xapp data in request body - url="+r.URL.RequestURI())
respondWithError(w, http.StatusMethodNotAllowed, "Invalid xapp data!")
return
}
defer r.Body.Close()
- xapp, err := m.helm.Install(xapp.Name)
+ xapp, err := m.helm.Install(cm)
if err != nil {
respondWithError(w, http.StatusInternalServerError, err.Error())
return
m.sd.notifyClients(xapps, "updated")
}
+func (m *XappManager) getConfig(w http.ResponseWriter, r *http.Request) {
+ respondWithJSON(w, http.StatusOK, UploadConfig())
+}
+
+func (m *XappManager) createConfig(w http.ResponseWriter, r *http.Request) {
+ var c XAppConfig
+ if parseConfig(w, r, &c) != nil {
+ return
+ }
+
+ if err := CreateConfigMap(c); err != nil {
+ respondWithError(w, http.StatusInternalServerError, err.Error())
+ return
+ }
+ respondWithJSON(w, http.StatusCreated, nil)
+}
+
+func (m *XappManager) deleteConfig(w http.ResponseWriter, r *http.Request) {
+ var c XAppConfig
+ if parseConfig(w, r, &c) != nil {
+ return
+ }
+
+ if _, err := DeleteConfigMap(c); err != nil {
+ respondWithError(w, http.StatusInternalServerError, err.Error())
+ return
+ }
+ respondWithJSON(w, http.StatusNotFound, nil)
+}
+
// Helper functions
func respondWithError(w http.ResponseWriter, code int, message string) {
respondWithJSON(w, code, map[string]string{"error": message})
}
return
}
+
+func parseConfig(w http.ResponseWriter, r *http.Request, req *XAppConfig) error {
+ if r.Body == nil || json.NewDecoder(r.Body).Decode(&req) != nil {
+ mdclog(MdclogErr, "Invalid request payload - url="+r.URL.RequestURI())
+ respondWithError(w, http.StatusMethodNotAllowed, "Invalid request payload")
+ return errors.New("Invalid payload")
+ }
+ defer r.Body.Close()
+
+ return nil
+}
return names, helmError
}
-func (h *MockedHelmer) Install(name string) (Xapp, error) {
+func (h *MockedHelmer) Install(m ConfigMetadata) (Xapp, error) {
return xapp, helmError
}
func (d *DB) Create() {
ns := viper.GetString("db.sessionNamespace")
- d.session = sdl.Create(ns)
+ d.session = sdl.NewSdlInstance(ns, sdl.NewDatabase())
// Test DB connection, and wait until ready!
for {
--- /dev/null
+/*
+==================================================================================
+ Copyright (c) 2019 AT&T Intellectual Property.
+ Copyright (c) 2019 Nokia
+
+ Licensed 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 main
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "github.com/spf13/viper"
+ "github.com/xeipuuv/gojsonschema"
+ "io/ioutil"
+ "log"
+ "os"
+ "path"
+ "regexp"
+ "strings"
+ "time"
+)
+
+type ConfigMetadata struct {
+ Name string `json:"name"`
+ ConfigName string `json:"configName, omitempty"`
+ Namespace string `json:"namespace, omitempty"`
+}
+
+type XAppConfig struct {
+ Metadata ConfigMetadata `json:"metadata"`
+ Descriptor interface{} `json:"descriptor, omitempty"`
+ Configuration interface{} `json:"config, omitempty"`
+}
+
+type ConfigMap struct {
+ Kind string `json:"kind"`
+ ApiVersion string `json:"apiVersion"`
+ Data interface{} `json:"data"`
+ Metadata CMMetadata `json:"metadata"`
+}
+
+type CMMetadata struct {
+ Name string `json:"name"`
+ Namespace string `json:"namespace"`
+}
+
+func UploadConfig() (cfg []XAppConfig) {
+ for _, name := range GetNamesFromHelmRepo() {
+ if name == "appmgr" {
+ continue
+ }
+
+ c := XAppConfig{
+ Metadata: ConfigMetadata{Name: name, Namespace: "ricxapp", ConfigName: name + "-appconfig"},
+ }
+
+ err := ReadSchema(name, &c)
+ if err != nil {
+ continue
+ }
+
+ err = ReadConfigMap(name, "ricxapp", &c.Configuration)
+ if err != nil {
+ log.Println("No active configMap found, using default!")
+ }
+
+ cfg = append(cfg, c)
+ }
+ return
+}
+
+func ReadSchema(name string, c *XAppConfig) (err error) {
+ if err = FetchChart(name); err != nil {
+ return
+ }
+
+ tarDir := viper.GetString("xapp.tarDir")
+ err = ReadFile(path.Join(tarDir, name, viper.GetString("xapp.schema")), &c.Descriptor)
+ if err != nil {
+ return
+ }
+
+ err = ReadFile(path.Join(tarDir, name, viper.GetString("xapp.config")), &c.Configuration)
+ if err != nil {
+ return
+ }
+
+ if err = os.RemoveAll(path.Join(tarDir, name)); err != nil {
+ log.Println("RemoveAll failed", err)
+ }
+
+ return
+}
+
+func ReadConfigMap(name string, ns string, c *interface{}) (err error) {
+ args := fmt.Sprintf("get configmap -o jsonpath='{.data.config-file\\.json}' -n %s %s-appconfig", ns, name)
+ configMapJson, err := KubectlExec(args)
+ if err != nil {
+ return
+ }
+
+ err = json.Unmarshal([]byte(configMapJson), &c)
+ if err != nil {
+ return
+ }
+
+ return
+}
+
+func ApplyConfigMap(r XAppConfig) (err error) {
+ cm := ConfigMap{
+ Kind: "ConfigMap",
+ ApiVersion: "v1",
+ Metadata: CMMetadata{Name: r.Metadata.Name, Namespace: r.Metadata.Namespace},
+ Data: r.Configuration,
+ }
+
+ cmJson, err := json.Marshal(cm)
+ if err != nil {
+ log.Println("Config marshalling failed: ", err)
+ return
+ }
+
+ cmFile := viper.GetString("xapp.tmpConfig")
+ err = ioutil.WriteFile(cmFile, cmJson, 0644)
+ if err != nil {
+ log.Println("WriteFile failed: ", err)
+ return
+ }
+
+ cmd := " create configmap -n %s %s --from-file=%s -o json --dry-run | kubectl apply -f -"
+ args := fmt.Sprintf(cmd, r.Metadata.Namespace, r.Metadata.ConfigName, cmFile)
+ _, err = KubectlExec(args)
+ if err != nil {
+ return
+ }
+ log.Println("Configmap changes created!")
+
+ return
+}
+
+func CreateConfigMap(r XAppConfig) (err error) {
+ if err = Validate(r); err != nil {
+ return
+ }
+ return ApplyConfigMap(r)
+}
+
+func DeleteConfigMap(r XAppConfig) (cm interface{}, err error) {
+ err = ReadConfigMap(r.Metadata.Name, r.Metadata.Namespace, &cm)
+ if err == nil {
+ args := fmt.Sprintf(" delete configmap --namespace=%s %s", r.Metadata.Namespace, r.Metadata.ConfigName)
+ _, err = KubectlExec(args)
+ }
+ return
+}
+
+func PurgeConfigMap(m ConfigMetadata) (cm interface{}, err error) {
+ if m.ConfigName == "" {
+ m.ConfigName = m.Name + "-appconfig"
+ }
+ return DeleteConfigMap(XAppConfig{Metadata: m})
+}
+
+func RestoreConfigMap(m ConfigMetadata, cm interface{}) (err error) {
+ if m.ConfigName == "" {
+ m.ConfigName = m.Name + "-appconfig"
+ }
+ time.Sleep(time.Duration(10 * time.Second))
+
+ return ApplyConfigMap(XAppConfig{Metadata: m, Configuration: cm})
+}
+
+func GetNamesFromHelmRepo() (names []string) {
+ rname := viper.GetString("helm.repo-name")
+
+ cmdArgs := strings.Join([]string{"search ", rname}, "")
+ out, err := HelmExec(cmdArgs)
+ if err != nil {
+ return
+ }
+
+ re := regexp.MustCompile(rname + `/.*`)
+ result := re.FindAllStringSubmatch(string(out), -1)
+ if result != nil {
+ var tmp string
+ for _, v := range result {
+ fmt.Sscanf(v[0], "%s", &tmp)
+ names = append(names, strings.Split(tmp, "/")[1])
+ }
+ }
+ return names
+}
+
+func Validate(req XAppConfig) (err error) {
+ c := XAppConfig{}
+ err = ReadSchema(req.Metadata.Name, &c)
+ if err != nil {
+ log.Printf("No schema file found for '%s', aborting ...", req.Metadata.Name)
+ return err
+ }
+
+ schemaLoader := gojsonschema.NewGoLoader(c.Descriptor)
+ documentLoader := gojsonschema.NewGoLoader(req.Configuration)
+
+ log.Println("Starting validation ...")
+ result, err := gojsonschema.Validate(schemaLoader, documentLoader)
+ if err != nil {
+ log.Println("Validation failed: ", err)
+ return
+ }
+
+ log.Println("validation done ...", err, result.Valid())
+ if result.Valid() == false {
+ log.Println("The document is not valid, Errors: ", result.Errors())
+ s := make([]string, 3)
+ for i, desc := range result.Errors() {
+ s = append(s, fmt.Sprintf(" (%d): %s.\n", i, desc.String()))
+ }
+ return errors.New(strings.Join(s, " "))
+ }
+ return
+}
+
+func ReadFile(name string, data interface{}) (err error) {
+ f, err := ioutil.ReadFile(name)
+ if err != nil {
+ log.Printf("Reading '%s' file failed: %v", name, err)
+ return
+ }
+
+ err = json.Unmarshal(f, &data)
+ if err != nil {
+ log.Printf("Unmarshalling '%s' file failed: %v", name, err)
+ return
+ }
+
+ return
+}
+
+func FetchChart(name string) (err error) {
+ tarDir := viper.GetString("xapp.tarDir")
+ repo := viper.GetString("helm.repo-name")
+ fetchArgs := fmt.Sprintf("--untar --untardir %s %s/%s", tarDir, repo, name)
+
+ _, err = HelmExec(strings.Join([]string{"fetch ", fetchArgs}, ""))
+ return
+}
+
+func GetMessages(name string) (msgs MessageTypes, err error) {
+ log.Println("Fetching tx/rx messages for: ", name)
+ return
+}
"errors"
"fmt"
"github.com/spf13/viper"
- "gopkg.in/yaml.v2"
"io/ioutil"
"log"
"os"
"os/exec"
- "path"
"regexp"
"strconv"
"strings"
var execCommand = exec.Command
func Exec(args string) (out []byte, err error) {
- cmd := execCommand("/bin/sh", "-c", strings.Join([]string{"helm", args}, " "))
-
- if !strings.HasSuffix(os.Args[0], ".test") {
- out, err = cmd.CombinedOutput()
- if err != nil {
- mdclog(MdclogErr, formatLog("Command failed", args, err.Error()))
- }
- return out, err
- }
+ cmd := execCommand("/bin/sh", "-c", args)
var stdout bytes.Buffer
var stderr bytes.Buffer
cmd.Stdout = &stdout
cmd.Stderr = &stderr
- log.Printf("Running command: %v", cmd)
- for i := 0; i < 3; i++ {
+ log.Println("Running command: ", cmd)
+ for i := 0; i < viper.GetInt("helm.retry"); i++ {
err = cmd.Run()
if err != nil {
mdclog(MdclogErr, formatLog("Command failed, retrying", args, err.Error()+stderr.String()))
- time.Sleep(time.Duration(5) * time.Second)
+ time.Sleep(time.Duration(2) * time.Second)
continue
}
break
return stdout.Bytes(), errors.New(stderr.String())
}
+func HelmExec(args string) (out []byte, err error) {
+ return Exec(strings.Join([]string{"helm", args}, " "))
+}
+
+func KubectlExec(args string) (out []byte, err error) {
+ return Exec(strings.Join([]string{"kubectl", args}, " "))
+}
+
func (h *Helm) Initialize() {
if h.initDone == true {
return
mdclog(MdclogErr, formatLog("Helm repo addition failed, retyring ...", "", ""))
time.Sleep(time.Duration(10) * time.Second)
}
+
h.initDone = true
}
func (h *Helm) Run(args string) (out []byte, err error) {
- return Exec(args)
+ return HelmExec(args)
}
// API functions
return out, err
}
- return Exec(strings.Join([]string{"init -c"}, ""))
+ return HelmExec(strings.Join([]string{"init -c"}, ""))
}
func (h *Helm) AddRepo() (out []byte, err error) {
// Get helm repo address from values.yaml
repo := viper.GetString("helm.repo")
- return Exec(strings.Join([]string{"repo add ", rname, " ", repo, username, pwd}, ""))
+ return HelmExec(strings.Join([]string{"repo add ", rname, " ", repo, username, pwd}, ""))
}
-func (h *Helm) Install(name string) (xapp Xapp, err error) {
+func (h *Helm) Install(m ConfigMetadata) (xapp Xapp, err error) {
out, err := h.Run(strings.Join([]string{"repo update "}, ""))
if err != nil {
return
}
- rname := viper.GetString("helm.repo-name")
+ m.Namespace = getNamespace(m.Namespace)
+ cm, cmErr := PurgeConfigMap(m)
- ns := getNamespaceArgs()
- out, err = h.Run(strings.Join([]string{"install ", rname, "/", name, " --name ", name, ns}, ""))
+ ns := " --namespace=" + m.Namespace
+ rname := viper.GetString("helm.repo-name")
+ out, err = h.Run(strings.Join([]string{"install ", rname, "/", m.Name, " --name ", m.Name, ns}, ""))
if err != nil {
return
}
- return h.ParseStatus(name, string(out))
+ if cmErr == nil {
+ cmErr = RestoreConfigMap(m, cm)
+ }
+ return h.ParseStatus(m.Name, string(out))
}
func (h *Helm) Status(name string) (xapp Xapp, err error) {
func (h *Helm) List() (names []string, err error) {
- ns := getNamespaceArgs()
- out, err := h.Run(strings.Join([]string{"list --all --output yaml ", ns}, ""))
+ ns := getNamespace("")
+ out, err := h.Run(strings.Join([]string{"list --all --output yaml --namespace=", ns}, ""))
if err != nil {
mdclog(MdclogErr, formatLog("Listing deployed xapps failed", "", err.Error()))
return
}
// Helper functions
-func (h *Helm) GetMessages(name string) (msgs MessageTypes, err error) {
- tarDir := viper.GetString("xapp.tarDir")
- if tarDir == "" {
- tarDir = "/tmp"
- }
-
- if h.Fetch(name, tarDir); err != nil {
- mdclog(MdclogWarn, formatLog("Fetch chart failed", "", err.Error()))
- return
- }
-
- return h.ParseMessages(name, tarDir, viper.GetString("xapp.msg_type_file"))
-
-}
-
-func (h *Helm) ParseMessages(name string, chartDir, msgFile string) (msgs MessageTypes, err error) {
- yamlFile, err := ioutil.ReadFile(path.Join(chartDir, name, msgFile))
- if err != nil {
- mdclog(MdclogWarn, formatLog("ReadFile failed", "", err.Error()))
- return
- }
-
- err = yaml.Unmarshal(yamlFile, &msgs)
- if err != nil {
- mdclog(MdclogWarn, formatLog("Unmarshal failed", "", err.Error()))
- return
- }
-
- if err = os.RemoveAll(path.Join(chartDir, name)); err != nil {
- mdclog(MdclogWarn, formatLog("RemoveAll failed", "", err.Error()))
- }
-
- return
-}
-
func (h *Helm) GetVersion(name string) (version string) {
- ns := getNamespaceArgs()
- out, err := h.Run(strings.Join([]string{"list --output yaml ", name, ns}, ""))
+ ns := getNamespace("")
+ out, err := h.Run(strings.Join([]string{"list --output yaml --namespace=", ns, " ", name}, ""))
if err != nil {
return
}
xapp.Version = h.GetVersion(name)
xapp.Status = h.GetState(out)
- types, err := h.GetMessages(name)
+ types, err := GetMessages(name)
if err != nil {
// xAPP can still be deployed if the msg_type file is missing.
- mdclog(MdclogWarn, formatLog("method GetMessages Failed....", "", err.Error()))
+ mdclog(MdclogWarn, formatLog("GetMessages Failed....", "", err.Error()))
//Set err back to nil, so it does not cause issues in called functions.
err = nil
return err
}
-func getNamespaceArgs() string {
+func getNamespace(namespace string) string {
+ if namespace != "" {
+ return namespace
+ }
+
ns := viper.GetString("xapp.namespace")
if ns == "" {
ns = "ricxapp"
}
- return " --namespace=" + ns
+ return ns
}
func formatLog(text string, args string, err string) string {
func mdclog(severity C.mdclog_severity_t, msg string) {
msg = fmt.Sprintf("%s:: %s ", time.Now().Format("2019-01-02 15:04:05"), msg)
- C.mdclog_mdc_add(C.CString("XM"), C.CString("1.0.0"))
+ C.mdclog_mdc_add(C.CString("XM"), C.CString("1.0.1"))
C.xAppMgr_mdclog_write(severity, C.CString(msg))
}
}
func TestTeardown(t *testing.T) {
- db := sdl.Create(viper.GetString("db.sessionNamespace"))
+ db := sdl.NewSdlInstance(viper.GetString("db.sessionNamespace"), sdl.NewDatabase())
db.RemoveAll()
}
}
type Xapp struct {
- Name string `json:"name"`
- Status string `json:"status"`
- Version string `json:"version"`
- Instances []XappInstance `json:"instances"`
+ Name string `json:"name"`
+ ConfigName string `json:"configName, omitempty"`
+ Namespace string `json:"namespace, omitempty"`
+ Status string `json:"status"`
+ Version string `json:"version"`
+ Instances []XappInstance `json:"instances"`
}
type XappInstance struct {
type Helmer interface {
Initialize()
- Install(name string) (xapp Xapp, err error)
+ Install(m ConfigMetadata) (xapp Xapp, err error)
Status(name string) (xapp Xapp, err error)
StatusAll() (xapps []Xapp, err error)
List() (xapps []string, err error)
"host": ":8080"
"helm":
"host": "192.168.0.12:31807"
- "repo": "/opt/ric/dummy-xapp-chart"
- "repo-name": "dummy"
+ "repo": "http://192.168.0.6/charts"
+ "repo-name": "helm-repo"
"secrets":
"username": "admin"
"password": "ric"
"helm-username-file": "./helm_repo_username"
"helm-password-file": "./helm_repo_password"
+ "retry": 1
"xapp":
"namespace": "ricxapp"
"tarDir": "/tmp"
- "msg_type_file": "msg_type.yaml"
+ "schema": "descriptors/schema.json"
+ "config": "config/config-file.json"
+ "tmpConfig": "/tmp/config-file.json"
"db":
"sessionNamespace": "XMSession"
"host": ":6379"
require (
gerrit.oran-osc.org/r/ric-plt/sdlgo v0.0.0
+ github.com/BurntSushi/toml v0.3.1 // indirect
github.com/fsnotify/fsnotify v1.4.7
github.com/gorilla/mux v1.7.1
- github.com/mitchellh/mapstructure v1.1.2
github.com/orcaman/concurrent-map v0.0.0-20190314100340-2693aad1ed75
github.com/segmentio/ksuid v1.0.2
github.com/spf13/viper v1.3.2
- gopkg.in/yaml.v2 v2.2.2
+ github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect
+ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
+ github.com/xeipuuv/gojsonschema v1.1.0
)
-replace gerrit.oran-osc.org/r/ric-plt/sdlgo => ./internal/sdlgo
+replace gerrit.oran-osc.org/r/ric-plt/sdlgo => gerrit.oran-osc.org/r/ric-plt/sdlgo.git v0.0.1
+gerrit.oran-osc.org/r/ric-plt/sdlgo.git v0.0.1 h1:l2dl31r++3xhgCumTzwvuo0/F415eqU4aFk/uDQ4WnM=
+gerrit.oran-osc.org/r/ric-plt/sdlgo.git v0.0.1/go.mod h1:LVhkNS82IofJTBK/VYPKiYed9MG/3OFwvWC6MGSDw1w=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4=
github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA=
+github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/gorilla/mux v1.7.1 h1:Dw4jY2nghMMRsh1ol8dv1axHkDwMQK2DHerMNJsIpJU=
github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/ginkgo v1.8.0 h1:VkHVNpR4iVnU8XQR6DBm8BqYjN7CRzw+xKUbVVbbW9w=
github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
+github.com/onsi/gomega v1.5.0 h1:izbySO9zDPmjJ8rDjLvkA2zJHIo+HkYXHnf7eN7SSyo=
github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/orcaman/concurrent-map v0.0.0-20190314100340-2693aad1ed75 h1:IV56VwUb9Ludyr7s53CMuEh4DdTnnQtEPLEgLyJ0kHI=
github.com/orcaman/concurrent-map v0.0.0-20190314100340-2693aad1ed75/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.3.2 h1:VUFqw5KcqRf7i70GOzW7N+Q7+gxVBkSSqiXB12+JQ4M=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
+github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
+github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
+github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
+github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
+github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
+github.com/xeipuuv/gojsonschema v1.1.0 h1:ngVtJC9TY/lg0AA/1k48FYhBrhRoFlEmWzsehpNAaZg=
+github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/net v0.0.0-20180906233101-161cd47e91fd h1:nTDtHvHSdCn1m6ITfMRqtOd/9+7a3s8RBNOZ3eYZzJA=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a h1:1n5lsVfiQW3yfsRGu98756EH1YthsFqr/5mxHduZW2A=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
# Modify this section to point to Docker image repository
image:
#repository: "snapshot.docker.ranco-dev-tools.eastus.cloudapp.azure.com:10001"
- repository: "k8s-cluster-docker-helm-repo:5000"
+ repository: "192.168.0.6:5000"
#repositoryCred:
# user: docker
# xAppmanager Docker image name and tag
name: appmgr
- tag: 1.0.0
+ tag: 1.0.1
#nameOverride: ""
#fullnameOverride: ""
"host": ":8080"
"helm":
# Remote helm repo URL. UPDATE this as required.
- "repo": "https://k8s-cluster-docker-helm-repo/helm_charts"
+ "repo": "http://192.168.0.6/charts"
# Repo name referred within the appmgr
"repo-name": "helm-repo"
# helm username and password files
"helm-username-file": "/opt/ric/secret/helm_repo_username"
"helm-password-file": "/opt/ric/secret/helm_repo_password"
+ "retry": 1
"xapp":
#Namespace to install xAPPs
"namespace": "ricxapp"
-
- #File containing xAPP message types
- "msg_type_file": "msg_type.yaml"
+ "tarDir": "/tmp"
+ "schema": "descriptors/schema.json"
+ "config": "config/config-file.json"
+ "tmpConfig": "/tmp/config-file.json"
# To be provided as env variables
appenv: