├── .DS_Store ├── .dockerignore ├── .gitignore ├── .helmignore ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── Dockerfile ├── Jenkinsfile ├── Makefile ├── README.md ├── charts ├── .DS_Store ├── preview │ ├── Chart.yaml │ ├── Makefile │ ├── requirements.yaml │ └── values.yaml └── showcase-admin-tool │ ├── .DS_Store │ ├── .helmignore │ ├── Chart.yaml │ ├── Makefile │ ├── README.md │ ├── templates │ ├── .DS_Store │ ├── NOTES.txt │ ├── _helpers.tpl │ ├── deployment.yaml │ ├── role.yaml │ ├── rolebinding.yaml │ ├── service.yaml │ └── serviceaccount.yaml │ └── values.yaml ├── mvnw ├── mvnw.cmd ├── pom.xml ├── skaffold.yaml ├── src ├── main │ ├── java │ │ └── org │ │ │ └── s1p │ │ │ └── demo │ │ │ └── spring │ │ │ └── boot │ │ │ └── admin │ │ │ ├── DemoApplication.java │ │ │ ├── config │ │ │ └── AdminServerDiscoveryAutoConfiguration.java │ │ │ └── discovery │ │ │ ├── DefaultServiceInstanceConverter.java │ │ │ ├── InstanceDiscoveryListener.java │ │ │ ├── KubernetesServiceInstanceConverter.java │ │ │ └── ServiceInstanceConverter.java │ └── resources │ │ ├── META-INF │ │ └── additional-spring-configuration-metadata.json │ │ ├── application.yml │ │ └── bootstrap.yml └── test │ └── java │ └── org │ └── s1p │ └── demo │ └── spring │ └── boot │ └── admin │ └── DemoApplicationTests.java └── watch.sh /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salaboy/showcase-admin-tool/54434308b1ebf7a2ffc0467e0241eaec8c6b3f32/.DS_Store -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | draft.toml 2 | charts/ 3 | NOTICE 4 | LICENSE 5 | README.md -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | ### IntelliJ IDEA ### 14 | .idea 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | /nbproject/private/ 21 | /build/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ -------------------------------------------------------------------------------- /.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | *.png 23 | 24 | # known compile time folders 25 | target/ 26 | node_modules/ 27 | vendor/ -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salaboy/showcase-admin-tool/54434308b1ebf7a2ffc0467e0241eaec8c6b3f32/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.3/apache-maven-3.5.3-bin.zip 2 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jdk-slim 2 | ENV PORT 8080 3 | ENV CLASSPATH /opt/lib 4 | EXPOSE 8080 5 | 6 | # copy pom.xml and wildcards to avoid this command failing if there's no target/lib directory 7 | COPY pom.xml target/lib* /opt/lib/ 8 | 9 | # NOTE we assume there's only 1 jar in the target dir 10 | # but at least this means we don't have to guess the name 11 | # we could do with a better way to know the name - or to always create an app.jar or something 12 | COPY target/*.jar /opt/app.jar 13 | WORKDIR /opt 14 | ENTRYPOINT exec java $JAVA_OPTS -jar app.jar -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | pipeline { 2 | agent { 3 | label "jenkins-maven" 4 | } 5 | environment { 6 | ORG = 'salaboy' 7 | APP_NAME = 'showcase-admin-tool' 8 | CHARTMUSEUM_CREDS = credentials('jenkins-x-chartmuseum') 9 | } 10 | stages { 11 | stage('CI Build and push snapshot') { 12 | when { 13 | branch 'PR-*' 14 | } 15 | environment { 16 | PREVIEW_VERSION = "0.0.0-SNAPSHOT-$BRANCH_NAME-$BUILD_NUMBER" 17 | PREVIEW_NAMESPACE = "$APP_NAME-$BRANCH_NAME".toLowerCase() 18 | HELM_RELEASE = "$PREVIEW_NAMESPACE".toLowerCase() 19 | } 20 | steps { 21 | container('maven') { 22 | sh "mvn versions:set -DnewVersion=$PREVIEW_VERSION" 23 | sh "mvn install" 24 | sh 'export VERSION=$PREVIEW_VERSION && skaffold build -f skaffold.yaml' 25 | 26 | 27 | sh "jx step post build --image $DOCKER_REGISTRY/$ORG/$APP_NAME:$PREVIEW_VERSION" 28 | } 29 | 30 | dir ('./charts/preview') { 31 | container('maven') { 32 | sh "make preview" 33 | sh "jx preview --app $APP_NAME --dir ../.." 34 | } 35 | } 36 | } 37 | } 38 | stage('Build Release') { 39 | when { 40 | branch 'master' 41 | } 42 | steps { 43 | container('maven') { 44 | // ensure we're not on a detached head 45 | sh "git checkout master" 46 | sh "git config --global credential.helper store" 47 | 48 | sh "jx step git credentials" 49 | // so we can retrieve the version in later steps 50 | sh "echo \$(jx-release-version) > VERSION" 51 | sh "mvn versions:set -DnewVersion=\$(cat VERSION)" 52 | } 53 | dir ('./charts/showcase-admin-tool') { 54 | container('maven') { 55 | sh "make tag" 56 | } 57 | } 58 | container('maven') { 59 | sh 'mvn clean deploy' 60 | 61 | sh 'export VERSION=`cat VERSION` && skaffold build -f skaffold.yaml' 62 | 63 | 64 | sh "jx step post build --image $DOCKER_REGISTRY/$ORG/$APP_NAME:\$(cat VERSION)" 65 | } 66 | } 67 | } 68 | stage('Promote to Environments') { 69 | when { 70 | branch 'master' 71 | } 72 | steps { 73 | dir ('./charts/showcase-admin-tool') { 74 | container('maven') { 75 | sh 'jx step changelog --version v\$(cat ../../VERSION)' 76 | 77 | // release the helm chart 78 | sh 'jx step helm release' 79 | 80 | // promote through all 'Auto' promotion Environments 81 | sh 'jx promote -b --all-auto --timeout 1h --version \$(cat ../../VERSION)' 82 | } 83 | } 84 | } 85 | } 86 | } 87 | post { 88 | always { 89 | cleanWs() 90 | } 91 | failure { 92 | input """Pipeline failed. 93 | We will keep the build pod around to help you diagnose any failures. 94 | 95 | Select Proceed or Abort to terminate the build pod""" 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | # Makefile 3 | # see https://www.gnu.org/software/make/manual/make.html 4 | 5 | 6 | # VARIABLES 7 | 8 | NAME := showcase-admin-tool 9 | GIT_COMMIT_HASH := $(shell git log --pretty=format:'%h' -n 1) 10 | 11 | BUILD_TOOL := ./mvnw 12 | JAR_FILE := $(shell find build/libs -name '*.jar' 2>/dev/null) 13 | 14 | IMAGE_NAME := samples/$(NAME) 15 | IMAGE_TAG := latest 16 | 17 | # CLOUD-NATIVE 18 | IMAGE_EXPOSE_PORT := 8080 19 | # LOCALHOST 20 | #IMAGE_EXPOSE_PORT := 9291 21 | 22 | DOCKER_HOST_IP := localhost 23 | DOCKER_HOST_PORT := 5000 24 | 25 | .PHONY: help 26 | .DEFAULT_GOAL := help 27 | 28 | 29 | # GENERAL 30 | 31 | help : ## Help 32 | @echo "" 33 | @echo "*** $(NAME) Makefile help ***" 34 | @echo "" 35 | @echo "Targets list:" 36 | @grep -E '^[a-zA-Z_-]+ :.*?## .*$$' $(MAKEFILE_LIST) | sort -k 1,1 | awk 'BEGIN {FS = ":.*?## "}; {printf "\t\033[36m%-30s\033[0m %s\n", $$1, $$2}' 37 | @echo "" 38 | 39 | print-variables : ## Print variables values 40 | @echo "MAKE: $(MAKE)" 41 | @echo "MAKEFILES: $(MAKEFILES)" 42 | @echo "MAKEFILE_LIST: $(MAKEFILE_LIST)" 43 | @echo "- - - " 44 | @echo "NAME: $(NAME)" 45 | @echo "GIT_COMMIT_HASH: $(GIT_COMMIT_HASH)" 46 | @echo "- - - " 47 | @echo "BUILD_TOOL: $(BUILD_TOOL)" 48 | @echo "JAR_FILE: $(JAR_FILE)" 49 | @echo "- - - " 50 | @echo "IMAGE_NAME: $(IMAGE_NAME)" 51 | @echo "IMAGE_TAG: $(IMAGE_TAG)" 52 | @echo "IMAGE_EXPOSE_PORT: $(IMAGE_EXPOSE_PORT)" 53 | @echo "DOCKER_HOST_IP: $(DOCKER_HOST_IP)" 54 | @echo "DOCKER_HOST_PORT: $(DOCKER_HOST_PORT)" 55 | 56 | 57 | # BUILDING 58 | 59 | build : ## Build the application excluding tests 60 | $(BUILD_TOOL) package -DskipTests 61 | 62 | build-test : ## Build the application including tests 63 | $(BUILD_TOOL) package 64 | 65 | clean : ## Clean the application 66 | $(BUILD_TOOL) clean 67 | 68 | clean-build : ## Clean and Build the application excluding tests 69 | $(BUILD_TOOL) clean package -DskipTests 70 | 71 | clean-build-test : ## Clean and Build the application including tests 72 | $(BUILD_TOOL) clean package 73 | 74 | 75 | # TESTING 76 | 77 | test : clean-build ## Run all tests in the application 78 | $(BUILD_TOOL) test 79 | 80 | unit-test : clean-build ## Run Unit tests in the application 81 | $(BUILD_TOOL) test 82 | 83 | integration-test : clean-build ## Run Integration tests in the application 84 | $(BUILD_TOOL) -Dtest=*IntegrationTest test 85 | 86 | specific-test : clean-build ## Run Specific tests in the application 87 | $(BUILD_TOOL) -Dtest=$@ test 88 | 89 | 90 | # RUNNING 91 | 92 | run : ## Run the application through Spring Boot 93 | $(BUILD_TOOL) spring-boot:run -DskipTests 94 | 95 | javarun : ## Run the application through the generated fat-jar 96 | java -jar $(JAR_FILE) 97 | 98 | 99 | # DOCKER 100 | 101 | docker-build : clean-build-test ## Build the docker IMAGE_NAME of the application 102 | docker build -t $(IMAGE_NAME):$(IMAGE_TAG)-$(GIT_COMMIT_HASH) -f Dockerfile . 103 | 104 | docker-run : docker-build ## Run the containerised application through docker 105 | docker run -d --name $(NAME) -p $(IMAGE_EXPOSE_PORT):$(IMAGE_EXPOSE_PORT) $(IMAGE_NAME):$(IMAGE_TAG)-$(GIT_COMMIT_HASH) 106 | 107 | docker-stop : ## Stop the containerised application 108 | docker container stop -f $(NAME) 109 | 110 | docker-push : docker-build ## Push the docker application to the docker registry 111 | docker push $(DOCKER_HOST_IP):$(DOCKER_HOST_PORT)/$(IMAGE_NAME):$(IMAGE_TAG)-$(GIT_COMMIT_HASH) 112 | 113 | docker-delete-local : docker-stop ## Delete the docker IMAGE_NAME of the application 114 | docker container rm -f $(NAME) 115 | docker image rm -f $(NAME) 116 | 117 | docker-delete-remote : docker-stop ## Delete the docker IMAGE_NAME of the application from the docker registry 118 | docker image remove $(DOCKER_HOST_IP):$(DOCKER_HOST_PORT)/$(IMAGE_NAME):$(IMAGE_TAG)-$(GIT_COMMIT_HASH) 119 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Showcase - Spring Boot Admin server 2 | -------------------------------------------------------------------------------- /charts/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salaboy/showcase-admin-tool/54434308b1ebf7a2ffc0467e0241eaec8c6b3f32/charts/.DS_Store -------------------------------------------------------------------------------- /charts/preview/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: A Helm chart for Kubernetes 3 | icon: https://raw.githubusercontent.com/jenkins-x/jenkins-x-platform/master/images/java.png 4 | name: preview 5 | version: 0.1.0-SNAPSHOT 6 | -------------------------------------------------------------------------------- /charts/preview/Makefile: -------------------------------------------------------------------------------- 1 | OS := $(shell uname) 2 | 3 | preview: 4 | ifeq ($(OS),Darwin) 5 | sed -i "" -e "s/version:.*/version: $(PREVIEW_VERSION)/" Chart.yaml 6 | sed -i "" -e "s/version:.*/version: $(PREVIEW_VERSION)/" ../*/Chart.yaml 7 | sed -i "" -e "s/tag: .*/tag: $(PREVIEW_VERSION)/" values.yaml 8 | else ifeq ($(OS),Linux) 9 | sed -i -e "s/version:.*/version: $(PREVIEW_VERSION)/" Chart.yaml 10 | sed -i -e "s/version:.*/version: $(PREVIEW_VERSION)/" ../*/Chart.yaml 11 | sed -i -e "s|repository: .*|repository: $(DOCKER_REGISTRY)\/salaboy\/showcase-admin-tool|" values.yaml 12 | sed -i -e "s/tag: .*/tag: $(PREVIEW_VERSION)/" values.yaml 13 | else 14 | echo "platfrom $(OS) not supported to release from" 15 | exit -1 16 | endif 17 | echo " version: $(PREVIEW_VERSION)" >> requirements.yaml 18 | jx step helm build 19 | -------------------------------------------------------------------------------- /charts/preview/requirements.yaml: -------------------------------------------------------------------------------- 1 | 2 | dependencies: 3 | - alias: expose 4 | name: exposecontroller 5 | repository: https://chartmuseum.build.cd.jenkins-x.io 6 | version: 2.3.56 7 | - alias: cleanup 8 | name: exposecontroller 9 | repository: https://chartmuseum.build.cd.jenkins-x.io 10 | version: 2.3.56 11 | - alias: preview 12 | name: showcase-admin-tool 13 | repository: file://../showcase-admin-tool 14 | -------------------------------------------------------------------------------- /charts/preview/values.yaml: -------------------------------------------------------------------------------- 1 | 2 | expose: 3 | Annotations: 4 | helm.sh/hook: post-install,post-upgrade 5 | helm.sh/hook-delete-policy: hook-succeeded 6 | config: 7 | exposer: Ingress 8 | http: true 9 | tlsacme: false 10 | 11 | cleanup: 12 | Args: 13 | - --cleanup 14 | Annotations: 15 | helm.sh/hook: pre-delete 16 | helm.sh/hook-delete-policy: hook-succeeded 17 | 18 | preview: 19 | image: 20 | repository: 21 | tag: 22 | pullPolicy: IfNotPresent -------------------------------------------------------------------------------- /charts/showcase-admin-tool/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salaboy/showcase-admin-tool/54434308b1ebf7a2ffc0467e0241eaec8c6b3f32/charts/showcase-admin-tool/.DS_Store -------------------------------------------------------------------------------- /charts/showcase-admin-tool/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *~ 18 | # Various IDEs 19 | .project 20 | .idea/ 21 | *.tmproj 22 | -------------------------------------------------------------------------------- /charts/showcase-admin-tool/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | description: A Helm chart for Kubernetes 3 | icon: https://raw.githubusercontent.com/jenkins-x/jenkins-x-platform/master/images/java.png 4 | name: showcase-admin-tool 5 | version: 0.1.0-SNAPSHOT 6 | -------------------------------------------------------------------------------- /charts/showcase-admin-tool/Makefile: -------------------------------------------------------------------------------- 1 | CHART_REPO := http://jenkins-x-chartmuseum:8080 2 | CURRENT=$(pwd) 3 | NAME := showcase-admin-tool 4 | OS := $(shell uname) 5 | RELEASE_VERSION := $(shell cat ../../VERSION) 6 | 7 | build: clean 8 | rm -rf requirements.lock 9 | helm dependency build 10 | helm lint 11 | 12 | install: clean build 13 | helm install . --name ${NAME} 14 | 15 | upgrade: clean build 16 | helm upgrade ${NAME} . 17 | 18 | delete: 19 | helm delete --purge ${NAME} 20 | 21 | clean: 22 | rm -rf charts 23 | rm -rf ${NAME}*.tgz 24 | 25 | release: clean 26 | helm dependency build 27 | helm lint 28 | helm init --client-only 29 | helm package . 30 | curl --fail -u $(CHARTMUSEUM_CREDS_USR):$(CHARTMUSEUM_CREDS_PSW) --data-binary "@$(NAME)-$(shell sed -n 's/^version: //p' Chart.yaml).tgz" $(CHART_REPO)/api/charts 31 | rm -rf ${NAME}*.tgz% 32 | 33 | tag: 34 | ifeq ($(OS),Darwin) 35 | sed -i "" -e "s/version:.*/version: $(RELEASE_VERSION)/" Chart.yaml 36 | sed -i "" -e "s/tag: .*/tag: $(RELEASE_VERSION)/" values.yaml 37 | else ifeq ($(OS),Linux) 38 | sed -i -e "s/version:.*/version: $(RELEASE_VERSION)/" Chart.yaml 39 | sed -i -e "s|repository: .*|repository: $(DOCKER_REGISTRY)\/salaboy\/showcase-admin-tool|" values.yaml 40 | sed -i -e "s/tag: .*/tag: $(RELEASE_VERSION)/" values.yaml 41 | else 42 | echo "platfrom $(OS) not supported to release from" 43 | exit -1 44 | endif 45 | git add --all 46 | git commit -m "release $(RELEASE_VERSION)" --allow-empty # if first release then no verion update is performed 47 | git tag -fa v$(RELEASE_VERSION) -m "Release version $(RELEASE_VERSION)" 48 | git push origin v$(RELEASE_VERSION) 49 | -------------------------------------------------------------------------------- /charts/showcase-admin-tool/README.md: -------------------------------------------------------------------------------- 1 | # Java application -------------------------------------------------------------------------------- /charts/showcase-admin-tool/templates/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/salaboy/showcase-admin-tool/54434308b1ebf7a2ffc0467e0241eaec8c6b3f32/charts/showcase-admin-tool/templates/.DS_Store -------------------------------------------------------------------------------- /charts/showcase-admin-tool/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 2 | Get the application URL by running these commands: 3 | 4 | kubectl get ingress {{ template "fullname" . }} 5 | -------------------------------------------------------------------------------- /charts/showcase-admin-tool/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | {{/* 3 | Expand the name of the chart. 4 | */}} 5 | {{- define "name" -}} 6 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} 7 | {{- end -}} 8 | 9 | {{/* 10 | Create a default fully qualified app name. 11 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 12 | */}} 13 | {{- define "fullname" -}} 14 | {{- $name := default .Chart.Name .Values.nameOverride -}} 15 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} 16 | {{- end -}} 17 | -------------------------------------------------------------------------------- /charts/showcase-admin-tool/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: extensions/v1beta1 2 | kind: Deployment 3 | metadata: 4 | name: {{ .Chart.Name }} 5 | labels: 6 | draft: {{ default "draft-app" .Values.draft }} 7 | chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}" 8 | spec: 9 | replicas: {{ .Values.replicaCount }} 10 | template: 11 | metadata: 12 | labels: 13 | draft: {{ default "draft-app" .Values.draft }} 14 | app: {{ template "fullname" . }} 15 | {{- if .Values.podAnnotations }} 16 | annotations: 17 | {{ toYaml .Values.podAnnotations | indent 8 }} 18 | {{- end }} 19 | spec: 20 | containers: 21 | - name: {{ .Chart.Name }} 22 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" 23 | env: 24 | - name: JAVA_OPTS 25 | value: -Xmx{{ .Values.javaOpts.xmx }} -Xms{{ .Values.javaOpts.xms }} {{ .Values.javaOpts.other}} 26 | imagePullPolicy: {{ .Values.image.pullPolicy }} 27 | ports: 28 | - containerPort: {{ .Values.service.internalPort }} 29 | livenessProbe: 30 | httpGet: 31 | path: {{ .Values.probePath }} 32 | port: {{ .Values.service.internalPort }} 33 | initialDelaySeconds: {{ .Values.livenessProbe.initialDelaySeconds }} 34 | periodSeconds: {{ .Values.livenessProbe.periodSeconds }} 35 | successThreshold: {{ .Values.livenessProbe.successThreshold }} 36 | timeoutSeconds: {{ .Values.livenessProbe.timeoutSeconds }} 37 | readinessProbe: 38 | httpGet: 39 | path: {{ .Values.probePath }} 40 | port: {{ .Values.service.internalPort }} 41 | periodSeconds: {{ .Values.readinessProbe.periodSeconds }} 42 | successThreshold: {{ .Values.readinessProbe.successThreshold }} 43 | timeoutSeconds: {{ .Values.readinessProbe.timeoutSeconds }} 44 | resources: 45 | {{ toYaml .Values.resources | indent 12 }} 46 | terminationGracePeriodSeconds: {{ .Values.terminationGracePeriodSeconds }} 47 | serviceAccountName: {{ .Chart.Name }} -------------------------------------------------------------------------------- /charts/showcase-admin-tool/templates/role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: Role 3 | metadata: 4 | name: {{ .Chart.Name }} 5 | rules: 6 | - apiGroups: 7 | - extensions 8 | resources: 9 | - ingresses 10 | verbs: 11 | - get 12 | - list 13 | - watch 14 | - patch 15 | - create 16 | - update 17 | - delete 18 | - apiGroups: 19 | - "" 20 | resources: 21 | - configmaps 22 | - services 23 | - endpoints 24 | - pods 25 | - configmaps 26 | verbs: 27 | - get 28 | - list 29 | - watch 30 | - patch 31 | - update 32 | - apiGroups: 33 | - apps 34 | resources: 35 | - deployments 36 | verbs: 37 | - get 38 | - list 39 | - watch 40 | - patch 41 | - update 42 | - apiGroups: 43 | - "" 44 | resources: 45 | - routes 46 | verbs: 47 | - get 48 | - list 49 | - watch 50 | - patch 51 | - create 52 | - update 53 | - delete 54 | -------------------------------------------------------------------------------- /charts/showcase-admin-tool/templates/rolebinding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: {{ .Chart.Name }} 5 | namespace: {{ .Release.Namespace }} 6 | roleRef: 7 | apiGroup: rbac.authorization.k8s.io 8 | kind: Role 9 | name: {{ .Chart.Name }} 10 | subjects: 11 | - kind: ServiceAccount 12 | name: {{ .Chart.Name }} 13 | namespace: {{ .Release.Namespace }} 14 | -------------------------------------------------------------------------------- /charts/showcase-admin-tool/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | {{- if .Values.service.name }} 5 | name: {{ .Values.service.name }} 6 | {{- else }} 7 | name: {{ template "fullname" . }} 8 | {{- end }} 9 | labels: 10 | chart: "{{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}" 11 | {{- if .Values.service.annotations }} 12 | annotations: 13 | {{ toYaml .Values.service.annotations | indent 4 }} 14 | {{- end }} 15 | spec: 16 | type: {{ .Values.service.type }} 17 | ports: 18 | - port: {{ .Values.service.externalPort }} 19 | targetPort: {{ .Values.service.internalPort }} 20 | protocol: TCP 21 | name: http 22 | selector: 23 | app: {{ template "fullname" . }} 24 | -------------------------------------------------------------------------------- /charts/showcase-admin-tool/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ServiceAccount 3 | metadata: 4 | labels: 5 | app: {{ .Chart.Name }} 6 | chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" 7 | release: "{{ .Release.Name }}" 8 | heritage: "{{ .Release.Service }}" 9 | name: {{ .Chart.Name }} 10 | -------------------------------------------------------------------------------- /charts/showcase-admin-tool/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for Maven projects. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | replicaCount: 1 5 | image: 6 | repository: draft 7 | tag: dev 8 | pullPolicy: IfNotPresent 9 | service: 10 | name: showcase-admin-tool 11 | type: ClusterIP 12 | externalPort: 80 13 | internalPort: 8080 14 | annotations: 15 | fabric8.io/expose: "true" 16 | fabric8.io/ingress.annotations: "kubernetes.io/ingress.class: nginx" 17 | resources: 18 | limits: 19 | cpu: 1000m 20 | memory: 1024Mi 21 | requests: 22 | cpu: 1000m 23 | memory: 1024Mi 24 | probePath: /actuator/health 25 | livenessProbe: 26 | initialDelaySeconds: 60 27 | periodSeconds: 10 28 | successThreshold: 1 29 | timeoutSeconds: 1 30 | readinessProbe: 31 | periodSeconds: 10 32 | successThreshold: 1 33 | timeoutSeconds: 1 34 | terminationGracePeriodSeconds: 10 35 | javaOpts: 36 | xmx: 1024m 37 | xms: 768m 38 | other: -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -Dsun.zip.disableMemoryMapping=true -XX:+UseParallelGC -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=10 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -------------------------------------------------------------------------------- /mvnw: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # ---------------------------------------------------------------------------- 3 | # Licensed to the Apache Software Foundation (ASF) under one 4 | # or more contributor license agreements. See the NOTICE file 5 | # distributed with this work for additional information 6 | # regarding copyright ownership. The ASF licenses this file 7 | # to you under the Apache License, Version 2.0 (the 8 | # "License"); you may not use this file except in compliance 9 | # with the License. You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, 14 | # software distributed under the License is distributed on an 15 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 | # KIND, either express or implied. See the License for the 17 | # specific language governing permissions and limitations 18 | # under the License. 19 | # ---------------------------------------------------------------------------- 20 | 21 | # ---------------------------------------------------------------------------- 22 | # Maven2 Start Up Batch script 23 | # 24 | # Required ENV vars: 25 | # ------------------ 26 | # JAVA_HOME - location of a JDK home dir 27 | # 28 | # Optional ENV vars 29 | # ----------------- 30 | # M2_HOME - location of maven2's installed home dir 31 | # MAVEN_OPTS - parameters passed to the Java VM when running Maven 32 | # e.g. to debug Maven itself, use 33 | # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 34 | # MAVEN_SKIP_RC - flag to disable loading of mavenrc files 35 | # ---------------------------------------------------------------------------- 36 | 37 | if [ -z "$MAVEN_SKIP_RC" ] ; then 38 | 39 | if [ -f /etc/mavenrc ] ; then 40 | . /etc/mavenrc 41 | fi 42 | 43 | if [ -f "$HOME/.mavenrc" ] ; then 44 | . "$HOME/.mavenrc" 45 | fi 46 | 47 | fi 48 | 49 | # OS specific support. $var _must_ be set to either true or false. 50 | cygwin=false; 51 | darwin=false; 52 | mingw=false 53 | case "`uname`" in 54 | CYGWIN*) cygwin=true ;; 55 | MINGW*) mingw=true;; 56 | Darwin*) darwin=true 57 | # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home 58 | # See https://developer.apple.com/library/mac/qa/qa1170/_index.html 59 | if [ -z "$JAVA_HOME" ]; then 60 | if [ -x "/usr/libexec/java_home" ]; then 61 | export JAVA_HOME="`/usr/libexec/java_home`" 62 | else 63 | export JAVA_HOME="/Library/Java/Home" 64 | fi 65 | fi 66 | ;; 67 | esac 68 | 69 | if [ -z "$JAVA_HOME" ] ; then 70 | if [ -r /etc/gentoo-release ] ; then 71 | JAVA_HOME=`java-config --jre-home` 72 | fi 73 | fi 74 | 75 | if [ -z "$M2_HOME" ] ; then 76 | ## resolve links - $0 may be a link to maven's home 77 | PRG="$0" 78 | 79 | # need this for relative symlinks 80 | while [ -h "$PRG" ] ; do 81 | ls=`ls -ld "$PRG"` 82 | link=`expr "$ls" : '.*-> \(.*\)$'` 83 | if expr "$link" : '/.*' > /dev/null; then 84 | PRG="$link" 85 | else 86 | PRG="`dirname "$PRG"`/$link" 87 | fi 88 | done 89 | 90 | saveddir=`pwd` 91 | 92 | M2_HOME=`dirname "$PRG"`/.. 93 | 94 | # make it fully qualified 95 | M2_HOME=`cd "$M2_HOME" && pwd` 96 | 97 | cd "$saveddir" 98 | # echo Using m2 at $M2_HOME 99 | fi 100 | 101 | # For Cygwin, ensure paths are in UNIX format before anything is touched 102 | if $cygwin ; then 103 | [ -n "$M2_HOME" ] && 104 | M2_HOME=`cygpath --unix "$M2_HOME"` 105 | [ -n "$JAVA_HOME" ] && 106 | JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 107 | [ -n "$CLASSPATH" ] && 108 | CLASSPATH=`cygpath --path --unix "$CLASSPATH"` 109 | fi 110 | 111 | # For Migwn, ensure paths are in UNIX format before anything is touched 112 | if $mingw ; then 113 | [ -n "$M2_HOME" ] && 114 | M2_HOME="`(cd "$M2_HOME"; pwd)`" 115 | [ -n "$JAVA_HOME" ] && 116 | JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" 117 | # TODO classpath? 118 | fi 119 | 120 | if [ -z "$JAVA_HOME" ]; then 121 | javaExecutable="`which javac`" 122 | if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then 123 | # readlink(1) is not available as standard on Solaris 10. 124 | readLink=`which readlink` 125 | if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then 126 | if $darwin ; then 127 | javaHome="`dirname \"$javaExecutable\"`" 128 | javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" 129 | else 130 | javaExecutable="`readlink -f \"$javaExecutable\"`" 131 | fi 132 | javaHome="`dirname \"$javaExecutable\"`" 133 | javaHome=`expr "$javaHome" : '\(.*\)/bin'` 134 | JAVA_HOME="$javaHome" 135 | export JAVA_HOME 136 | fi 137 | fi 138 | fi 139 | 140 | if [ -z "$JAVACMD" ] ; then 141 | if [ -n "$JAVA_HOME" ] ; then 142 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 143 | # IBM's JDK on AIX uses strange locations for the executables 144 | JAVACMD="$JAVA_HOME/jre/sh/java" 145 | else 146 | JAVACMD="$JAVA_HOME/bin/java" 147 | fi 148 | else 149 | JAVACMD="`which java`" 150 | fi 151 | fi 152 | 153 | if [ ! -x "$JAVACMD" ] ; then 154 | echo "Error: JAVA_HOME is not defined correctly." >&2 155 | echo " We cannot execute $JAVACMD" >&2 156 | exit 1 157 | fi 158 | 159 | if [ -z "$JAVA_HOME" ] ; then 160 | echo "Warning: JAVA_HOME environment variable is not set." 161 | fi 162 | 163 | CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher 164 | 165 | # traverses directory structure from process work directory to filesystem root 166 | # first directory with .mvn subdirectory is considered project base directory 167 | find_maven_basedir() { 168 | 169 | if [ -z "$1" ] 170 | then 171 | echo "Path not specified to find_maven_basedir" 172 | return 1 173 | fi 174 | 175 | basedir="$1" 176 | wdir="$1" 177 | while [ "$wdir" != '/' ] ; do 178 | if [ -d "$wdir"/.mvn ] ; then 179 | basedir=$wdir 180 | break 181 | fi 182 | # workaround for JBEAP-8937 (on Solaris 10/Sparc) 183 | if [ -d "${wdir}" ]; then 184 | wdir=`cd "$wdir/.."; pwd` 185 | fi 186 | # end of workaround 187 | done 188 | echo "${basedir}" 189 | } 190 | 191 | # concatenates all lines of a file 192 | concat_lines() { 193 | if [ -f "$1" ]; then 194 | echo "$(tr -s '\n' ' ' < "$1")" 195 | fi 196 | } 197 | 198 | BASE_DIR=`find_maven_basedir "$(pwd)"` 199 | if [ -z "$BASE_DIR" ]; then 200 | exit 1; 201 | fi 202 | 203 | export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} 204 | echo $MAVEN_PROJECTBASEDIR 205 | MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" 206 | 207 | # For Cygwin, switch paths to Windows format before running java 208 | if $cygwin; then 209 | [ -n "$M2_HOME" ] && 210 | M2_HOME=`cygpath --path --windows "$M2_HOME"` 211 | [ -n "$JAVA_HOME" ] && 212 | JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` 213 | [ -n "$CLASSPATH" ] && 214 | CLASSPATH=`cygpath --path --windows "$CLASSPATH"` 215 | [ -n "$MAVEN_PROJECTBASEDIR" ] && 216 | MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` 217 | fi 218 | 219 | WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 220 | 221 | exec "$JAVACMD" \ 222 | $MAVEN_OPTS \ 223 | -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ 224 | "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ 225 | ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" 226 | -------------------------------------------------------------------------------- /mvnw.cmd: -------------------------------------------------------------------------------- 1 | @REM ---------------------------------------------------------------------------- 2 | @REM Licensed to the Apache Software Foundation (ASF) under one 3 | @REM or more contributor license agreements. See the NOTICE file 4 | @REM distributed with this work for additional information 5 | @REM regarding copyright ownership. The ASF licenses this file 6 | @REM to you under the Apache License, Version 2.0 (the 7 | @REM "License"); you may not use this file except in compliance 8 | @REM with the License. You may obtain a copy of the License at 9 | @REM 10 | @REM http://www.apache.org/licenses/LICENSE-2.0 11 | @REM 12 | @REM Unless required by applicable law or agreed to in writing, 13 | @REM software distributed under the License is distributed on an 14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | @REM KIND, either express or implied. See the License for the 16 | @REM specific language governing permissions and limitations 17 | @REM under the License. 18 | @REM ---------------------------------------------------------------------------- 19 | 20 | @REM ---------------------------------------------------------------------------- 21 | @REM Maven2 Start Up Batch script 22 | @REM 23 | @REM Required ENV vars: 24 | @REM JAVA_HOME - location of a JDK home dir 25 | @REM 26 | @REM Optional ENV vars 27 | @REM M2_HOME - location of maven2's installed home dir 28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands 29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending 30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven 31 | @REM e.g. to debug Maven itself, use 32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files 34 | @REM ---------------------------------------------------------------------------- 35 | 36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' 37 | @echo off 38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' 39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% 40 | 41 | @REM set %HOME% to equivalent of $HOME 42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") 43 | 44 | @REM Execute a user defined script before this one 45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre 46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending 47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" 48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" 49 | :skipRcPre 50 | 51 | @setlocal 52 | 53 | set ERROR_CODE=0 54 | 55 | @REM To isolate internal variables from possible post scripts, we use another setlocal 56 | @setlocal 57 | 58 | @REM ==== START VALIDATION ==== 59 | if not "%JAVA_HOME%" == "" goto OkJHome 60 | 61 | echo. 62 | echo Error: JAVA_HOME not found in your environment. >&2 63 | echo Please set the JAVA_HOME variable in your environment to match the >&2 64 | echo location of your Java installation. >&2 65 | echo. 66 | goto error 67 | 68 | :OkJHome 69 | if exist "%JAVA_HOME%\bin\java.exe" goto init 70 | 71 | echo. 72 | echo Error: JAVA_HOME is set to an invalid directory. >&2 73 | echo JAVA_HOME = "%JAVA_HOME%" >&2 74 | echo Please set the JAVA_HOME variable in your environment to match the >&2 75 | echo location of your Java installation. >&2 76 | echo. 77 | goto error 78 | 79 | @REM ==== END VALIDATION ==== 80 | 81 | :init 82 | 83 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". 84 | @REM Fallback to current working directory if not found. 85 | 86 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% 87 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir 88 | 89 | set EXEC_DIR=%CD% 90 | set WDIR=%EXEC_DIR% 91 | :findBaseDir 92 | IF EXIST "%WDIR%"\.mvn goto baseDirFound 93 | cd .. 94 | IF "%WDIR%"=="%CD%" goto baseDirNotFound 95 | set WDIR=%CD% 96 | goto findBaseDir 97 | 98 | :baseDirFound 99 | set MAVEN_PROJECTBASEDIR=%WDIR% 100 | cd "%EXEC_DIR%" 101 | goto endDetectBaseDir 102 | 103 | :baseDirNotFound 104 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR% 105 | cd "%EXEC_DIR%" 106 | 107 | :endDetectBaseDir 108 | 109 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig 110 | 111 | @setlocal EnableExtensions EnableDelayedExpansion 112 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a 113 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% 114 | 115 | :endReadAdditionalConfig 116 | 117 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" 118 | 119 | set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" 120 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain 121 | 122 | %MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* 123 | if ERRORLEVEL 1 goto error 124 | goto end 125 | 126 | :error 127 | set ERROR_CODE=1 128 | 129 | :end 130 | @endlocal & set ERROR_CODE=%ERROR_CODE% 131 | 132 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost 133 | @REM check for post script, once with legacy .bat ending and once with .cmd ending 134 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" 135 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" 136 | :skipRcPost 137 | 138 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' 139 | if "%MAVEN_BATCH_PAUSE%" == "on" pause 140 | 141 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% 142 | 143 | exit /B %ERROR_CODE% 144 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.s1p.demo 7 | spring-boot-admin-k8s 8 | 0.0.1-SNAPSHOT 9 | jar 10 | 11 | S1P : Spring Boot Admin K8s 12 | S1P : Spring Boot Admin K8s 13 | 14 | 15 | 16 | UTF-8 17 | UTF-8 18 | 1.8 19 | 2.1.0-SNAPSHOT 20 | Finchley.SR1 21 | 1.0.0.BUILD-SNAPSHOT 22 | 3.7.0 23 | 24 | 25 | 26 | 27 | 28 | org.springframework.cloud 29 | spring-cloud-dependencies 30 | ${spring-cloud.version} 31 | pom 32 | import 33 | 34 | 35 | org.springframework.cloud 36 | spring-cloud-kubernetes 37 | ${spring.cloud.k8s.version} 38 | pom 39 | import 40 | 41 | 42 | de.codecentric 43 | spring-boot-admin-dependencies 44 | ${spring-boot-admin.version} 45 | pom 46 | import 47 | 48 | 49 | 50 | 51 | 52 | 53 | org.springframework.boot 54 | spring-boot-starter-actuator 55 | 56 | 57 | org.springframework.boot 58 | spring-boot-starter-web 59 | 60 | 61 | org.springframework.boot 62 | spring-boot-starter-security 63 | 64 | 65 | org.jolokia 66 | jolokia-core 67 | 68 | 69 | de.codecentric 70 | spring-boot-admin-starter-server 71 | 72 | 73 | org.springframework.cloud 74 | spring-cloud-kubernetes-discovery 75 | 76 | 77 | org.springframework.cloud 78 | spring-cloud-kubernetes-config 79 | 80 | 81 | org.springframework.boot 82 | spring-boot-devtools 83 | runtime 84 | 85 | 86 | org.projectlombok 87 | lombok 88 | true 89 | 90 | 91 | org.springframework.boot 92 | spring-boot-starter-test 93 | test 94 | 95 | 96 | 97 | 98 | 99 | 100 | org.apache.maven.plugins 101 | maven-compiler-plugin 102 | ${maven-compiler-plugin.version} 103 | 104 | ${java.version} 105 | ${java.version} 106 | true 107 | true 108 | true 109 | 110 | 111 | 112 | org.springframework.boot 113 | spring-boot-maven-plugin 114 | 115 | 116 | 117 | repackage 118 | build-info 119 | 120 | 121 | 122 | 123 | org.s1p.demo.spring.boot.admin.DemoApplication 124 | false 125 | 126 | 127 | 128 | 129 | org.apache.maven.plugins 130 | maven-deploy-plugin 131 | 2.8.2 132 | 133 | 134 | 135 | 136 | 137 | spring-snaps 138 | https://repo.spring.io/snapshot/ 139 | 140 | 141 | spring-libs-snaps 142 | https://repo.spring.io/libs-snapshot/ 143 | 144 | 145 | sonatype-nexus-snapshots 146 | Sonatype Nexus Snapshots 147 | https://oss.sonatype.org/content/repositories/snapshots/ 148 | 149 | true 150 | 151 | 152 | false 153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /skaffold.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: skaffold/v1alpha2 2 | kind: Config 3 | build: 4 | tagPolicy: 5 | envTemplate: 6 | template: "{{.DOCKER_REGISTRY}}/salaboy/showcase-admin-tool:{{.VERSION}}" 7 | artifacts: 8 | - imageName: changeme 9 | workspace: . 10 | docker: {} 11 | local: {} 12 | deploy: 13 | kubectl: 14 | manifests: 15 | profiles: 16 | - name: dev 17 | build: 18 | tagPolicy: 19 | envTemplate: 20 | template: "{{.DOCKER_REGISTRY}}/salaboy/showcase-admin-tool:{{.DIGEST_HEX}}" 21 | artifacts: 22 | - docker: {} 23 | local: {} 24 | deploy: 25 | helm: 26 | releases: 27 | - name: showcase-admin-tool 28 | chartPath: charts/showcase-admin-tool 29 | setValueTemplates: 30 | image.repository: "{{.DOCKER_REGISTRY}}/salaboy/showcase-admin-tool" 31 | image.tag: "{{.DIGEST_HEX}}" 32 | -------------------------------------------------------------------------------- /src/main/java/org/s1p/demo/spring/boot/admin/DemoApplication.java: -------------------------------------------------------------------------------- 1 | package org.s1p.demo.spring.boot.admin; 2 | 3 | import de.codecentric.boot.admin.server.config.EnableAdminServer; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 7 | import org.springframework.scheduling.annotation.EnableScheduling; 8 | 9 | @SpringBootApplication 10 | @EnableAdminServer 11 | @EnableDiscoveryClient 12 | @EnableScheduling 13 | public class DemoApplication { 14 | 15 | public static void main(String[] args) { 16 | SpringApplication.run(DemoApplication.class, args); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/org/s1p/demo/spring/boot/admin/config/AdminServerDiscoveryAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.s1p.demo.spring.boot.admin.config; 18 | 19 | 20 | import io.fabric8.kubernetes.client.KubernetesClient; 21 | import org.s1p.demo.spring.boot.admin.discovery.DefaultServiceInstanceConverter; 22 | import org.s1p.demo.spring.boot.admin.discovery.InstanceDiscoveryListener; 23 | import org.s1p.demo.spring.boot.admin.discovery.KubernetesServiceInstanceConverter; 24 | import org.s1p.demo.spring.boot.admin.discovery.ServiceInstanceConverter; 25 | import de.codecentric.boot.admin.server.config.AdminServerAutoConfiguration; 26 | import de.codecentric.boot.admin.server.config.AdminServerMarkerConfiguration; 27 | import de.codecentric.boot.admin.server.config.AdminServerProperties; 28 | import de.codecentric.boot.admin.server.domain.entities.InstanceRepository; 29 | import de.codecentric.boot.admin.server.services.InstanceRegistry; 30 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 31 | import org.springframework.boot.autoconfigure.AutoConfigureBefore; 32 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 33 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 34 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 35 | import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; 36 | import org.springframework.boot.context.properties.ConfigurationProperties; 37 | import org.springframework.cloud.client.discovery.DiscoveryClient; 38 | import org.springframework.context.annotation.Bean; 39 | import org.springframework.context.annotation.Configuration; 40 | import org.springframework.context.annotation.Primary; 41 | import org.springframework.context.annotation.Profile; 42 | import org.springframework.core.task.AsyncTaskExecutor; 43 | import org.springframework.security.config.annotation.web.builders.HttpSecurity; 44 | import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; 45 | import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; 46 | import org.springframework.security.web.csrf.CookieCsrfTokenRepository; 47 | import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer; 48 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 49 | 50 | @Configuration 51 | @ConditionalOnSingleCandidate(DiscoveryClient.class) 52 | @ConditionalOnBean(AdminServerMarkerConfiguration.Marker.class) 53 | @ConditionalOnProperty(prefix = "spring.boot.admin.discovery", name = "enabled", matchIfMissing = true) 54 | @AutoConfigureAfter(value = AdminServerAutoConfiguration.class, name = { 55 | "org.springframework.cloud.kubernetes.discovery.KubernetesDiscoveryClientAutoConfiguration", 56 | "org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration"}) 57 | public class AdminServerDiscoveryAutoConfiguration { 58 | 59 | @Bean 60 | @ConditionalOnMissingBean 61 | @ConfigurationProperties(prefix = "spring.boot.admin.discovery") 62 | public InstanceDiscoveryListener instanceDiscoveryListener(ServiceInstanceConverter serviceInstanceConverter, 63 | DiscoveryClient discoveryClient, 64 | InstanceRegistry registry, 65 | InstanceRepository repository) { 66 | InstanceDiscoveryListener listener = new InstanceDiscoveryListener(discoveryClient, registry, repository); 67 | listener.setConverter(serviceInstanceConverter); 68 | return listener; 69 | } 70 | 71 | @Configuration 72 | @ConditionalOnMissingBean({ServiceInstanceConverter.class}) 73 | @ConditionalOnBean(KubernetesClient.class) 74 | public static class KubernetesConverterConfiguration { 75 | @Bean 76 | @ConfigurationProperties(prefix = "spring.boot.admin.discovery.converter") 77 | public KubernetesServiceInstanceConverter serviceInstanceConverter() { 78 | return new KubernetesServiceInstanceConverter(); 79 | } 80 | } 81 | 82 | @Profile("secure") 83 | @Configuration 84 | public static class SecuritySecureConfig extends WebSecurityConfigurerAdapter { 85 | private final String adminContextPath; 86 | 87 | public SecuritySecureConfig(AdminServerProperties adminServerProperties) { 88 | this.adminContextPath = adminServerProperties.getContextPath(); 89 | } 90 | 91 | @Override 92 | protected void configure(HttpSecurity http) throws Exception { 93 | SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler(); 94 | successHandler.setTargetUrlParameter("redirectTo"); 95 | successHandler.setDefaultTargetUrl(adminContextPath + "/"); 96 | 97 | http.authorizeRequests() 98 | .antMatchers(adminContextPath + "/assets/**").permitAll() // <1> 99 | .antMatchers(adminContextPath + "/login").permitAll() 100 | .antMatchers(adminContextPath + "/actuator/**").permitAll() 101 | .anyRequest().authenticated() // <2> 102 | .and() 103 | .formLogin().loginPage(adminContextPath + "/login").successHandler(successHandler).and() // <3> 104 | .logout().logoutUrl(adminContextPath + "/logout").and() 105 | .httpBasic().and() // <4> 106 | .csrf() 107 | .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) // <5> 108 | .ignoringAntMatchers( 109 | adminContextPath + "/instances", // <6> 110 | adminContextPath + "/actuator/**" // <7> 111 | ); 112 | } 113 | } 114 | 115 | @Profile("insecure") 116 | @Configuration 117 | public static class SecurityPermitAllConfig extends WebSecurityConfigurerAdapter { 118 | private final String adminContextPath; 119 | 120 | public SecurityPermitAllConfig(AdminServerProperties adminServerProperties) { 121 | this.adminContextPath = adminServerProperties.getContextPath(); 122 | } 123 | 124 | @Override 125 | protected void configure(HttpSecurity http) throws Exception { 126 | http.authorizeRequests() 127 | .anyRequest() 128 | .permitAll() 129 | .and() 130 | .csrf() 131 | .csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse()) 132 | .ignoringAntMatchers(adminContextPath + "/instances", adminContextPath + "/actuator/**"); 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/main/java/org/s1p/demo/spring/boot/admin/discovery/DefaultServiceInstanceConverter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.s1p.demo.spring.boot.admin.discovery; 18 | 19 | import java.net.URI; 20 | import java.util.Map; 21 | 22 | import de.codecentric.boot.admin.server.domain.values.Registration; 23 | import org.slf4j.Logger; 24 | import org.slf4j.LoggerFactory; 25 | import org.springframework.cloud.client.ServiceInstance; 26 | import org.springframework.web.util.UriComponentsBuilder; 27 | 28 | import static org.springframework.util.StringUtils.isEmpty; 29 | 30 | public class DefaultServiceInstanceConverter implements ServiceInstanceConverter { 31 | private static final Logger LOGGER = LoggerFactory.getLogger(DefaultServiceInstanceConverter.class); 32 | private static final String KEY_MANAGEMENT_PORT = "management.port"; 33 | private static final String KEY_MANAGEMENT_PATH = "management.context-path"; 34 | private static final String KEY_HEALTH_PATH = "health.path"; 35 | 36 | /** 37 | * Default context-path to be appended to the url of the discovered service for the 38 | * managment-url. 39 | */ 40 | private String managementContextPath = "/actuator"; 41 | /** 42 | * Default path of the health-endpoint to be used for the health-url of the discovered service. 43 | */ 44 | private String healthEndpointPath = "health"; 45 | 46 | @Override 47 | public Registration convert(ServiceInstance instance) { 48 | LOGGER.debug("Converting service '{}' running at '{}' with metadata {}", instance.getServiceId(), 49 | instance.getUri(), instance.getMetadata()); 50 | 51 | Registration.Builder builder = Registration.create(instance.getServiceId(), getHealthUrl(instance).toString()); 52 | 53 | URI managementUrl = getManagementUrl(instance); 54 | if (managementUrl != null) { 55 | builder.managementUrl(managementUrl.toString()); 56 | } 57 | 58 | URI serviceUrl = getServiceUrl(instance); 59 | if (serviceUrl != null) { 60 | builder.serviceUrl(serviceUrl.toString()); 61 | } 62 | 63 | Map metadata = getMetadata(instance); 64 | if (metadata != null) { 65 | builder.metadata(metadata); 66 | } 67 | 68 | return builder.build(); 69 | } 70 | 71 | protected URI getHealthUrl(ServiceInstance instance) { 72 | String healthPath = instance.getMetadata().get(KEY_HEALTH_PATH); 73 | if (isEmpty(healthPath)) { 74 | healthPath = healthEndpointPath; 75 | } 76 | 77 | return UriComponentsBuilder.fromUri(getManagementUrl(instance)).path("/").path(healthPath).build().toUri(); 78 | } 79 | 80 | protected URI getManagementUrl(ServiceInstance instance) { 81 | String managamentPath = instance.getMetadata().get(KEY_MANAGEMENT_PATH); 82 | if (isEmpty(managamentPath)) { 83 | managamentPath = managementContextPath; 84 | } 85 | 86 | URI serviceUrl = getServiceUrl(instance); 87 | String managamentPort = instance.getMetadata().get(KEY_MANAGEMENT_PORT); 88 | if (isEmpty(managamentPort)) { 89 | managamentPort = String.valueOf(serviceUrl.getPort()); 90 | } 91 | 92 | return UriComponentsBuilder.fromUri(serviceUrl) 93 | .port(managamentPort) 94 | .path("/") 95 | .path(managamentPath) 96 | .build() 97 | .toUri(); 98 | } 99 | 100 | protected URI getServiceUrl(ServiceInstance instance) { 101 | return UriComponentsBuilder.fromUri(instance.getUri()).path("/").build().toUri(); 102 | } 103 | 104 | protected Map getMetadata(ServiceInstance instance) { 105 | return instance.getMetadata(); 106 | } 107 | 108 | 109 | public void setManagementContextPath(String managementContextPath) { 110 | this.managementContextPath = managementContextPath; 111 | } 112 | 113 | public String getManagementContextPath() { 114 | return managementContextPath; 115 | } 116 | 117 | public void setHealthEndpointPath(String healthEndpointPath) { 118 | this.healthEndpointPath = healthEndpointPath; 119 | } 120 | 121 | public String getHealthEndpointPath() { 122 | return healthEndpointPath; 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/main/java/org/s1p/demo/spring/boot/admin/discovery/InstanceDiscoveryListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.s1p.demo.spring.boot.admin.discovery; 18 | 19 | import java.util.Collections; 20 | import java.util.HashSet; 21 | import java.util.Set; 22 | import java.util.stream.Collectors; 23 | 24 | import de.codecentric.boot.admin.server.domain.entities.Instance; 25 | import de.codecentric.boot.admin.server.domain.entities.InstanceRepository; 26 | import de.codecentric.boot.admin.server.domain.values.InstanceId; 27 | import de.codecentric.boot.admin.server.domain.values.Registration; 28 | import de.codecentric.boot.admin.server.services.InstanceRegistry; 29 | import org.slf4j.Logger; 30 | import org.slf4j.LoggerFactory; 31 | import org.springframework.boot.context.event.ApplicationReadyEvent; 32 | import org.springframework.cloud.client.ServiceInstance; 33 | import org.springframework.cloud.client.discovery.DiscoveryClient; 34 | import org.springframework.cloud.client.discovery.event.HeartbeatEvent; 35 | import org.springframework.cloud.client.discovery.event.HeartbeatMonitor; 36 | import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent; 37 | import org.springframework.cloud.client.discovery.event.ParentHeartbeatEvent; 38 | import org.springframework.context.event.EventListener; 39 | import org.springframework.util.PatternMatchUtils; 40 | import reactor.core.publisher.Flux; 41 | import reactor.core.publisher.Mono; 42 | 43 | 44 | public class InstanceDiscoveryListener { 45 | private static final Logger log = LoggerFactory.getLogger(InstanceDiscoveryListener.class); 46 | private static final String SOURCE = "discovery"; 47 | private final DiscoveryClient discoveryClient; 48 | private final InstanceRegistry registry; 49 | private final InstanceRepository repository; 50 | private final HeartbeatMonitor monitor = new HeartbeatMonitor(); 51 | private ServiceInstanceConverter converter = new DefaultServiceInstanceConverter(); 52 | 53 | /** 54 | * Set of serviceIds to be ignored and not to be registered as application. Supports simple 55 | * patterns (e.g. "foo*", "*foo", "foo*bar"). 56 | */ 57 | private Set ignoredServices = new HashSet<>(); 58 | 59 | /** 60 | * Set of serviceIds that has to match to be registered as application. Supports simple 61 | * patterns (e.g. "foo*", "*foo", "foo*bar"). Default value is everything 62 | */ 63 | private Set services = new HashSet<>(Collections.singletonList("*")); 64 | 65 | public InstanceDiscoveryListener(DiscoveryClient discoveryClient, 66 | InstanceRegistry registry, 67 | InstanceRepository repository) { 68 | this.discoveryClient = discoveryClient; 69 | this.registry = registry; 70 | this.repository = repository; 71 | } 72 | 73 | @EventListener 74 | public void onApplicationReady(ApplicationReadyEvent event) { 75 | discover(); 76 | } 77 | 78 | @EventListener 79 | public void onInstanceRegistered(InstanceRegisteredEvent event) { 80 | discover(); 81 | } 82 | 83 | @EventListener 84 | public void onParentHeartbeat(ParentHeartbeatEvent event) { 85 | discoverIfNeeded(event.getValue()); 86 | } 87 | 88 | @EventListener 89 | public void onApplicationEvent(HeartbeatEvent event) { 90 | discoverIfNeeded(event.getValue()); 91 | } 92 | 93 | private void discoverIfNeeded(Object value) { 94 | if (this.monitor.update(value)) { 95 | discover(); 96 | } 97 | } 98 | 99 | protected void discover() { 100 | Flux.fromIterable(discoveryClient.getServices()) 101 | .filter(this::shouldRegisterService) 102 | .flatMapIterable(discoveryClient::getInstances) 103 | .flatMap(this::registerInstance) 104 | .collect(Collectors.toSet()) 105 | .flatMap(this::removeStaleInstances) 106 | .subscribe(v -> { }, ex -> log.error("Unexpected error.", ex)); 107 | } 108 | 109 | protected Mono removeStaleInstances(Set registeredInstanceIds) { 110 | return repository.findAll() 111 | .filter(instance -> SOURCE.equals(instance.getRegistration().getSource())) 112 | .map(Instance::getId) 113 | .filter(id -> !registeredInstanceIds.contains(id)) 114 | .doOnNext(id -> log.info("Instance ({}) missing in DiscoveryClient services ", id)) 115 | .flatMap(registry::deregister) 116 | .then(); 117 | } 118 | 119 | protected boolean shouldRegisterService(final String serviceId) { 120 | boolean shouldRegister = matchesPattern(serviceId, services) && !matchesPattern(serviceId, ignoredServices); 121 | if (!shouldRegister) { 122 | log.debug("Ignoring discovered service {}", serviceId); 123 | } 124 | return shouldRegister; 125 | } 126 | 127 | protected boolean matchesPattern(String serviceId, Set patterns) { 128 | return patterns.stream().anyMatch(pattern -> PatternMatchUtils.simpleMatch(pattern, serviceId)); 129 | } 130 | 131 | protected Mono registerInstance(ServiceInstance instance) { 132 | try { 133 | Registration registration = converter.convert(instance).toBuilder().source(SOURCE).build(); 134 | log.debug("Registering discovered instance {}", registration); 135 | return registry.register(registration); 136 | } catch (Exception ex) { 137 | log.error("Couldn't register instance for service {}", instance, ex); 138 | } 139 | return Mono.empty(); 140 | } 141 | 142 | public void setConverter(ServiceInstanceConverter converter) { 143 | this.converter = converter; 144 | } 145 | 146 | public void setIgnoredServices(Set ignoredServices) { 147 | this.ignoredServices = ignoredServices; 148 | } 149 | 150 | public Set getIgnoredServices() { 151 | return ignoredServices; 152 | } 153 | 154 | public Set getServices() { 155 | return services; 156 | } 157 | 158 | public void setServices(Set services) { 159 | this.services = services; 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /src/main/java/org/s1p/demo/spring/boot/admin/discovery/KubernetesServiceInstanceConverter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.s1p.demo.spring.boot.admin.discovery; 18 | 19 | import java.net.URI; 20 | 21 | import org.springframework.cloud.client.ServiceInstance; 22 | import org.springframework.cloud.kubernetes.discovery.KubernetesServiceInstance; 23 | import org.springframework.util.Assert; 24 | 25 | 26 | public class KubernetesServiceInstanceConverter extends DefaultServiceInstanceConverter { 27 | 28 | @Override 29 | protected URI getHealthUrl(ServiceInstance instance) { 30 | Assert.isInstanceOf(KubernetesServiceInstance.class, 31 | instance, 32 | "serviceInstance must be of type KubernetesServiceInstance"); 33 | return ((KubernetesServiceInstance) instance).getUri(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/org/s1p/demo/spring/boot/admin/discovery/ServiceInstanceConverter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014-2018 the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.s1p.demo.spring.boot.admin.discovery; 18 | 19 | import de.codecentric.boot.admin.server.domain.entities.Instance; 20 | import de.codecentric.boot.admin.server.domain.values.Registration; 21 | import org.springframework.cloud.client.ServiceInstance; 22 | 23 | 24 | public interface ServiceInstanceConverter { 25 | 26 | /** 27 | * Converts a service instance to a application instance to be registered. 28 | * 29 | * @param instance the service instance. 30 | * @return Instance 31 | */ 32 | Registration convert(ServiceInstance instance); 33 | } 34 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/additional-spring-configuration-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "groups": [ 3 | ], 4 | "properties": [ 5 | { 6 | "name": "spring.boot.admin.discovery.enabled", 7 | "type": "java.lang.Boolean", 8 | "description": "Enable Spring Cloud Discovery support.", 9 | "defaultValue": "true" 10 | } 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | main: 3 | allow-bean-definition-overriding: true 4 | application: 5 | name: showcase-admin-tool 6 | cloud: 7 | gateway: 8 | discovery: 9 | locator: 10 | enabled: true 11 | url-expression: "'http://'+serviceId" 12 | kubernetes: 13 | reload: 14 | enabled: true 15 | mode: polling 16 | period: 5000 17 | discovery: 18 | filter: "metadata.labels['spring-boot']" 19 | boot: 20 | admin: 21 | monitor: 22 | status-lifetime: 5000ms 23 | period: 5000ms 24 | read-timeout: 5000ms 25 | profiles: 26 | active: 27 | - secure 28 | 29 | logging: 30 | level: 31 | org.springframework.cloud.gateway: TRACE 32 | org.springframework.cloud.loadbalancer: TRACE 33 | 34 | management: 35 | endpoints: 36 | web: 37 | exposure: 38 | include: "*" 39 | endpoint: 40 | health: 41 | enabled: true 42 | show-details: ALWAYS 43 | restart: 44 | enabled: true 45 | health: 46 | info: 47 | enabled: true 48 | 49 | --- 50 | 51 | spring: 52 | profiles: secure 53 | security: 54 | user: 55 | name: "user" 56 | password: "password" 57 | 58 | --- 59 | 60 | spring: 61 | profiles: insecure 62 | 63 | -------------------------------------------------------------------------------- /src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: showcase-admin-tool 4 | cloud: 5 | kubernetes: 6 | reload: 7 | enabled: true 8 | mode: polling 9 | period: 5000 -------------------------------------------------------------------------------- /src/test/java/org/s1p/demo/spring/boot/admin/DemoApplicationTests.java: -------------------------------------------------------------------------------- 1 | package org.s1p.demo.spring.boot.admin; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.test.context.junit4.SpringRunner; 7 | 8 | @RunWith(SpringRunner.class) 9 | @SpringBootTest 10 | public class DemoApplicationTests { 11 | 12 | @Test 13 | public void contextLoads() { 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /watch.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # watch the java files and continously deploy the service 4 | mvn clean install 5 | skaffold run -p dev 6 | reflex -r "\.java$" -- bash -c 'mvn install && skaffold run -p dev' 7 | --------------------------------------------------------------------------------