Initial Commit
Change-Id: Iec38321b67ec1171d492b31b43ffed58ffabcbb2
This commit is contained in:
parent
9b05f5d222
commit
ac23039c0d
@ -22,3 +22,8 @@ version: 0.1.0
|
||||
# follow Semantic Versioning. They should reflect the version the application is using.
|
||||
# It is recommended to use it with quotes.
|
||||
appVersion: "latest"
|
||||
|
||||
dependencies:
|
||||
- name: postgresql
|
||||
version: 14.3.3
|
||||
repository: https://charts.bitnami.com/bitnami
|
||||
|
@ -27,6 +27,10 @@ spec:
|
||||
serviceAccountName: {{ include "nebulous-overlay-network-manager.serviceAccountName" . }}
|
||||
securityContext:
|
||||
{{- toYaml .Values.podSecurityContext | nindent 8 }}
|
||||
initContainers:
|
||||
- name: wait-for-postgresql
|
||||
image: docker.io/bitnami/postgresql:14.3.0
|
||||
command: ['sh', '-c', 'until pg_isready -h nebulous-overlay-network-manager-postgresql -p 5432; do echo waiting for database; sleep 2; done;']
|
||||
containers:
|
||||
- name: {{ .Chart.Name }}
|
||||
securityContext:
|
||||
@ -34,19 +38,33 @@ spec:
|
||||
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
- name: onm-api
|
||||
containerPort: 8082
|
||||
protocol: TCP
|
||||
- name: pgadmin
|
||||
containerPort: 5050
|
||||
protocol: TCP
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
resources:
|
||||
{{- toYaml .Values.resources | nindent 12 }}
|
||||
env:
|
||||
- name: POSTGRES_USER
|
||||
value: {{ .Values.postgresql.global.postgresql.auth.username }}
|
||||
- name: POSTGRES_PASSWORD
|
||||
value: {{ .Values.postgresql.global.postgresql.auth.password }}
|
||||
- name: POSTGRES_DB
|
||||
value: {{ .Values.postgresql.global.postgresql.auth.database }}
|
||||
- name: POSTGRES_IP_FQDN
|
||||
value: "nebulous-overlay-network-manager-postgresql"
|
||||
- name: POSTGRES_CONNECTION_STRING
|
||||
value: "jdbc:postgresql://nebulous-overlay-network-manager-postgresql:5432/postgres"
|
||||
- name: WIREGUARD_NETWORK_PORTION
|
||||
value: "{{ .Values.customEnv.WIREGUARD_NETWORK_PORTION }}"
|
||||
- name: WIREGUARD_DEFAULT_SERVER_IP
|
||||
value: "{{ .Values.customEnv.WIREGUARD_DEFAULT_SERVER_IP }}"
|
||||
- name: WIREGUARD_ALLOWED_IPS
|
||||
value: "{{ .Values.customEnv.WIREGUARD_ALLOWED_IPS }}"
|
||||
- name: _PROD_WG_BOOTSTRAP_AGENT_SCRIPTS_DIR
|
||||
value: "{{ .Values.customEnv._PROD_WG_BOOTSTRAP_AGENT_SCRIPTS_DIR }}"
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
|
@ -7,9 +7,13 @@ metadata:
|
||||
spec:
|
||||
type: {{ .Values.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.service.port }}
|
||||
targetPort: http
|
||||
- port: {{ .Values.service.pgadminPort }}
|
||||
targetPort: pgadmin
|
||||
protocol: TCP
|
||||
name: http
|
||||
name: pgadmin
|
||||
- port: {{ .Values.service.onmApiPort }}
|
||||
targetPort: onm-api
|
||||
protocol: TCP
|
||||
name: onm-api
|
||||
selector:
|
||||
{{- include "nebulous-overlay-network-manager.selectorLabels" . | nindent 4 }}
|
||||
|
@ -5,7 +5,7 @@
|
||||
replicaCount: 1
|
||||
|
||||
image:
|
||||
repository: "quay.io/nebulous/overlay-network-manager-java-spring-boot-demo"
|
||||
repository: "quay.io/nebulous/overlay-network-manager"
|
||||
pullPolicy: IfNotPresent
|
||||
# Overrides the image tag whose default is the chart appVersion.
|
||||
tag: ""
|
||||
@ -39,6 +39,8 @@ securityContext: {}
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 80
|
||||
pgadminPort: 5050
|
||||
onmApiPort: 8082
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
@ -80,3 +82,18 @@ nodeSelector: {}
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
||||
|
||||
postgresql:
|
||||
global:
|
||||
postgresql:
|
||||
auth:
|
||||
postgresPassword: "nebulous"
|
||||
username: "postgresql"
|
||||
password: "postgresql"
|
||||
database: "postgres"
|
||||
|
||||
customEnv:
|
||||
WIREGUARD_NETWORK_PORTION: "192.168.55."
|
||||
WIREGUARD_DEFAULT_SERVER_IP: "192.168.55.1"
|
||||
WIREGUARD_ALLOWED_IPS: "192.168.55.0/24"
|
||||
_PROD_WG_BOOTSTRAP_AGENT_SCRIPTS_DIR: "/deployments/wg-bootstrap-agent-scripts"
|
||||
|
@ -1,15 +0,0 @@
|
||||
#
|
||||
# Build stage
|
||||
#
|
||||
FROM docker.io/library/maven:3.9.2-eclipse-temurin-17 AS build
|
||||
COPY src /home/app/src
|
||||
COPY pom.xml /home/app
|
||||
RUN mvn -f /home/app/pom.xml clean package
|
||||
|
||||
#
|
||||
# Package stage
|
||||
#
|
||||
FROM docker.io/library/eclipse-temurin:17-jre
|
||||
COPY --from=build /home/app/target/demo-0.0.1-SNAPSHOT.jar /usr/local/lib/demo.jar
|
||||
EXPOSE 8080
|
||||
ENTRYPOINT ["java","-jar","/usr/local/lib/demo.jar"]
|
@ -1,42 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.1.0</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.example</groupId>
|
||||
<artifactId>demo</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>demo</name>
|
||||
<description>Demo project for Spring Boot</description>
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -1,13 +0,0 @@
|
||||
package com.example.demo;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class DemoApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(DemoApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package com.example.demo;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
public class DemoController {
|
||||
|
||||
@RequestMapping("/")
|
||||
public Object root() {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
package com.example.demo;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class DemoApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
11
network-manager/.env.example
Normal file
11
network-manager/.env.example
Normal file
@ -0,0 +1,11 @@
|
||||
PC_IP_ADDRESS=
|
||||
|
||||
POSTGRES_CONNECTION_STRING=
|
||||
POSTGRES_USER=
|
||||
POSTGRES_PASSWORD=
|
||||
|
||||
WIREGUARD_NETWORK_PORTION=
|
||||
WIREGUARD_DEFAULT_SERVER_IP=
|
||||
WIREGUARD_ALLOWED_IPS=
|
||||
_DEV_WG_BOOTSTRAP_AGENT_SCRIPTS_DIR=
|
||||
_PROD_WG_BOOTSTRAP_AGENT_SCRIPTS_DIR=
|
@ -31,3 +31,6 @@ build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
# Local environment
|
||||
.env
|
18
network-manager/.m2/settings.xml
Normal file
18
network-manager/.m2/settings.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
|
||||
http://maven.apache.org/xsd/settings-1.0.0.xsd">
|
||||
<servers>
|
||||
<server>
|
||||
<id>quarkus-base-no-auth</id>
|
||||
<configuration>
|
||||
<httpHeaders>
|
||||
<property>
|
||||
<name>Job-Token</name>
|
||||
<value>${CI_JOB_TOKEN}</value>
|
||||
</property>
|
||||
</httpHeaders>
|
||||
</configuration>
|
||||
</server>
|
||||
</servers>
|
||||
</settings>
|
1
network-manager/.mvn/wrapper/.gitignore
vendored
Normal file
1
network-manager/.mvn/wrapper/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
maven-wrapper.jar
|
142
network-manager/.mvn/wrapper/MavenWrapperDownloader.java
vendored
Normal file
142
network-manager/.mvn/wrapper/MavenWrapperDownloader.java
vendored
Normal file
@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
import java.nio.channels.*;
|
||||
import java.util.Properties;
|
||||
|
||||
public class MavenWrapperDownloader
|
||||
{
|
||||
private static final String WRAPPER_VERSION = "3.1.1";
|
||||
|
||||
/**
|
||||
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
|
||||
*/
|
||||
private static final String DEFAULT_DOWNLOAD_URL =
|
||||
"https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/" + WRAPPER_VERSION
|
||||
+ "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
|
||||
|
||||
/**
|
||||
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to use instead of the
|
||||
* default one.
|
||||
*/
|
||||
private static final String MAVEN_WRAPPER_PROPERTIES_PATH = ".mvn/wrapper/maven-wrapper.properties";
|
||||
|
||||
/**
|
||||
* Path where the maven-wrapper.jar will be saved to.
|
||||
*/
|
||||
private static final String MAVEN_WRAPPER_JAR_PATH = ".mvn/wrapper/maven-wrapper.jar";
|
||||
|
||||
/**
|
||||
* Name of the property which should be used to override the default download url for the wrapper.
|
||||
*/
|
||||
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
|
||||
|
||||
public static void main( String args[] )
|
||||
{
|
||||
System.out.println( "- Downloader started" );
|
||||
File baseDirectory = new File( args[0] );
|
||||
System.out.println( "- Using base directory: " + baseDirectory.getAbsolutePath() );
|
||||
|
||||
// If the maven-wrapper.properties exists, read it and check if it contains a custom
|
||||
// wrapperUrl parameter.
|
||||
File mavenWrapperPropertyFile = new File( baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH );
|
||||
String url = DEFAULT_DOWNLOAD_URL;
|
||||
if ( mavenWrapperPropertyFile.exists() )
|
||||
{
|
||||
FileInputStream mavenWrapperPropertyFileInputStream = null;
|
||||
try
|
||||
{
|
||||
mavenWrapperPropertyFileInputStream = new FileInputStream( mavenWrapperPropertyFile );
|
||||
Properties mavenWrapperProperties = new Properties();
|
||||
mavenWrapperProperties.load( mavenWrapperPropertyFileInputStream );
|
||||
url = mavenWrapperProperties.getProperty( PROPERTY_NAME_WRAPPER_URL, url );
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
System.out.println( "- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'" );
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
if ( mavenWrapperPropertyFileInputStream != null )
|
||||
{
|
||||
mavenWrapperPropertyFileInputStream.close();
|
||||
}
|
||||
}
|
||||
catch ( IOException e )
|
||||
{
|
||||
// Ignore ...
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println( "- Downloading from: " + url );
|
||||
|
||||
File outputFile = new File( baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH );
|
||||
if ( !outputFile.getParentFile().exists() )
|
||||
{
|
||||
if ( !outputFile.getParentFile().mkdirs() )
|
||||
{
|
||||
System.out.println( "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath()
|
||||
+ "'" );
|
||||
}
|
||||
}
|
||||
System.out.println( "- Downloading to: " + outputFile.getAbsolutePath() );
|
||||
try
|
||||
{
|
||||
downloadFileFromURL( url, outputFile );
|
||||
System.out.println( "Done" );
|
||||
System.exit( 0 );
|
||||
}
|
||||
catch ( Throwable e )
|
||||
{
|
||||
System.out.println( "- Error downloading" );
|
||||
e.printStackTrace();
|
||||
System.exit( 1 );
|
||||
}
|
||||
}
|
||||
|
||||
private static void downloadFileFromURL( String urlString, File destination )
|
||||
throws Exception
|
||||
{
|
||||
if ( System.getenv( "MVNW_USERNAME" ) != null && System.getenv( "MVNW_PASSWORD" ) != null )
|
||||
{
|
||||
String username = System.getenv( "MVNW_USERNAME" );
|
||||
char[] password = System.getenv( "MVNW_PASSWORD" ).toCharArray();
|
||||
Authenticator.setDefault( new Authenticator()
|
||||
{
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication()
|
||||
{
|
||||
return new PasswordAuthentication( username, password );
|
||||
}
|
||||
} );
|
||||
}
|
||||
URL website = new URL( urlString );
|
||||
ReadableByteChannel rbc;
|
||||
rbc = Channels.newChannel( website.openStream() );
|
||||
FileOutputStream fos = new FileOutputStream( destination );
|
||||
fos.getChannel().transferFrom( rbc, 0, Long.MAX_VALUE );
|
||||
fos.close();
|
||||
rbc.close();
|
||||
}
|
||||
|
||||
}
|
18
network-manager/.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
18
network-manager/.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip
|
||||
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar
|
43
network-manager/Dockerfile
Normal file
43
network-manager/Dockerfile
Normal file
@ -0,0 +1,43 @@
|
||||
FROM docker.io/curlimages/curl:8.5.0 AS downloader
|
||||
ARG RUN_JAVA_VERSION=1.3.5
|
||||
RUN curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /tmp/run-java.sh
|
||||
|
||||
FROM docker.io/maven:3.9.1-eclipse-temurin-20 AS build
|
||||
|
||||
WORKDIR /app
|
||||
COPY src ./src
|
||||
COPY wg-bootstrap-agent-scripts ./wg-bootstrap-agent-scripts
|
||||
COPY pom.xml ./
|
||||
|
||||
RUN mvn clean package -DskipTests
|
||||
|
||||
FROM docker.io/eclipse-temurin:20-jre-alpine
|
||||
|
||||
ENV USER_ID=1001
|
||||
|
||||
RUN mkdir /deployments \
|
||||
&& chown ${USER_ID} /deployments \
|
||||
&& chmod "g+rwX" /deployments \
|
||||
&& chown 1001:root /deployments
|
||||
|
||||
COPY --from=downloader /tmp/run-java.sh /deployments/run-java.sh
|
||||
|
||||
RUN chown ${USER_ID} /deployments/run-java.sh && chmod 540 /deployments/run-java.sh
|
||||
|
||||
# Configure the JAVA_OPTIONS, you can add -XshowSettings:vm to also display the heap size.
|
||||
ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager"
|
||||
ENV JAVA_TOOL_OPTIONS="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8090"
|
||||
ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en'
|
||||
|
||||
# Copy the built artifact from the maven image
|
||||
COPY --from=build /app/target/*-runner.jar /deployments/app.jar
|
||||
|
||||
# Copy scripts from build Dockerfile step
|
||||
COPY --from=build /app/wg-bootstrap-agent-scripts /deployments/wg-bootstrap-agent-scripts
|
||||
|
||||
EXPOSE 8080
|
||||
EXPOSE 8090
|
||||
|
||||
USER ${USER_ID}
|
||||
|
||||
ENTRYPOINT [ "/deployments/run-java.sh" ]
|
85
network-manager/README.md
Normal file
85
network-manager/README.md
Normal file
@ -0,0 +1,85 @@
|
||||
# Overlay Network Manager
|
||||
|
||||
## Provided Services
|
||||
|
||||
This is a template project, providing the bare minimum in order to build a Quarkus Service.
|
||||
To be more precise, it includes:
|
||||
1. Swagger UI with OpenAPI Specification
|
||||
|
||||
## Technology Stack
|
||||
|
||||
This project uses Quarkus, the Supersonic Subatomic Java Framework.
|
||||
|
||||
If you want to learn more about Quarkus, please visit its website: https://quarkus.io/.
|
||||
|
||||
Moreover, the core services used, alongside with their versions, are:
|
||||
1. Quarkus **3.2.7.Final**
|
||||
2. Java **20**
|
||||
|
||||
## Environmental Variables
|
||||
|
||||
There is a .env.example file containing all the appropriate information.
|
||||
|
||||
## Swagger/OpenAPI Services
|
||||
These are accessible through the following paths:
|
||||
1. Swagger UI: http://localhost:8080/api/swagger
|
||||
2. OpenAPI Specification: http://localhost:8080/api/openapi
|
||||
|
||||
## Running the application in dev mode
|
||||
|
||||
You can run your application in dev mode that enables live coding using:
|
||||
```shell script
|
||||
./mvnw compile quarkus:dev
|
||||
```
|
||||
> **_NOTE:_** Quarkus now ships with a Dev UI, which is available in dev mode only at http://localhost:8080/q/dev/.
|
||||
|
||||
## Packaging and running the application
|
||||
|
||||
The application can be packaged using:
|
||||
```shell script
|
||||
./mvnw package
|
||||
```
|
||||
It produces the `quarkus-run.jar` file in the `target/quarkus-app/` directory.
|
||||
Be aware that it’s not a _über-jar_ as the dependencies are copied into the `target/quarkus-app/lib/` directory.
|
||||
|
||||
The application is now runnable using `java -jar target/quarkus-app/quarkus-run.jar`.
|
||||
|
||||
If you want to build a _über-jar_, execute the following command:
|
||||
```shell script
|
||||
./mvnw package -Dquarkus.package.type=uber-jar
|
||||
```
|
||||
|
||||
The application, packaged as a _über-jar_, is now runnable using `java -jar target/*-runner.jar`.
|
||||
|
||||
## Creating a native executable
|
||||
|
||||
You can create a native executable using:
|
||||
```shell script
|
||||
./mvnw package -Pnative
|
||||
```
|
||||
|
||||
Or, if you don't have GraalVM installed, you can run the native executable build in a container using:
|
||||
```shell script
|
||||
./mvnw package -Pnative -Dquarkus.native.container-build=true
|
||||
```
|
||||
|
||||
You can then execute your native executable with: `./target/getting-started-1.0.0-SNAPSHOT-runner`
|
||||
|
||||
If you want to learn more about building native executables, please consult https://quarkus.io/guides/maven-tooling.
|
||||
|
||||
Run the docker image using:
|
||||
```shell script
|
||||
docker run -i --env-file .env --rm -p 8080:8080 <docker-image-name>
|
||||
```
|
||||
|
||||
## Related Guides
|
||||
|
||||
- RESTEasy Reactive ([guide](https://quarkus.io/guides/resteasy-reactive)): A JAX-RS implementation utilizing build time processing and Vert.x. This extension is not compatible with the quarkus-resteasy extension, or any of the extensions that depend on it.
|
||||
|
||||
## Provided Code
|
||||
|
||||
### RESTEasy Reactive
|
||||
|
||||
Easily start your Reactive RESTful Web Services
|
||||
|
||||
[Related guide section...](https://quarkus.io/guides/getting-started-reactive#reactive-jax-rs-resources)
|
@ -0,0 +1,52 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Define the original and the copy paths for the kubeconfig file
|
||||
ORIGINAL_KUBECONFIG_PATH="$HOME/.kube/config"
|
||||
KUBECONFIG_COPY_PATH="$HOME/.kube/config-copy"
|
||||
|
||||
# Copy the original kubeconfig file to a new location
|
||||
if [ -f "$ORIGINAL_KUBECONFIG_PATH" ]; then
|
||||
cp "$ORIGINAL_KUBECONFIG_PATH" "$KUBECONFIG_COPY_PATH"
|
||||
echo "Kubeconfig file copied to $KUBECONFIG_COPY_PATH."
|
||||
else
|
||||
echo "Original kubeconfig file not found at $ORIGINAL_KUBECONFIG_PATH."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Create the configmap from the copied kubeconfig file
|
||||
kubectl create configmap kubeconfig --from-file=config=$KUBECONFIG_COPY_PATH
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "ConfigMap created successfully."
|
||||
else
|
||||
echo "Failed to create ConfigMap."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Directory to store the YAML files
|
||||
REPO_URL="https://gitlab.ubitech.eu/nebulous/use-cases/k8s-gatekeeper/-/raw/origin/config"
|
||||
|
||||
# Create the directory if it doesn't exist
|
||||
CONFIG_DIR=$HOME/k8s/config
|
||||
mkdir -p $CONFIG_DIR
|
||||
|
||||
# List of configuration files to download
|
||||
CONFIG_FILES="rbac.yaml webhook_deployment.yaml webhook_internal.yaml auth.casbin.org_casbinmodels.yaml auth.casbin.org_casbinpolicies.yaml"
|
||||
|
||||
# Download the configuration files
|
||||
for file in $CONFIG_FILES; do
|
||||
echo "WGET file: $file"
|
||||
wget -O "$CONFIG_DIR/$file" "$REPO_URL/$file"
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to download $file."
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
# apply the downloaded configurations with delay
|
||||
DELAY=5
|
||||
for file in $CONFIG_FILES; do
|
||||
kubectl apply -f "$CONFIG_DIR/$file"
|
||||
sleep $DELAY
|
||||
done
|
||||
|
||||
echo "All configurations applied successfully."
|
@ -0,0 +1,70 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Capture the second argument as the hostname
|
||||
HOSTNAME=$1
|
||||
# Set the hostname
|
||||
echo "Setting hostname to '$HOSTNAME'..."
|
||||
sudo hostnamectl set-hostname "$HOSTNAME"
|
||||
|
||||
WIREGUARD_VPN_IP=`ip a | grep wg | grep inet | awk '{print $2}' | cut -d'/' -f1`
|
||||
|
||||
# Create k8s directory to host all appropriate files
|
||||
mkdir -p $HOME/k8s
|
||||
|
||||
# Update Repository
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt update
|
||||
|
||||
# Install libraries
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common
|
||||
|
||||
# Docker Keys
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --yes --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
|
||||
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
|
||||
# Update Repositories again
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt update
|
||||
|
||||
# Install Docker
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt install -y docker-ce=5:20.10.22~3-0~ubuntu-jammy docker-ce-cli=5:20.10.22~3-0~ubuntu-jammy containerd.io=1.6.14-1
|
||||
sudo usermod -aG docker $USER
|
||||
sudo systemctl enable docker
|
||||
sudo systemctl start docker
|
||||
cat <<EOF | sudo tee /etc/docker/daemon.json
|
||||
{
|
||||
"exec-opts": ["native.cgroupdriver=systemd"],
|
||||
"log-driver": "json-file",
|
||||
"log-opts": {
|
||||
"max-size": "100m"
|
||||
},
|
||||
"storage-driver": "overlay2"
|
||||
}
|
||||
EOF
|
||||
|
||||
sudo systemctl restart docker
|
||||
|
||||
# Kubernetes Keys
|
||||
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --yes --dearmor -o /usr/share/keyrings/google-archive-keyring.gpg
|
||||
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/google-archive-keyring.gpg] http://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list > /dev/null
|
||||
|
||||
# Update Repositories
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get update
|
||||
|
||||
# Install K8s CLI tools
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y kubeadm=1.22.4-00 kubelet=1.22.4-00 kubectl=1.22.4-00
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-mark hold kubeadm kubelet kubectl
|
||||
echo "KUBELET_EXTRA_ARGS=--node-ip=${WIREGUARD_VPN_IP}" | sudo tee -a /etc/default/kubelet
|
||||
sudo systemctl restart kubelet
|
||||
|
||||
# Disable Swap
|
||||
sudo swapoff -a
|
||||
sudo sed -i '/ swap / s/^/#/' /etc/fstab
|
||||
|
||||
# Set hostname label to K8s Node
|
||||
sudo kubectl label nodes "$HOSTNAME" disktype=ssd
|
||||
|
||||
# Install Helm Package Manager
|
||||
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
|
||||
sudo chmod 700 get_helm.sh
|
||||
sudo $HOME/get_helm.sh
|
||||
|
||||
echo "Configuration complete."
|
@ -0,0 +1,27 @@
|
||||
#!/bin/sh
|
||||
|
||||
WIREGUARD_VPN_IP=`ip a | grep wg | grep inet | awk '{print $2}' | cut -d'/' -f1`
|
||||
|
||||
# Init kubernetes
|
||||
sudo kubeadm init --apiserver-advertise-address ${WIREGUARD_VPN_IP} --service-cidr 10.96.0.0/16 --pod-network-cidr 10.244.0.0/16
|
||||
|
||||
# Set kubeconfig file
|
||||
mkdir -p $HOME/.kube
|
||||
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
|
||||
sudo chown $(id -u):$(id -g) $HOME/.kube/config
|
||||
|
||||
# Add Cilium Helm Repo
|
||||
helm repo add cilium https://helm.cilium.io/
|
||||
helm repo update
|
||||
|
||||
# Install Cilium with Wireguard parameters
|
||||
helm install cilium cilium/cilium --namespace kube-system --set encryption.enabled=true --set encryption.type=wireguard
|
||||
|
||||
# Add KubeVela Helm repository and update
|
||||
echo "Setting up KubeVela..."
|
||||
helm repo add kubevela https://kubevelacharts.oss-cn-hangzhou.aliyuncs.com/core
|
||||
helm repo update
|
||||
helm install --create-namespace -n vela-system kubevela kubevela/vela-core --wait
|
||||
|
||||
# Save join command to specific path for the worker nodes to SCP
|
||||
kubeadm token create --print-join-command > $HOME/k8s-join-command.sh
|
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
MASTER_IP=$1
|
||||
MASTER_USERNAME=$2
|
||||
|
||||
# Join Kubernetes Cluster
|
||||
sudo scp -o StrictHostKeyChecking=no -i $HOME/wg-private-key.key $MASTER_USERNAME@$MASTER_IP:/home/$MASTER_USERNAME/k8s-join-command.sh /home/$USER/k8s/k8s-join-command.sh
|
||||
|
||||
sudo chmod +x $HOME/k8s/k8s-join-command.sh
|
||||
|
||||
sudo $HOME/k8s/k8s-join-command.sh
|
316
network-manager/mvnw
vendored
Executable file
316
network-manager/mvnw
vendored
Executable file
@ -0,0 +1,316 @@
|
||||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# https://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.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Maven Start Up Batch script
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# JAVA_HOME - location of a JDK home dir
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# M2_HOME - location of maven2's installed home dir
|
||||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
# e.g. to debug Maven itself, use
|
||||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||
|
||||
if [ -f /usr/local/etc/mavenrc ] ; then
|
||||
. /usr/local/etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f /etc/mavenrc ] ; then
|
||||
. /etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f "$HOME/.mavenrc" ] ; then
|
||||
. "$HOME/.mavenrc"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# OS specific support. $var _must_ be set to either true or false.
|
||||
cygwin=false;
|
||||
darwin=false;
|
||||
mingw=false
|
||||
case "`uname`" in
|
||||
CYGWIN*) cygwin=true ;;
|
||||
MINGW*) mingw=true;;
|
||||
Darwin*) darwin=true
|
||||
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
|
||||
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
if [ -x "/usr/libexec/java_home" ]; then
|
||||
export JAVA_HOME="`/usr/libexec/java_home`"
|
||||
else
|
||||
export JAVA_HOME="/Library/Java/Home"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
if [ -r /etc/gentoo-release ] ; then
|
||||
JAVA_HOME=`java-config --jre-home`
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$M2_HOME" ] ; then
|
||||
## resolve links - $0 may be a link to maven's home
|
||||
PRG="$0"
|
||||
|
||||
# need this for relative symlinks
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG="`dirname "$PRG"`/$link"
|
||||
fi
|
||||
done
|
||||
|
||||
saveddir=`pwd`
|
||||
|
||||
M2_HOME=`dirname "$PRG"`/..
|
||||
|
||||
# make it fully qualified
|
||||
M2_HOME=`cd "$M2_HOME" && pwd`
|
||||
|
||||
cd "$saveddir"
|
||||
# echo Using m2 at $M2_HOME
|
||||
fi
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||
if $cygwin ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --unix "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
||||
fi
|
||||
|
||||
# For Mingw, ensure paths are in UNIX format before anything is touched
|
||||
if $mingw ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME="`(cd "$M2_HOME"; pwd)`"
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
javaExecutable="`which javac`"
|
||||
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
|
||||
# readlink(1) is not available as standard on Solaris 10.
|
||||
readLink=`which readlink`
|
||||
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
|
||||
if $darwin ; then
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
|
||||
else
|
||||
javaExecutable="`readlink -f \"$javaExecutable\"`"
|
||||
fi
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
|
||||
JAVA_HOME="$javaHome"
|
||||
export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JAVACMD" ] ; then
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
else
|
||||
JAVACMD="`\\unset -f command; \\command -v java`"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||
echo " We cannot execute $JAVACMD" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
echo "Warning: JAVA_HOME environment variable is not set."
|
||||
fi
|
||||
|
||||
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
||||
|
||||
# traverses directory structure from process work directory to filesystem root
|
||||
# first directory with .mvn subdirectory is considered project base directory
|
||||
find_maven_basedir() {
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "Path not specified to find_maven_basedir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
basedir="$1"
|
||||
wdir="$1"
|
||||
while [ "$wdir" != '/' ] ; do
|
||||
if [ -d "$wdir"/.mvn ] ; then
|
||||
basedir=$wdir
|
||||
break
|
||||
fi
|
||||
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
||||
if [ -d "${wdir}" ]; then
|
||||
wdir=`cd "$wdir/.."; pwd`
|
||||
fi
|
||||
# end of workaround
|
||||
done
|
||||
echo "${basedir}"
|
||||
}
|
||||
|
||||
# concatenates all lines of a file
|
||||
concat_lines() {
|
||||
if [ -f "$1" ]; then
|
||||
echo "$(tr -s '\n' ' ' < "$1")"
|
||||
fi
|
||||
}
|
||||
|
||||
BASE_DIR=`find_maven_basedir "$(pwd)"`
|
||||
if [ -z "$BASE_DIR" ]; then
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
##########################################################################################
|
||||
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
##########################################################################################
|
||||
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found .mvn/wrapper/maven-wrapper.jar"
|
||||
fi
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
|
||||
fi
|
||||
if [ -n "$MVNW_REPOURL" ]; then
|
||||
jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
|
||||
else
|
||||
jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
|
||||
fi
|
||||
while IFS="=" read key value; do
|
||||
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
|
||||
esac
|
||||
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Downloading from: $jarUrl"
|
||||
fi
|
||||
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
|
||||
if $cygwin; then
|
||||
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
|
||||
fi
|
||||
|
||||
if command -v wget > /dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found wget ... using wget"
|
||||
fi
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
|
||||
else
|
||||
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
|
||||
fi
|
||||
elif command -v curl > /dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found curl ... using curl"
|
||||
fi
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
curl -o "$wrapperJarPath" "$jarUrl" -f
|
||||
else
|
||||
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
|
||||
fi
|
||||
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Falling back to using Java to download"
|
||||
fi
|
||||
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||
# For Cygwin, switch paths to Windows format before running javac
|
||||
if $cygwin; then
|
||||
javaClass=`cygpath --path --windows "$javaClass"`
|
||||
fi
|
||||
if [ -e "$javaClass" ]; then
|
||||
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Compiling MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
# Compiling the Java class
|
||||
("$JAVA_HOME/bin/javac" "$javaClass")
|
||||
fi
|
||||
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
# Running the downloader
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Running MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
##########################################################################################
|
||||
# End of extension
|
||||
##########################################################################################
|
||||
|
||||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo $MAVEN_PROJECTBASEDIR
|
||||
fi
|
||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --path --windows "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
||||
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
|
||||
fi
|
||||
|
||||
# Provide a "standardized" way to retrieve the CLI args that will
|
||||
# work with both Windows and non-Windows executions.
|
||||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
|
||||
export MAVEN_CMD_LINE_ARGS
|
||||
|
||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
$MAVEN_DEBUG_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.home=${M2_HOME}" \
|
||||
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
188
network-manager/mvnw.cmd
vendored
Normal file
188
network-manager/mvnw.cmd
vendored
Normal file
@ -0,0 +1,188 @@
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM https://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Maven Start Up Batch script
|
||||
@REM
|
||||
@REM Required ENV vars:
|
||||
@REM JAVA_HOME - location of a JDK home dir
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM M2_HOME - location of maven2's installed home dir
|
||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
|
||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
@REM e.g. to debug Maven itself, use
|
||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM set title of command window
|
||||
title %0
|
||||
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM set %HOME% to equivalent of $HOME
|
||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
|
||||
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||
@setlocal
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
:OkJHome
|
||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set EXEC_DIR=%CD%
|
||||
set WDIR=%EXEC_DIR%
|
||||
:findBaseDir
|
||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set WDIR=%CD%
|
||||
goto findBaseDir
|
||||
|
||||
:baseDirFound
|
||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||
cd "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
|
||||
|
||||
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
|
||||
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
|
||||
)
|
||||
|
||||
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
if exist %WRAPPER_JAR% (
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Found %WRAPPER_JAR%
|
||||
)
|
||||
) else (
|
||||
if not "%MVNW_REPOURL%" == "" (
|
||||
SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar"
|
||||
)
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||
echo Downloading from: %DOWNLOAD_URL%
|
||||
)
|
||||
|
||||
powershell -Command "&{"^
|
||||
"$webclient = new-object System.Net.WebClient;"^
|
||||
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
|
||||
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
|
||||
"}"^
|
||||
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
|
||||
"}"
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Finished downloading %WRAPPER_JAR%
|
||||
)
|
||||
)
|
||||
@REM End of extension
|
||||
|
||||
@REM Provide a "standardized" way to retrieve the CLI args that will
|
||||
@REM work with both Windows and non-Windows executions.
|
||||
set MAVEN_CMD_LINE_ARGS=%*
|
||||
|
||||
%MAVEN_JAVA_EXE% ^
|
||||
%JVM_CONFIG_MAVEN_PROPS% ^
|
||||
%MAVEN_OPTS% ^
|
||||
%MAVEN_DEBUG_OPTS% ^
|
||||
-classpath %WRAPPER_JAR% ^
|
||||
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
|
||||
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
|
||||
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%"=="on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
|
||||
|
||||
cmd /C exit /B %ERROR_CODE%
|
210
network-manager/pom.xml
Normal file
210
network-manager/pom.xml
Normal file
@ -0,0 +1,210 @@
|
||||
<?xml version="1.0"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>eu.nebulous</groupId>
|
||||
<artifactId>network-manager</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<properties>
|
||||
<!-- Core Properties -->
|
||||
<compiler-plugin.version>3.11.0</compiler-plugin.version>
|
||||
<maven.compiler.release>17</maven.compiler.release>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
|
||||
<quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
|
||||
<quarkus.platform.version>3.2.7.Final</quarkus.platform.version>
|
||||
<!-- Skip Integration Tests Flag -->
|
||||
<skipITs>true</skipITs>
|
||||
<!-- Surefire Plugin Version -->
|
||||
<surefire-plugin.version>3.0.0</surefire-plugin.version>
|
||||
<!-- QPID JMS Properties -->
|
||||
<quarkus.qpid.jms.group-id>${quarkus.platform.group-id}</quarkus.qpid.jms.group-id>
|
||||
<quarkus.qpid.jms.version>${quarkus.platform.version}</quarkus.qpid.jms.version>
|
||||
<!-- Lombok Version -->
|
||||
<lombok.version>1.18.24</lombok.version>
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${quarkus.platform.group-id}</groupId>
|
||||
<artifactId>${quarkus.platform.artifact-id}</artifactId>
|
||||
<version>${quarkus.platform.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>${quarkus.qpid.jms.group-id}</groupId>
|
||||
<artifactId>quarkus-qpid-jms-bom</artifactId>
|
||||
<version>${quarkus.qpid.jms.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-resteasy</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-resteasy-jackson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-arc</artifactId>
|
||||
</dependency>
|
||||
<!-- Quarkus Test -->
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-junit5</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.rest-assured</groupId>
|
||||
<artifactId>rest-assured</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<!-- Smallrye -->
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-smallrye-openapi</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-smallrye-health</artifactId>
|
||||
</dependency>
|
||||
<!-- JSON Parser -->
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.10.1</version>
|
||||
</dependency>
|
||||
<!-- Application File in YAML Format -->
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-config-yaml</artifactId>
|
||||
</dependency>
|
||||
<!-- Hibernate -->
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-hibernate-validator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-hibernate-orm-panache</artifactId>
|
||||
</dependency>
|
||||
<!-- PostgreSQL -->
|
||||
<dependency>
|
||||
<groupId>io.quarkus</groupId>
|
||||
<artifactId>quarkus-jdbc-postgresql</artifactId>
|
||||
</dependency>
|
||||
<!-- BouncyCastle -->
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcprov-jdk18on</artifactId>
|
||||
<version>1.76</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bouncycastle</groupId>
|
||||
<artifactId>bcpkix-jdk15on</artifactId>
|
||||
<version>1.70</version>
|
||||
</dependency>
|
||||
<!-- Lombok -->
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<!-- Java SSH Remote Command Execution -->
|
||||
<dependency>
|
||||
<groupId>org.apache.sshd</groupId>
|
||||
<artifactId>sshd-core</artifactId>
|
||||
<version>2.11.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.sshd</groupId>
|
||||
<artifactId>sshd-common</artifactId>
|
||||
<version>2.11.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.sshd</groupId>
|
||||
<artifactId>sshd-scp</artifactId>
|
||||
<version>2.11.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>${quarkus.platform.group-id}</groupId>
|
||||
<artifactId>quarkus-maven-plugin</artifactId>
|
||||
<version>${quarkus.platform.version}</version>
|
||||
<extensions>true</extensions>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>build</goal>
|
||||
<goal>generate-code</goal>
|
||||
<goal>generate-code-tests</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>${compiler-plugin.version}</version>
|
||||
<configuration>
|
||||
<compilerArgs>
|
||||
<arg>-parameters</arg>
|
||||
</compilerArgs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${surefire-plugin.version}</version>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
|
||||
<maven.home>${maven.home}</maven.home>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-failsafe-plugin</artifactId>
|
||||
<version>${surefire-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>integration-test</goal>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<systemPropertyVariables>
|
||||
<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
|
||||
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
|
||||
<maven.home>${maven.home}</maven.home>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>native</id>
|
||||
<activation>
|
||||
<property>
|
||||
<name>native</name>
|
||||
</property>
|
||||
</activation>
|
||||
<properties>
|
||||
<skipITs>false</skipITs>
|
||||
<quarkus.package.type>native</quarkus.package.type>
|
||||
</properties>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
31
network-manager/src/main/java/Application.java
Normal file
31
network-manager/src/main/java/Application.java
Normal file
@ -0,0 +1,31 @@
|
||||
import io.quarkus.runtime.ShutdownEvent;
|
||||
import io.quarkus.runtime.StartupEvent;
|
||||
import io.quarkus.runtime.configuration.ProfileManager;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.enterprise.event.Observes;
|
||||
|
||||
import java.time.ZoneId;
|
||||
import java.util.TimeZone;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@ApplicationScoped
|
||||
public class Application {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(Application.class.getName());
|
||||
|
||||
public Application() {
|
||||
// Empty Constructor
|
||||
}
|
||||
|
||||
void onStart(@Observes StartupEvent ev) {
|
||||
logger.info("The application is starting...");
|
||||
logger.log(Level.INFO,"Default timezone: {0} with id {1}", new Object[]{TimeZone.getDefault().getDisplayName(), ZoneId.systemDefault()});
|
||||
var profile = ProfileManager.getLaunchMode();
|
||||
logger.log(Level.INFO,"Running profile: {0}", profile);
|
||||
}
|
||||
|
||||
void onStop(@Observes ShutdownEvent ev) {
|
||||
logger.info("The application is stopping...");
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package eu.nebulous.dto;
|
||||
|
||||
public record ApplicationNodeDto(
|
||||
String publicIp,
|
||||
String applicationUUID,
|
||||
Boolean isMaster,
|
||||
String sshUsername,
|
||||
String privateKeyBase64,
|
||||
String publicKey
|
||||
) {}
|
20
network-manager/src/main/java/eu/nebulous/dto/LogDto.java
Normal file
20
network-manager/src/main/java/eu/nebulous/dto/LogDto.java
Normal file
@ -0,0 +1,20 @@
|
||||
package eu.nebulous.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.logging.Level;
|
||||
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class LogDto {
|
||||
private Date date;
|
||||
private Level logLevel;
|
||||
private String title;
|
||||
private String message;
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package eu.nebulous.enums;
|
||||
public enum StatusEnum {
|
||||
|
||||
SUCCESS("Success"),
|
||||
FAILURE("Failure");
|
||||
|
||||
private final String description;
|
||||
|
||||
StatusEnum(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package eu.nebulous.exception;
|
||||
|
||||
import jakarta.ws.rs.WebApplicationException;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
import static jakarta.ws.rs.core.Response.Status.BAD_REQUEST;
|
||||
|
||||
public class BadRequestAlertException extends WebApplicationException {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public BadRequestAlertException(String message, String entityName, String errorKey) {
|
||||
super(Response.status(BAD_REQUEST).entity(message).header("message", "error." + errorKey).header("params", entityName).build());
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package eu.nebulous.exception;
|
||||
|
||||
import jakarta.ws.rs.WebApplicationException;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
public class InternalServerErrorException extends WebApplicationException {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public InternalServerErrorException() {
|
||||
this("HTTP 500 - Internal server error. Please contact site admin.");
|
||||
}
|
||||
|
||||
public InternalServerErrorException(String message) {
|
||||
super(Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity(message).build());
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package eu.nebulous.exception;
|
||||
|
||||
import jakarta.ws.rs.WebApplicationException;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
||||
import java.io.Serial;
|
||||
|
||||
import static jakarta.ws.rs.core.Response.Status.NOT_FOUND;
|
||||
|
||||
public class NotFoundAlertException extends WebApplicationException {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public NotFoundAlertException(String entityName) {
|
||||
super(Response.status(NOT_FOUND).entity("Entity " + entityName + "was not found")
|
||||
.header("message", "error." + "notfound")
|
||||
.header("params", entityName).build());
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package eu.nebulous.model;
|
||||
|
||||
import io.quarkus.hibernate.orm.panache.PanacheEntity;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Entity
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ApplicationMasterNode extends PanacheEntity {
|
||||
private String uuid;
|
||||
|
||||
@Column(name = "publicIp")
|
||||
private String publicIp;
|
||||
|
||||
@Column(name = "applicationUUID")
|
||||
private String applicationUUID;
|
||||
|
||||
@Column(name = "sshUsername")
|
||||
private String sshUsername;
|
||||
|
||||
@Column(length = 5000, name = "openSSLPrivateKey")
|
||||
private String openSSLPrivateKey;
|
||||
|
||||
@Column(length = 1000, name = "openSSLPublicKey")
|
||||
private String openSSLPublicKey;
|
||||
|
||||
@Column(name = "wireguardPrivateKey")
|
||||
private String wireguardPrivateKey;
|
||||
|
||||
@Column(name = "wireguardPublicKey")
|
||||
private String wireguardPublicKey;
|
||||
|
||||
@Column(name = "wireguardOverlaySubnet")
|
||||
private String wireguardOverlaySubnet;
|
||||
|
||||
@Column(name = "wireguardIp")
|
||||
private String wireguardIp;
|
||||
|
||||
@Column(name = "dateCreated")
|
||||
private Date dateCreated;
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
package eu.nebulous.model;
|
||||
|
||||
import io.quarkus.hibernate.orm.panache.PanacheEntity;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Entity
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class ApplicationWorkerNode extends PanacheEntity {
|
||||
private String uuid;
|
||||
|
||||
@Column(name = "publicIp")
|
||||
private String publicIp;
|
||||
|
||||
@Column(name = "sshUsername")
|
||||
private String sshUsername;
|
||||
|
||||
@Column(name = "wireguardPrivateKey")
|
||||
private String wireguardPrivateKey;
|
||||
|
||||
@Column(name = "wireguardPublicKey")
|
||||
private String wireguardPublicKey;
|
||||
|
||||
@Column(length = 5000, name = "openSSLPrivateKey")
|
||||
private String openSSLPrivateKey;
|
||||
|
||||
@Column(length = 1000, name = "openSSLPublicKey")
|
||||
private String openSSLPublicKey;
|
||||
|
||||
@Column(name = "dateCreated")
|
||||
private Date dateCreated;
|
||||
|
||||
@Column(name = "wireguardIp")
|
||||
private String wireguardIp;
|
||||
|
||||
@ManyToOne
|
||||
public ApplicationMasterNode applicationMasterNode;
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package eu.nebulous.repository;
|
||||
|
||||
import eu.nebulous.model.ApplicationMasterNode;
|
||||
import io.quarkus.hibernate.orm.panache.PanacheRepository;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
|
||||
@ApplicationScoped
|
||||
public class ApplicationMasterNodeRepository implements PanacheRepository<ApplicationMasterNode> {
|
||||
|
||||
public ApplicationMasterNode findByApplicationUUID(String applicationUUID){
|
||||
return find("applicationUUID", applicationUUID).firstResult();
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package eu.nebulous.repository;
|
||||
|
||||
import eu.nebulous.dto.ApplicationNodeDto;
|
||||
import eu.nebulous.model.ApplicationMasterNode;
|
||||
import eu.nebulous.model.ApplicationWorkerNode;
|
||||
import io.quarkus.hibernate.orm.panache.PanacheRepository;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ApplicationScoped
|
||||
public class ApplicationWorkerNodeRepository implements PanacheRepository<ApplicationWorkerNode> {
|
||||
public List<ApplicationWorkerNode> findWorkerNodesByMasterNode(ApplicationMasterNode masterNode){
|
||||
return find("applicationMasterNode", masterNode).list();
|
||||
}
|
||||
|
||||
public ApplicationWorkerNode findWorkerByPublicIp(ApplicationNodeDto applicationNodeDto){
|
||||
return find("publicIp", applicationNodeDto.publicIp()).firstResult();
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package eu.nebulous.resource;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import jakarta.ws.rs.Path;
|
||||
|
||||
@Singleton
|
||||
public class ApiResource {
|
||||
private final ApplicationNodeResource applicationNodeResource;
|
||||
|
||||
@Inject
|
||||
public ApiResource(ApplicationNodeResource applicationNodeResource) {
|
||||
this.applicationNodeResource = applicationNodeResource;
|
||||
}
|
||||
|
||||
@Path("/node")
|
||||
public ApplicationNodeResource getAuthResource() {
|
||||
return applicationNodeResource;
|
||||
}
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
package eu.nebulous.resource;
|
||||
|
||||
import eu.nebulous.dto.ApplicationNodeDto;
|
||||
import eu.nebulous.service.ApplicationNodeService;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Singleton;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.ws.rs.Consumes;
|
||||
import jakarta.ws.rs.DELETE;
|
||||
import jakarta.ws.rs.POST;
|
||||
import jakarta.ws.rs.Path;
|
||||
import jakarta.ws.rs.core.MediaType;
|
||||
import jakarta.ws.rs.core.Response;
|
||||
import org.eclipse.microprofile.openapi.annotations.Operation;
|
||||
import org.eclipse.microprofile.openapi.annotations.tags.Tag;
|
||||
|
||||
@Singleton
|
||||
public class ApplicationNodeResource {
|
||||
|
||||
@Inject
|
||||
ApplicationNodeService applicationNodeService;
|
||||
|
||||
@POST
|
||||
@Path("/create")
|
||||
@Tag(name = "Application Node")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Operation(summary = "Add Application Node to Application Cluster")
|
||||
public Response addApplicationNode(@Valid ApplicationNodeDto applicationNodeDto) {
|
||||
// Create Configuration for Application Node
|
||||
var logs = applicationNodeService.evaluateNodeCreation(applicationNodeDto);
|
||||
|
||||
return Response.ok(logs).build();
|
||||
}
|
||||
|
||||
@DELETE
|
||||
@Path("/delete")
|
||||
@Tag(name = "Application Node")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
@Operation(summary = "Delete Application Node From Application Cluster")
|
||||
public Response deleteApplicationNode(@Valid ApplicationNodeDto applicationNodeDto) {
|
||||
// Create Configuration for Application Node
|
||||
var logs = applicationNodeService.evaluateNodeDeletion(applicationNodeDto);
|
||||
|
||||
return Response.ok(logs).build();
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package eu.nebulous.resource;
|
||||
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.ws.rs.Path;
|
||||
|
||||
@Path("/")
|
||||
public class GatewayResource {
|
||||
private final ApiResource apiResource;
|
||||
|
||||
@Inject
|
||||
public GatewayResource(ApiResource apiResource) {
|
||||
this.apiResource = apiResource;
|
||||
}
|
||||
|
||||
@Path("/api/v1")
|
||||
public ApiResource getApiResource() {
|
||||
return apiResource;
|
||||
}
|
||||
}
|
@ -0,0 +1,289 @@
|
||||
package eu.nebulous.service;
|
||||
|
||||
import eu.nebulous.dto.ApplicationNodeDto;
|
||||
import eu.nebulous.dto.LogDto;
|
||||
import eu.nebulous.model.ApplicationMasterNode;
|
||||
import eu.nebulous.model.ApplicationWorkerNode;
|
||||
import eu.nebulous.repository.ApplicationMasterNodeRepository;
|
||||
import eu.nebulous.repository.ApplicationWorkerNodeRepository;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.transaction.Transactional;
|
||||
import org.eclipse.microprofile.config.inject.ConfigProperty;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
@ApplicationScoped
|
||||
public class ApplicationNodeService {
|
||||
@Inject
|
||||
ApplicationMasterNodeRepository applicationMasterNodeRepository;
|
||||
|
||||
@Inject
|
||||
ApplicationWorkerNodeRepository applicationWorkerNodeRepository;
|
||||
|
||||
@Inject
|
||||
WGKeyPairGeneratorService wgKeyPairGeneratorService;
|
||||
|
||||
@Inject
|
||||
RemoteCodeExecutionService remoteCodeExecutionService;
|
||||
|
||||
@Inject
|
||||
LogService logService;
|
||||
|
||||
@ConfigProperty(name = "WIREGUARD_ALLOWED_IPS")
|
||||
String wireguardAllowedIps;
|
||||
|
||||
@ConfigProperty(name = "WIREGUARD_DEFAULT_SERVER_IP")
|
||||
String wireguardDefaultServerIp;
|
||||
|
||||
@ConfigProperty(name = "WIREGUARD_NETWORK_PORTION")
|
||||
String wireguardNetworkPortion;
|
||||
|
||||
@ConfigProperty(name = "WG_BOOTSTRAP_AGENT_SCRIPTS_DIR")
|
||||
String wgBootstrapAgentScriptsDir;
|
||||
|
||||
private static final String ONM = "ONM";
|
||||
|
||||
private void persistApplicationMasterNode(List<LogDto> logList, ApplicationNodeDto applicationNodeDto, String openSSLPrivateKey, String openSSLPublicKey,
|
||||
String wireguardPrivateKey, String wireguardPublicKey) {
|
||||
try {
|
||||
var applicationMasterNode = new ApplicationMasterNode();
|
||||
applicationMasterNode.setUuid(UUID.randomUUID().toString());
|
||||
applicationMasterNode.setPublicIp(applicationNodeDto.publicIp());
|
||||
applicationMasterNode.setApplicationUUID(applicationNodeDto.applicationUUID());
|
||||
applicationMasterNode.setSshUsername(applicationNodeDto.sshUsername());
|
||||
applicationMasterNode.setDateCreated(new Date());
|
||||
applicationMasterNode.setOpenSSLPrivateKey(openSSLPrivateKey);
|
||||
applicationMasterNode.setOpenSSLPublicKey(openSSLPublicKey);
|
||||
applicationMasterNode.setWireguardPrivateKey(wireguardPrivateKey);
|
||||
applicationMasterNode.setWireguardPublicKey(wireguardPublicKey);
|
||||
applicationMasterNode.setWireguardOverlaySubnet(wireguardAllowedIps);
|
||||
applicationMasterNode.setWireguardIp(wireguardDefaultServerIp);
|
||||
|
||||
applicationMasterNodeRepository.persist(applicationMasterNode);
|
||||
|
||||
logService.log(logList, Level.INFO, ONM, "SUCCESS -> Application Node Master (" + applicationNodeDto.publicIp() +
|
||||
"," + applicationNodeDto.applicationUUID() + ") successfully persisted to DB!");
|
||||
} catch (Exception e) {
|
||||
logService.log(logList, Level.WARNING, ONM, "FAILURE -> The Application Node Master (" + applicationNodeDto.publicIp() +
|
||||
"," + applicationNodeDto.applicationUUID() + ") failed to be persisted to DB!");
|
||||
}
|
||||
}
|
||||
|
||||
private void persistApplicationWorkerNode(List<LogDto> logList, ApplicationNodeDto applicationNodeDto, ApplicationMasterNode masterNode,
|
||||
String wireguardPrivateKey, String wireguardPublicKey, String wireguardWorkerIp) {
|
||||
try {
|
||||
var applicationWorkerNode = new ApplicationWorkerNode();
|
||||
applicationWorkerNode.setUuid(UUID.randomUUID().toString());
|
||||
applicationWorkerNode.setSshUsername(applicationNodeDto.sshUsername());
|
||||
applicationWorkerNode.setPublicIp(applicationNodeDto.publicIp());
|
||||
applicationWorkerNode.setApplicationMasterNode(masterNode);
|
||||
applicationWorkerNode.setDateCreated(new Date());
|
||||
applicationWorkerNode.setWireguardPrivateKey(wireguardPrivateKey);
|
||||
applicationWorkerNode.setWireguardPublicKey(wireguardPublicKey);
|
||||
applicationWorkerNode.setWireguardIp(wireguardWorkerIp);
|
||||
applicationWorkerNode.setOpenSSLPrivateKey(applicationNodeDto.privateKeyBase64());
|
||||
applicationWorkerNode.setOpenSSLPublicKey(applicationNodeDto.publicKey());
|
||||
|
||||
applicationWorkerNodeRepository.persist(applicationWorkerNode);
|
||||
|
||||
logService.log(logList, Level.INFO, ONM, "SUCCESS -> Application Node Worker (" + applicationNodeDto.publicIp() +
|
||||
"," + applicationNodeDto.applicationUUID() + ") successfully persisted to DB!");
|
||||
} catch (Exception e) {
|
||||
logService.log(logList, Level.WARNING, ONM, "FAILURE -> The Application Node Worker (" + applicationNodeDto.publicIp() +
|
||||
"," + applicationNodeDto.applicationUUID() + ") failed to be persisted to DB!");
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public List<LogDto> evaluateNodeCreation(ApplicationNodeDto applicationNodeDto) {
|
||||
var logList = new ArrayList<LogDto>();
|
||||
|
||||
// Create WG Key Pair Function
|
||||
var wireguardKeyPair = wgKeyPairGeneratorService.createWireguardKeyPair(applicationNodeDto.publicIp());
|
||||
var wireguardPrivateKey = wireguardKeyPair.get("private");
|
||||
var wireguardPublicKey = wireguardKeyPair.get("public");
|
||||
|
||||
logService.log(logList, Level.INFO, ONM, "Created WG Key Pair for Application Node with Public IP: " + applicationNodeDto.publicIp());
|
||||
|
||||
if (applicationNodeDto.isMaster().equals(Boolean.TRUE)) {
|
||||
logService.log(logList, Level.INFO, ONM, "------------------------------------ wg-server-create.sh ------------------------------------");
|
||||
logService.log(logList, Level.INFO, ONM, "SCP FILE wg-server-create.sh to HOST: " + applicationNodeDto.publicIp());
|
||||
|
||||
remoteCodeExecutionService.scpFile(applicationNodeDto.sshUsername(),applicationNodeDto.publicIp(),
|
||||
22,applicationNodeDto.privateKeyBase64(),30L,
|
||||
wgBootstrapAgentScriptsDir + "/server/wg-server-create.sh",
|
||||
"wireguard",null);
|
||||
logService.log(logList, Level.INFO, ONM, "SCP COMPLETED! Ready to run wg-server-create.sh to HOST: " + applicationNodeDto.publicIp());
|
||||
|
||||
var permissionsCommand = "sudo chmod +x /home/" + applicationNodeDto.sshUsername() + "/wireguard/wg-server-create.sh";
|
||||
var executeCommand = "sudo /home/" + applicationNodeDto.sshUsername() + "/wireguard/wg-server-create.sh " + wireguardPrivateKey + " " +
|
||||
wireguardPublicKey + " " + " " + wireguardDefaultServerIp;
|
||||
remoteCodeExecutionService.runCommand(applicationNodeDto.sshUsername(),applicationNodeDto.privateKeyBase64(),applicationNodeDto.publicIp(),
|
||||
22,30L,
|
||||
permissionsCommand + ";" + executeCommand, null);
|
||||
logService.log(logList, Level.INFO, ONM, "COMMAND wg-server-create.sh for HOST " + applicationNodeDto.publicIp() + " COMPLETED!");
|
||||
logService.log(logList, Level.INFO, ONM, "------------------------------------ wg-server-create.sh ------------------------------------");
|
||||
|
||||
// Persist to DB
|
||||
persistApplicationMasterNode(logList, applicationNodeDto, applicationNodeDto.privateKeyBase64(), applicationNodeDto.publicKey(),
|
||||
wireguardPrivateKey, wireguardPublicKey);
|
||||
} else {
|
||||
String wireguardWorkerIp = wireguardNetworkPortion + "2";
|
||||
ApplicationMasterNode masterNode = applicationMasterNodeRepository.findByApplicationUUID(applicationNodeDto.applicationUUID());
|
||||
if (masterNode != null) {
|
||||
List<ApplicationWorkerNode> workerNodes = applicationWorkerNodeRepository.findWorkerNodesByMasterNode(masterNode);
|
||||
|
||||
logService.log(logList, Level.INFO, ONM, "Worker Nodes " + workerNodes.size());
|
||||
|
||||
if (!workerNodes.isEmpty()) wireguardWorkerIp = wireguardNetworkPortion + (workerNodes.size() + 2);
|
||||
var workerNodeClientName = "wg" + wireguardWorkerIp;
|
||||
|
||||
logService.log(logList, Level.INFO, ONM, "------------------------------------ wg-client-create_server.sh ------------------------------------");
|
||||
logService.log(logList, Level.INFO, ONM, "SCP FILE wg-client-create_server.sh to HOST: " + masterNode.getPublicIp());
|
||||
|
||||
remoteCodeExecutionService.scpFile(masterNode.getSshUsername(),masterNode.getPublicIp(),
|
||||
22, masterNode.getOpenSSLPrivateKey(), 30L,
|
||||
wgBootstrapAgentScriptsDir + "/client/wg-client-create_server.sh",
|
||||
"wireguard",null);
|
||||
logService.log(logList, Level.INFO, ONM, "SCP COMPLETED! Ready to run wg-client-create_server.sh to HOST: " + masterNode.getPublicIp());
|
||||
var permissionsCommandServer = "sudo chmod +x /home/" + masterNode.getSshUsername() + "/wireguard/wg-client-create_server.sh";
|
||||
var executeCommandServer = "sudo /home/" + masterNode.getSshUsername() + "/wireguard/wg-client-create_server.sh " + workerNodeClientName + " " + wireguardPrivateKey + " " +
|
||||
wireguardPublicKey + " " + masterNode.getSshUsername() + " " + masterNode.getWireguardPublicKey() + " " + masterNode.getPublicIp()+":"+"51820" + " " +
|
||||
wireguardWorkerIp + " " + wireguardAllowedIps;
|
||||
remoteCodeExecutionService.runCommand(masterNode.getSshUsername(),masterNode.getOpenSSLPrivateKey(),masterNode.getPublicIp(),
|
||||
22,30L,
|
||||
permissionsCommandServer + ";" + executeCommandServer, null);
|
||||
logService.log(logList, Level.INFO, ONM, "COMMAND wg-client-create_server.sh for HOST " + masterNode.getPublicIp() + " COMPLETED!");
|
||||
logService.log(logList, Level.INFO, ONM, "------------------------------------ wg-client-create_server.sh ------------------------------------");
|
||||
|
||||
logService.log(logList, Level.INFO, ONM, "------------------------------------ wg-client-create_client.sh ------------------------------------");
|
||||
remoteCodeExecutionService.scpFile(applicationNodeDto.sshUsername(),applicationNodeDto.publicIp(),
|
||||
22,applicationNodeDto.privateKeyBase64(),30L,
|
||||
wgBootstrapAgentScriptsDir + "/client/wg-client-create_client.sh",
|
||||
"wireguard",null);
|
||||
logService.log(logList, Level.INFO, ONM, "SCP COMPLETED! Ready to run wg-client-create_client.sh to HOST: " + applicationNodeDto.publicIp());
|
||||
var permissionsCommandClient = "sudo chmod +x /home/" + applicationNodeDto.sshUsername() + "/wireguard/wg-client-create_client.sh";
|
||||
var executeCommandClient = "sudo /home/" + applicationNodeDto.sshUsername() + "/wireguard/wg-client-create_client.sh " + applicationNodeDto.sshUsername() + " " +
|
||||
"\"" + masterNode.getOpenSSLPrivateKey() + "\" " + masterNode.getPublicIp() + " " + workerNodeClientName + " " + masterNode.getSshUsername();
|
||||
remoteCodeExecutionService.runCommand(applicationNodeDto.sshUsername(),applicationNodeDto.privateKeyBase64(),applicationNodeDto.publicIp(),
|
||||
22,30L, permissionsCommandClient + ";" + executeCommandClient, null);
|
||||
logService.log(logList, Level.INFO, ONM, "COMMAND wg-client-create_client.sh for HOST " + applicationNodeDto.publicIp() + " COMPLETED!");
|
||||
|
||||
logService.log(logList, Level.INFO, ONM, "------------------------------------ wg-client-create_client.sh ------------------------------------");
|
||||
|
||||
// Persist to DB
|
||||
persistApplicationWorkerNode(logList, applicationNodeDto, masterNode, wireguardPrivateKey, wireguardPublicKey, wireguardWorkerIp);
|
||||
}
|
||||
}
|
||||
|
||||
return logList;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public List<LogDto> evaluateNodeDeletion(ApplicationNodeDto applicationNodeDto) {
|
||||
var logList = new ArrayList<LogDto>();
|
||||
|
||||
if(applicationNodeDto.isMaster().equals(Boolean.TRUE)) {
|
||||
ApplicationMasterNode masterNode = applicationMasterNodeRepository.findByApplicationUUID(applicationNodeDto.applicationUUID());
|
||||
if (masterNode == null) {
|
||||
logService.log(logList, Level.INFO, ONM, "FAILURE -> Could not find an Application Master Node with applicationUUID " +
|
||||
applicationNodeDto.applicationUUID());
|
||||
|
||||
return logList;
|
||||
}
|
||||
|
||||
// Check If Master has workers below him
|
||||
List<ApplicationWorkerNode> workerNodes = applicationWorkerNodeRepository.findWorkerNodesByMasterNode(masterNode);
|
||||
if(workerNodes.isEmpty()) {
|
||||
logService.log(logList, Level.INFO, ONM, "------------------------------------ wg-server-delete.sh ------------------------------------");
|
||||
logService.log(logList, Level.INFO, ONM, "SCP FILE wg-server-delete.sh to HOST: " + applicationNodeDto.publicIp());
|
||||
|
||||
remoteCodeExecutionService.scpFile(applicationNodeDto.sshUsername(),applicationNodeDto.publicIp(),
|
||||
22,applicationNodeDto.privateKeyBase64(),30L,
|
||||
wgBootstrapAgentScriptsDir + "/server/wg-server-delete.sh",
|
||||
"wireguard",null);
|
||||
logService.log(logList, Level.INFO, ONM, "SCP COMPLETED! Ready to run wg-server-delete.sh to HOST: " + applicationNodeDto.publicIp());
|
||||
var permissionsCommand = "sudo chmod +x /home/" + applicationNodeDto.sshUsername() + "/wireguard/wg-server-delete.sh";
|
||||
var executeCommand = "sudo /home/" + applicationNodeDto.sshUsername() + "/wireguard/wg-server-delete.sh " + applicationNodeDto.sshUsername();
|
||||
remoteCodeExecutionService.runCommand(applicationNodeDto.sshUsername(),applicationNodeDto.privateKeyBase64(),applicationNodeDto.publicIp(),
|
||||
22,30L,
|
||||
permissionsCommand + ";" + executeCommand, null);
|
||||
logService.log(logList, Level.INFO, ONM, "COMMAND wg-server-delete.sh for HOST " + applicationNodeDto.publicIp() + " COMPLETED!");
|
||||
logService.log(logList, Level.INFO, ONM, "------------------------------------ wg-server-delete.sh ------------------------------------");
|
||||
deleteApplicationMasterNode(logList, masterNode);
|
||||
} else {
|
||||
logService.log(logList, Level.INFO, ONM, "The Application Master Node with PublicIP " + applicationNodeDto.publicIp() +
|
||||
" and applicationUUID " + applicationNodeDto.applicationUUID() + " has " + workerNodes.size() + " worker nodes.");
|
||||
//TODO: What happens when a request for deletion on a WG Server appears and it has workers running??
|
||||
}
|
||||
} else {
|
||||
var workerNode = applicationWorkerNodeRepository.findWorkerByPublicIp(applicationNodeDto);
|
||||
if(workerNode == null) {
|
||||
logService.log(logList, Level.INFO, ONM, "FAILURE -> Could not find an Application Worker Node with applicationUUID " + applicationNodeDto.publicIp());
|
||||
return logList;
|
||||
}
|
||||
|
||||
logService.log(logList, Level.INFO, ONM, "------------------------------------ wg-client-delete_client.sh ------------------------------------");
|
||||
logService.log(logList, Level.INFO, ONM, "SCP FILE wg-client-delete_client.sh to HOST: " + applicationNodeDto.publicIp());
|
||||
remoteCodeExecutionService.scpFile(applicationNodeDto.sshUsername(),applicationNodeDto.publicIp(),
|
||||
22,applicationNodeDto.privateKeyBase64(),30L,
|
||||
wgBootstrapAgentScriptsDir + "/client/wg-client-delete_client.sh",
|
||||
"wireguard",null);
|
||||
logService.log(logList, Level.INFO, ONM, "SCP COMPLETED! Ready to run wg-client-delete_client_script.sh to HOST: " + applicationNodeDto.publicIp());
|
||||
var permissionsCommandClient = "sudo chmod +x /home/" + applicationNodeDto.sshUsername() + "/wireguard/wg-client-delete_client.sh";
|
||||
var executeCommandClient = "sudo /home/" + applicationNodeDto.sshUsername() + "/wireguard/wg-client-delete_client.sh " + applicationNodeDto.sshUsername() +
|
||||
" " + "wg" + workerNode.getWireguardIp();
|
||||
remoteCodeExecutionService.runCommand(applicationNodeDto.sshUsername(),applicationNodeDto.privateKeyBase64(),applicationNodeDto.publicIp(),
|
||||
22,30L,
|
||||
permissionsCommandClient + ";" + executeCommandClient, null);
|
||||
logService.log(logList, Level.INFO, ONM, "COMMAND wg-client-delete_client.sh for HOST " + applicationNodeDto.publicIp() + " COMPLETED!");
|
||||
logService.log(logList, Level.INFO, ONM, "------------------------------------ wg-client-delete_client.sh ------------------------------------");
|
||||
|
||||
logService.log(logList, Level.INFO, ONM, "------------------------------------ wg-client-delete_server.sh ------------------------------------");
|
||||
logService.log(logList, Level.INFO, ONM, "SCP FILE wg-client-delete_server.sh to HOST: " + workerNode.getApplicationMasterNode().getPublicIp());
|
||||
remoteCodeExecutionService.scpFile(workerNode.getApplicationMasterNode().getSshUsername(),workerNode.getApplicationMasterNode().getPublicIp(),
|
||||
22,workerNode.getApplicationMasterNode().getOpenSSLPrivateKey(),30L,
|
||||
wgBootstrapAgentScriptsDir + "/client/wg-client-delete_server.sh",
|
||||
"wireguard",null);
|
||||
logService.log(logList, Level.INFO, ONM, "SCP COMPLETED! Ready to run wg-client-delete_server.sh to HOST: " + workerNode.getApplicationMasterNode().getPublicIp());
|
||||
var permissionsCommandServer = "sudo chmod +x /home/" + workerNode.getApplicationMasterNode().getSshUsername() + "/wireguard/wg-client-delete_server.sh";
|
||||
var executeCommandServer = "sudo /home/" + workerNode.getApplicationMasterNode().getSshUsername() + "/wireguard/wg-client-delete_server.sh " + "wg" + workerNode.getWireguardIp() +
|
||||
" " + workerNode.getWireguardPublicKey() + " " + applicationNodeDto.sshUsername();
|
||||
remoteCodeExecutionService.runCommand(workerNode.getApplicationMasterNode().getSshUsername(),workerNode.getApplicationMasterNode().getOpenSSLPrivateKey(),
|
||||
workerNode.getApplicationMasterNode().getPublicIp(),22,30L, permissionsCommandServer + ";" + executeCommandServer, null);
|
||||
logService.log(logList, Level.INFO, ONM, "COMMAND wg-client-delete_server.sh for HOST " + applicationNodeDto.publicIp() + " COMPLETED!");
|
||||
logService.log(logList, Level.INFO, ONM, "------------------------------------ wg-client-delete_server.sh ------------------------------------");
|
||||
|
||||
deleteApplicationWorkerNode(logList, workerNode);
|
||||
}
|
||||
|
||||
return logList;
|
||||
}
|
||||
|
||||
private void deleteApplicationMasterNode(List<LogDto> logList, ApplicationMasterNode masterNode) {
|
||||
try {
|
||||
applicationMasterNodeRepository.delete(masterNode);
|
||||
logService.log(logList, Level.INFO, ONM, "SUCCESS -> Application Node Master (" + masterNode.getPublicIp() + ", " +
|
||||
masterNode.getApplicationUUID() + ") successfully deleted from the DB!");
|
||||
} catch (Exception e) {
|
||||
logService.log(logList, Level.WARNING, ONM, "FAILURE -> The Application Node Master (" + masterNode.getPublicIp() + ", " +
|
||||
masterNode.getApplicationUUID() + ") failed to be deleted from the DB!");
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteApplicationWorkerNode(List<LogDto> logList, ApplicationWorkerNode workerNode) {
|
||||
try {
|
||||
applicationWorkerNodeRepository.delete(workerNode);
|
||||
logService.log(logList, Level.INFO, ONM, "SUCCESS -> Application Node Worker (" + workerNode.getPublicIp() + ", " +
|
||||
workerNode.getApplicationMasterNode().getApplicationUUID() + ") successfully deleted from the DB!");
|
||||
} catch (Exception e) {
|
||||
logService.log(logList, Level.WARNING, ONM, "FAILURE -> The Application Node Worker (" + workerNode.getPublicIp() + ", " +
|
||||
workerNode.getApplicationMasterNode().getApplicationUUID() + ") failed to be deleted from the DB!");
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package eu.nebulous.service;
|
||||
|
||||
import eu.nebulous.dto.LogDto;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@ApplicationScoped
|
||||
public class LogService {
|
||||
private static final Logger logger = Logger.getLogger(LogService.class.getName());
|
||||
|
||||
public void log(List<LogDto> logList, Level logLevel, String title, String message) {
|
||||
var date = new Date();
|
||||
|
||||
// Add log events to logList
|
||||
logList.add(new LogDto(date, logLevel, title, message));
|
||||
|
||||
// Log events
|
||||
logger.log(logLevel, "{0}: {1}", new Object[]{date, message});
|
||||
}
|
||||
}
|
@ -0,0 +1,135 @@
|
||||
package eu.nebulous.service;
|
||||
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import org.apache.sshd.client.SshClient;
|
||||
import org.apache.sshd.client.channel.ClientChannelEvent;
|
||||
import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
|
||||
import org.apache.sshd.scp.client.ScpClientCreator;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Base64;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.EnumSet;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@ApplicationScoped
|
||||
public class RemoteCodeExecutionService {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(RemoteCodeExecutionService.class.getName());
|
||||
|
||||
public void runCommand(String username, String privateKeyBase64, String host, int port,
|
||||
long defaultTimeoutSeconds, String command, String password) {
|
||||
|
||||
File privateKeyFile = createTmpFile(privateKeyBase64);
|
||||
|
||||
var client = SshClient.setUpDefaultClient();
|
||||
client.start();
|
||||
|
||||
try (var session = client.connect(username, host, port)
|
||||
.verify(defaultTimeoutSeconds, TimeUnit.SECONDS).getSession()) {
|
||||
|
||||
if (password != null) {
|
||||
session.addPasswordIdentity(password);
|
||||
} else {
|
||||
var fileKeyPairProvider = new FileKeyPairProvider();
|
||||
fileKeyPairProvider.setPaths(Collections.singleton(Paths.get(privateKeyFile.getAbsolutePath())));
|
||||
var key = fileKeyPairProvider.loadKeys(null).iterator().next();
|
||||
|
||||
session.addPublicKeyIdentity(key);
|
||||
}
|
||||
|
||||
session.auth().verify(defaultTimeoutSeconds, TimeUnit.SECONDS); // Timeout
|
||||
|
||||
try (var responseStream = new ByteArrayOutputStream();
|
||||
var channel = session.createExecChannel(command)) {
|
||||
channel.setOut(responseStream);
|
||||
|
||||
try {
|
||||
channel.open().verify(defaultTimeoutSeconds, TimeUnit.SECONDS);
|
||||
try (var pipedIn = channel.getInvertedIn()) {
|
||||
pipedIn.write(command.getBytes());
|
||||
pipedIn.flush();
|
||||
}
|
||||
|
||||
channel.waitFor(EnumSet.of(ClientChannelEvent.CLOSED),
|
||||
TimeUnit.SECONDS.toMillis(defaultTimeoutSeconds));
|
||||
var responseString = responseStream.toString();
|
||||
|
||||
logger.log(Level.INFO, "Response: {0}", new Object[]{responseString});
|
||||
} finally {
|
||||
channel.close(false);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
client.stop();
|
||||
privateKeyFile.delete();
|
||||
}
|
||||
}
|
||||
|
||||
public void scpFile(String username, String host, int port, String privateKeyBase64, long defaultTimeoutSeconds,
|
||||
String localFilePath, String remoteTargetFolder, String password) {
|
||||
|
||||
File privateKeyFile = createTmpFile(privateKeyBase64);
|
||||
|
||||
var client = SshClient.setUpDefaultClient();
|
||||
client.start();
|
||||
|
||||
try (var session = client.connect(username, host, port)
|
||||
.verify(defaultTimeoutSeconds, TimeUnit.SECONDS).getSession()) {
|
||||
|
||||
if (password != null) {
|
||||
session.addPasswordIdentity(password);
|
||||
} else {
|
||||
var fileKeyPairProvider = new FileKeyPairProvider();
|
||||
fileKeyPairProvider.setPaths(Collections.singleton(Paths.get(privateKeyFile.getAbsolutePath())));
|
||||
var key = fileKeyPairProvider.loadKeys(null).iterator().next();
|
||||
|
||||
session.addPublicKeyIdentity(key);
|
||||
}
|
||||
|
||||
session.auth().verify(defaultTimeoutSeconds, TimeUnit.SECONDS);
|
||||
|
||||
var creator = ScpClientCreator.instance();
|
||||
var scpClient = creator.createScpClient(session);
|
||||
|
||||
// To SCP a file to the remote system
|
||||
scpClient.upload(localFilePath, "/home/" + username + "/" + remoteTargetFolder);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
client.stop();
|
||||
privateKeyFile.delete();
|
||||
}
|
||||
}
|
||||
|
||||
private File createTmpFile(String privateKey) {
|
||||
try {
|
||||
// Create temp file.
|
||||
var temp = File.createTempFile("originPK" + UUID.randomUUID(), ".txt");
|
||||
|
||||
// Write to temp file
|
||||
var out = new BufferedWriter(new FileWriter(temp));
|
||||
var decodedString = new String(Base64.getMimeDecoder().decode(privateKey.getBytes()), StandardCharsets.UTF_8);
|
||||
|
||||
out.write(decodedString);
|
||||
out.close();
|
||||
|
||||
return temp;
|
||||
} catch (IOException e) {
|
||||
logger.log(Level.SEVERE, "{0} -> Problem creating tmp file for Origin Private Key File", new Object[]{new Date()});
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package eu.nebulous.service;
|
||||
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.StringWriter;
|
||||
import java.security.Key;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.PublicKey;
|
||||
import java.security.Security;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.util.Base64;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@ApplicationScoped
|
||||
public class SSHKeyPairGeneratorService {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(SSHKeyPairGeneratorService.class.getName());
|
||||
|
||||
public Map<String, String> createOpenSSL(String publicIp) {
|
||||
var openSSLKeyPairHashMap = new HashMap<String, String>();
|
||||
try {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
// Generate the RSA Key Pair
|
||||
var keyGen = KeyPairGenerator.getInstance("RSA");
|
||||
keyGen.initialize(2048);
|
||||
var pair = keyGen.generateKeyPair();
|
||||
|
||||
var privateKeyString = convertKeyToString(pair.getPrivate());
|
||||
var privateKeyBase64String = Base64.getEncoder().encodeToString(privateKeyString.getBytes());
|
||||
|
||||
openSSLKeyPairHashMap.put("private", privateKeyBase64String);
|
||||
// Output private key
|
||||
logger.log(Level.INFO, "{0}: SUCCESS -> OpenSSL Private Key Base64 for {1} just created: {2}",
|
||||
new Object[]{new Date(), publicIp, privateKeyBase64String});
|
||||
|
||||
// Convert public key to SSH format
|
||||
var sshPublicKey = convertPublicKeyToSSHFormat(pair.getPublic());
|
||||
openSSLKeyPairHashMap.put("public", sshPublicKey + " wg-public-key");
|
||||
|
||||
logger.log(Level.INFO, "{0}: SUCCESS -> OpenSSL Public Key (SSH Format) for {1} just created: {2} wg-public-key",
|
||||
new Object[]{new Date(), publicIp, sshPublicKey});
|
||||
|
||||
} catch (Exception e) {
|
||||
logger.log(Level.WARNING, "{0}: FAILURE -> Error generating OpenSSL Key Pair for {1}",
|
||||
new Object[]{new Date(), publicIp});
|
||||
}
|
||||
|
||||
return openSSLKeyPairHashMap;
|
||||
}
|
||||
|
||||
private static String convertKeyToString(Key key) throws IOException {
|
||||
var writer = new StringWriter();
|
||||
try (var pemWriter = new JcaPEMWriter(writer)) {
|
||||
pemWriter.writeObject(key);
|
||||
}
|
||||
return writer.toString();
|
||||
}
|
||||
|
||||
private static String convertPublicKeyToSSHFormat(PublicKey publicKey) throws IOException {
|
||||
var rsaPublicKey = (RSAPublicKey) publicKey;
|
||||
var byteOs = new ByteArrayOutputStream();
|
||||
var dos = new DataOutputStream(byteOs);
|
||||
dos.writeInt("ssh-rsa".getBytes().length);
|
||||
dos.write("ssh-rsa".getBytes());
|
||||
dos.writeInt(rsaPublicKey.getPublicExponent().toByteArray().length);
|
||||
dos.write(rsaPublicKey.getPublicExponent().toByteArray());
|
||||
dos.writeInt(rsaPublicKey.getModulus().toByteArray().length);
|
||||
dos.write(rsaPublicKey.getModulus().toByteArray());
|
||||
var publicKeyEncoded = new String(Base64.getEncoder().encode(byteOs.toByteArray()));
|
||||
return "ssh-rsa " + publicKeyEncoded;
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package eu.nebulous.service;
|
||||
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
import org.bouncycastle.crypto.generators.X25519KeyPairGenerator;
|
||||
import org.bouncycastle.crypto.params.X25519KeyGenerationParameters;
|
||||
import org.bouncycastle.crypto.params.X25519PrivateKeyParameters;
|
||||
import org.bouncycastle.crypto.params.X25519PublicKeyParameters;
|
||||
import org.bouncycastle.util.encoders.Base64;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@ApplicationScoped
|
||||
public class WGKeyPairGeneratorService {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(WGKeyPairGeneratorService.class.getName());
|
||||
|
||||
public Map<String, String> createWireguardKeyPair(String publicIp) {
|
||||
var wireguardKeyPairHashMap = new HashMap<String, String>();
|
||||
// Initialize key generator
|
||||
var keyPairGenerator = new X25519KeyPairGenerator();
|
||||
keyPairGenerator.init(new X25519KeyGenerationParameters(new SecureRandom()));
|
||||
|
||||
// Generate key pair
|
||||
var keyPair = keyPairGenerator.generateKeyPair();
|
||||
|
||||
// Extract private and public keys
|
||||
var privateKey = (X25519PrivateKeyParameters) keyPair.getPrivate();
|
||||
var publicKey = (X25519PublicKeyParameters) keyPair.getPublic();
|
||||
|
||||
// Encode keys to Base64
|
||||
var privateKeyBase64 = Base64.toBase64String(privateKey.getEncoded());
|
||||
var publicKeyBase64 = Base64.toBase64String(publicKey.getEncoded());
|
||||
|
||||
wireguardKeyPairHashMap.put("private", privateKeyBase64);
|
||||
wireguardKeyPairHashMap.put("public", publicKeyBase64);
|
||||
|
||||
// Output the keys
|
||||
logger.log(Level.INFO, "{0}: SUCCESS -> Private Key for {1} just created: {2}",
|
||||
new Object[]{new Date(), publicIp, privateKeyBase64});
|
||||
logger.log(Level.INFO, "{0}: SUCCESS -> Public Key for {1} just created: {2}",
|
||||
new Object[]{new Date(), publicIp, publicKeyBase64});
|
||||
|
||||
return wireguardKeyPairHashMap;
|
||||
}
|
||||
}
|
26
network-manager/src/main/java/eu/nebulous/util/Util.java
Normal file
26
network-manager/src/main/java/eu/nebulous/util/Util.java
Normal file
@ -0,0 +1,26 @@
|
||||
package eu.nebulous.util;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import eu.nebulous.exception.NotFoundAlertException;
|
||||
import jakarta.enterprise.context.ApplicationScoped;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
@ApplicationScoped
|
||||
public class Util {
|
||||
public String exceptionResponse(Exception e){
|
||||
var errors = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(errors));
|
||||
return errors.toString();
|
||||
}
|
||||
|
||||
public String toString(Object obj) {
|
||||
try {
|
||||
return new ObjectMapper().writeValueAsString(obj);
|
||||
} catch (JsonProcessingException e) {
|
||||
throw new NotFoundAlertException(e.toString());
|
||||
}
|
||||
}
|
||||
}
|
39
network-manager/src/main/resources/application.yml
Normal file
39
network-manager/src/main/resources/application.yml
Normal file
@ -0,0 +1,39 @@
|
||||
mp:
|
||||
openapi:
|
||||
extensions:
|
||||
smallrye:
|
||||
info:
|
||||
title: 'API Specification'
|
||||
version: '1.0'
|
||||
description: 'Exposed REST Services in order to talk with the world'
|
||||
name: 'NebulOus Overlay Network Manager'
|
||||
|
||||
quarkus:
|
||||
datasource:
|
||||
db-kind: postgresql
|
||||
jdbc:
|
||||
url: ${POSTGRES_CONNECTION_STRING}
|
||||
username: ${POSTGRES_USER}
|
||||
password: ${POSTGRES_PASSWORD}
|
||||
|
||||
hibernate-orm:
|
||||
database:
|
||||
generation: update
|
||||
|
||||
smallrye-openapi:
|
||||
path: '/api/openapi'
|
||||
security-scheme: 'jwt'
|
||||
security-scheme-name: 'Swagger Authentication'
|
||||
security-scheme-description: 'User Authentication through Keycloak'
|
||||
|
||||
swagger-ui:
|
||||
title: 'API Documentation'
|
||||
theme: material
|
||||
footer: © 2024
|
||||
always-include: true
|
||||
path: '/api/swagger'
|
||||
|
||||
"%prod":
|
||||
quarkus:
|
||||
package:
|
||||
type: uber-jar
|
@ -0,0 +1,7 @@
|
||||
# Create Client
|
||||
|
||||
* Server Name: wg0
|
||||
* Client Name: $CLIENT_NAME
|
||||
* Wireguard Client Directory: /etc/wireguard/clients/$CLIENT_NAME
|
||||
* Client Conf: /etc/wireguard/clients/$CLIENT_NAME/$CLIENT_NAME.conf
|
||||
* Server Conf: /etc/wireguard/wg0.conf
|
@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check if sufficient arguments are provided
|
||||
if [ "$#" -ne 5 ]; then
|
||||
echo "Usage: $0 <WORKER_SSH_USERNAME> <OPENSSL_PRIVATE_KEY> <SERVER_IP> <CLIENT_NAME> <MASTER_SSH_USERNAME>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Script parameter
|
||||
WORKER_SSH_USERNAME="$1"
|
||||
OPENSSL_PRIVATE_KEY="$2"
|
||||
SERVER_IP="$3"
|
||||
CLIENT_NAME="$4"
|
||||
MASTER_SSH_USERNAME="$5"
|
||||
|
||||
# Update Package Repository. Upgrade and Autoremove Packages
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get -y update
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get -y upgrade
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get -y autoremove
|
||||
|
||||
|
||||
# Step 1: Install WireGuard
|
||||
if ! command -v wg > /dev/null; then
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt install -y wireguard
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt install -y resolvconf
|
||||
fi
|
||||
|
||||
# Step 2: Base64 Decode the OpenSSH Private Key file
|
||||
echo $OPENSSL_PRIVATE_KEY | base64 -d --ignore-garbage > /home/$WORKER_SSH_USERNAME/wg-private-key.key
|
||||
chmod 400 /home/$WORKER_SSH_USERNAME/wg-private-key.key
|
||||
|
||||
# Step 3: Secure Copy to WG Server to get your conf file
|
||||
scp -o StrictHostKeyChecking=no -i /home/$WORKER_SSH_USERNAME/wg-private-key.key $MASTER_SSH_USERNAME@$SERVER_IP:/home/$MASTER_SSH_USERNAME/wireguard/clients/$CLIENT_NAME/$CLIENT_NAME.conf /home/$WORKER_SSH_USERNAME/wireguard
|
||||
sudo cp /home/$WORKER_SSH_USERNAME/wireguard/$CLIENT_NAME.conf /etc/wireguard/$CLIENT_NAME.conf
|
||||
|
||||
# Step 4: Enable and Start WireGuard Client Interface
|
||||
sudo systemctl enable wg-quick@$CLIENT_NAME
|
||||
sudo systemctl start wg-quick@$CLIENT_NAME
|
||||
|
||||
echo "WireGuard client configured and started for $CLIENT_NAME"
|
@ -0,0 +1,64 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check if sufficient arguments are provided
|
||||
if [ "$#" -ne 8 ]; then
|
||||
echo "Usage: $0 <WG_CLIENT_NAME> <WG_Client_Private_Key> <WG_Client_Public_Key> <SSH_Username> <Server_PublicKey> <Server_IP:Port> <Client_VPN_IP> <AllowedIPs>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Script parameters
|
||||
SERVER_NAME="wg0"
|
||||
CLIENT_NAME="$1"
|
||||
WG_CLIENT_PRIVATE_KEY="$2"
|
||||
WG_CLIENT_PUBLIC_KEY="$3"
|
||||
SSH_USERNAME="$4"
|
||||
SERVER_PUBLIC_KEY="$5"
|
||||
SERVER_IP_PORT="$6"
|
||||
CLIENT_VPN_IP="$7"
|
||||
ALLOWED_IPS="$8"
|
||||
WG_DIR="/etc/wireguard/clients/$CLIENT_NAME"
|
||||
CLIENT_CONF="$WG_DIR/${CLIENT_NAME}.conf"
|
||||
SERVER_CONF="/etc/wireguard/${SERVER_NAME}.conf"
|
||||
|
||||
# Step 1: Install WireGuard (if not already installed)
|
||||
if ! command -v wg > /dev/null; then
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt install -y wireguard
|
||||
fi
|
||||
|
||||
# Step 2: Create client directory
|
||||
sudo mkdir -p "$WG_DIR"
|
||||
mkdir -p /home/$SSH_USERNAME/wireguard/clients/$CLIENT_NAME
|
||||
|
||||
# Step 3: Generate Client Keys
|
||||
sudo echo $WG_CLIENT_PRIVATE_KEY > "$WG_DIR/${CLIENT_NAME}_privatekey"
|
||||
sudo echo $WG_CLIENT_PUBLIC_KEY > "$WG_DIR/${CLIENT_NAME}_publickey"
|
||||
client_private_key=$(sudo cat "$WG_DIR/${CLIENT_NAME}_privatekey")
|
||||
client_public_key=$(sudo cat "$WG_DIR/${CLIENT_NAME}_publickey")
|
||||
|
||||
# Step 4: Configure WireGuard Client
|
||||
sudo bash -c "cat > $CLIENT_CONF <<EOF
|
||||
[Interface]
|
||||
PrivateKey = $client_private_key
|
||||
Address = $CLIENT_VPN_IP
|
||||
DNS = 1.1.1.1 # Change this if you have a preferred DNS server
|
||||
|
||||
[Peer]
|
||||
PublicKey = $SERVER_PUBLIC_KEY
|
||||
Endpoint = $SERVER_IP_PORT
|
||||
AllowedIPs = $ALLOWED_IPS
|
||||
PersistentKeepalive = 25
|
||||
EOF"
|
||||
|
||||
# Step 5: Update Server Configuration
|
||||
sudo cp $CLIENT_CONF /home/$SSH_USERNAME/wireguard/clients/$CLIENT_NAME/$CLIENT_NAME.conf
|
||||
|
||||
sudo systemctl stop wg-quick@${SERVER_NAME}
|
||||
|
||||
sudo bash -c "echo -e '\n[Peer]\nPublicKey = $client_public_key\nAllowedIPs = $CLIENT_VPN_IP' >> $SERVER_CONF"
|
||||
|
||||
# Step 6: Restart WireGuard to apply changes
|
||||
sudo systemctl restart wg-quick@${SERVER_NAME}
|
||||
|
||||
echo "Client configuration for $CLIENT_NAME created and added to server config."
|
||||
echo "Transfer the client configuration to your client machine. Example command:"
|
||||
echo "scp $CLIENT_CONF user@client-ip:/path/to/destination"
|
@ -0,0 +1,35 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check if sufficient arguments are provided
|
||||
if [ "$#" -ne 2 ]; then
|
||||
echo "Usage: $0 <SSH_USERNAME> <WG_INTERFACE_NAME>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Script parameter
|
||||
SSH_USERNAME="$1"
|
||||
WG_INTERFACE_NAME="$2"
|
||||
|
||||
# Step 1: Stop and Disable WireGuard Interface
|
||||
sudo systemctl stop wg-quick@$WG_INTERFACE_NAME
|
||||
sudo systemctl disable wg-quick@$WG_INTERFACE_NAME
|
||||
|
||||
# Step 2: Remove Wireguard packages
|
||||
sudo apt-get remove --purge -y wireguard
|
||||
sudo apt-get autoremove -y
|
||||
|
||||
echo "Wireguard packages have been removed."
|
||||
|
||||
# Step 3: Remove Wireguard related directories
|
||||
sudo rm -rf /etc/wireguard
|
||||
sudo rm -rf /home/$SSH_USERNAME/wireguard
|
||||
|
||||
echo "WireGuard configuration files removed."
|
||||
|
||||
# Step 4: Remove WG OpenSSL Private Key
|
||||
sudo rm -rf /home/$SSH_USERNAME/wg-private-key.key
|
||||
|
||||
# Step 5: Remove OpenSSL Public Key
|
||||
sed -i '/wireguard-pub/d' /home/$SSH_USERNAME/.ssh/authorized_keys
|
||||
|
||||
echo "WireGuard client $WG_INTERFACE_NAME has been stopped and disabled."
|
@ -0,0 +1,25 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check if the client public key is provided
|
||||
if [ "$#" -ne 3 ]; then
|
||||
echo "Usage: $0 <Client_Name> <Client_PublicKey> <SSH_Username>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Script parameter
|
||||
SERVER_NAME="wg0"
|
||||
CLIENT_NAME="$1"
|
||||
CLIENT_PUBLIC_KEY="$2"
|
||||
SSH_USERNAME="$3"
|
||||
|
||||
# Step 1: Remove the client configuration from the server
|
||||
sudo wg set ${SERVER_NAME} peer ${CLIENT_PUBLIC_KEY} remove
|
||||
|
||||
# Step 2: Remove the client config file
|
||||
sudo rm -rf /etc/wireguard/clients/${CLIENT_NAME}
|
||||
sudo rm -rf /home/$SSH_USERNAME/wireguard/clients/${CLIENT_NAME}
|
||||
|
||||
# Step 3: Restart WireGuard to apply changes
|
||||
sudo systemctl restart wg-quick@${SERVER_NAME}
|
||||
|
||||
echo "Client with public key $CLIENT_PUBLIC_KEY has been removed from the server configuration."
|
60
network-manager/wg-bootstrap-agent-scripts/nm-bootstrap-script.sh
Executable file
60
network-manager/wg-bootstrap-agent-scripts/nm-bootstrap-script.sh
Executable file
@ -0,0 +1,60 @@
|
||||
#!/bin/bash
|
||||
|
||||
# "CREATE" or "DELETE" Overlay Node
|
||||
ACTION=$1
|
||||
# Define Application Node Type ("MASTER","WORKER")
|
||||
NODE_TYPE=$2
|
||||
# Application UUID
|
||||
APPLICATION_UUID=$3
|
||||
# Overlay Network Manager Public IP
|
||||
ONM_IP=$4
|
||||
|
||||
# Get the public IP
|
||||
public_ip=$(curl -s http://httpbin.org/ip | grep -oP '(?<="origin": ")[^"]*')
|
||||
|
||||
# Get the Application UUID from the environment variable
|
||||
application_uuid=$APPLICATION_UUID
|
||||
|
||||
# Get the currently logged in user (assuming single user login)
|
||||
logged_in_user=$(whoami)
|
||||
|
||||
# Get the isMaster variable from the environment variable
|
||||
if [ "$NODE_TYPE" == "MASTER" ]; then
|
||||
IS_MASTER="true";
|
||||
elif [ "$NODE_TYPE" == "WORKER" ]; then
|
||||
IS_MASTER="false"
|
||||
fi
|
||||
|
||||
# Check if string1 is equal to string2
|
||||
if [ "$ACTION" == "CREATE" ]; then
|
||||
echo "Creating OpenSSH Public/Private Key Pair..."
|
||||
# Create Wireguard Folder to accept the wireguard scripts
|
||||
mkdir -p /home/${logged_in_user}/wireguard
|
||||
|
||||
# Create OpenSSH Public/Private Key files
|
||||
ssh-keygen -C wireguard-pub -t rsa -b 4096 -f /home/${logged_in_user}/wireguard/wireguard -N ""
|
||||
|
||||
cat /home/${logged_in_user}/wireguard/wireguard.pub >> /home/${logged_in_user}/.ssh/authorized_keys
|
||||
fi
|
||||
|
||||
PRIVATE_KEY_FILE=$(cat /home/${logged_in_user}/wireguard/wireguard | base64 | tr '\n' ' ')
|
||||
|
||||
PAYLOAD=$(cat <<EOF
|
||||
{
|
||||
"privateKeyBase64": "${PRIVATE_KEY_FILE}",
|
||||
"publicKey": "$(</home/${logged_in_user}/wireguard/wireguard.pub)",
|
||||
"publicIp": "${public_ip}",
|
||||
"applicationUUID": "${application_uuid}",
|
||||
"sshUsername": "${logged_in_user}",
|
||||
"isMaster": "$IS_MASTER"
|
||||
}
|
||||
EOF
|
||||
)
|
||||
|
||||
echo "$PAYLOAD"
|
||||
|
||||
if [ "$ACTION" == "CREATE" ]; then
|
||||
curl -v -X POST -H "Content-Type: application/json" -d "$PAYLOAD" http://${ONM_IP}:8082/api/v1/node/create
|
||||
elif [ "$ACTION" == "DELETE" ]; then
|
||||
curl -v -X DELETE -H "Content-Type: application/json" -d "$PAYLOAD" http://${ONM_IP}:8082/api/v1/node/delete
|
||||
fi
|
@ -0,0 +1,7 @@
|
||||
# Create WG Server
|
||||
|
||||
* Interface Name: wg0
|
||||
* Listen Port: 51820
|
||||
* WG Server IP: 192.168.55.1
|
||||
* WG Server Keys Directory: /etc/wireguard/server_keys
|
||||
* WG Server Conf file: /etc/wireguard/wg0.conf
|
@ -0,0 +1,54 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Check if sufficient arguments are provided
|
||||
if [ "$#" -ne 3 ]; then
|
||||
echo "Usage: $0 <WG_Server_Private_Key> <WG_Server_Public_Key> <WG_Server_IP>"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Script parameters
|
||||
WG_SERVER_PRIVATE_KEY="$1"
|
||||
WG_SERVER_PUBLIC_KEY="$2"
|
||||
WG_INTERFACE="wg0"
|
||||
SERVER_IP="$3"
|
||||
LISTEN_PORT="51820"
|
||||
WG_DIR="/etc/wireguard"
|
||||
SERVER_KEYS_DIR="$WG_DIR/server_keys"
|
||||
SERVER_CONF="$WG_DIR/$WG_INTERFACE.conf"
|
||||
|
||||
# Update Package Repository. Upgrade and Autoremove Packages
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get -y update
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get -y upgrade
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get -y autoremove
|
||||
|
||||
# Step 1: Install WireGuard package
|
||||
if ! command -v wg > /dev/null; then
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt install -y wireguard
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt install -y resolvconf
|
||||
fi
|
||||
|
||||
# Step 2: Create directories for keys and configuration
|
||||
sudo mkdir -p "$SERVER_KEYS_DIR"
|
||||
sudo mkdir -p "$WG_DIR"
|
||||
|
||||
# Step 3: Generate Server Keys
|
||||
sudo echo $WG_SERVER_PRIVATE_KEY > "$SERVER_KEYS_DIR/${WG_INTERFACE}_privatekey"
|
||||
sudo echo $WG_SERVER_PUBLIC_KEY > "$SERVER_KEYS_DIR/${WG_INTERFACE}_publickey"
|
||||
server_private_key=$(sudo cat "$SERVER_KEYS_DIR/${WG_INTERFACE}_privatekey")
|
||||
|
||||
# Step 4: Create Server Configuration File
|
||||
sudo bash -c "cat > $SERVER_CONF <<EOF
|
||||
[Interface]
|
||||
Address = $SERVER_IP
|
||||
ListenPort = $LISTEN_PORT
|
||||
PrivateKey = $server_private_key
|
||||
SaveConfig = true
|
||||
EOF"
|
||||
|
||||
# Step 5: Enable and Start WireGuard
|
||||
sudo systemctl enable wg-quick@$WG_INTERFACE
|
||||
sudo systemctl start wg-quick@$WG_INTERFACE
|
||||
|
||||
echo "WireGuard server is up and running!"
|
||||
echo "Server configuration is located at $SERVER_CONF"
|
||||
echo "Server keys are stored in $SERVER_KEYS_DIR"
|
@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script parameter: WireGuard interface name (e.g., wg0)
|
||||
WG_INTERFACE=wg0
|
||||
|
||||
# Script parameter
|
||||
SSH_USERNAME="$1"
|
||||
|
||||
# Step 1: Disable and stop the WireGuard service
|
||||
sudo systemctl stop wg-quick@$WG_INTERFACE
|
||||
sudo systemctl disable wg-quick@$WG_INTERFACE
|
||||
|
||||
# Step 2: Remove the WireGuard interface
|
||||
sudo ip link delete $WG_INTERFACE
|
||||
|
||||
# Step 3: Remove Wiregaurd packages
|
||||
sudo apt remove --purge -y wireguard
|
||||
sudo apt autoremove -y
|
||||
|
||||
# Step 4: Remove OpenSSL Public Key
|
||||
sed -i '/wireguard-pub/d' /home/$SSH_USERNAME/.ssh/authorized_keys
|
||||
|
||||
# Step 5: Remove Wireguard related directories
|
||||
sudo rm -rf /etc/wireguard
|
||||
sudo rm -rf /home/$SSH_USERNAME/wireguard
|
||||
|
||||
echo "WireGuard has been uninstalled."
|
||||
echo "WireGuard server $WG_INTERFACE has been removed."
|
@ -8,15 +8,15 @@
|
||||
- nebulous-overlay-network-manager-container-images
|
||||
description: Build the container images.
|
||||
files: &image_files
|
||||
- ^java-spring-boot-demo/
|
||||
- ^network-manager/
|
||||
vars: &image_vars
|
||||
promote_container_image_job: nebulous-overlay-network-manager-upload-container-images
|
||||
container_images:
|
||||
- context: java-spring-boot-demo
|
||||
- context: network-manager
|
||||
registry: quay.io
|
||||
repository: quay.io/nebulous/overlay-network-manager-java-spring-boot-demo
|
||||
repository: quay.io/nebulous/overlay-network-manager
|
||||
namespace: nebulous
|
||||
repo_shortname: overlay-network-manager-java-spring-boot-demo
|
||||
repo_shortname: overlay-network-manager
|
||||
repo_description: ""
|
||||
|
||||
- job:
|
||||
@ -44,7 +44,7 @@
|
||||
description: Run Hadolint on Dockerfile(s).
|
||||
vars:
|
||||
dockerfiles:
|
||||
- java-spring-boot-demo/Dockerfile
|
||||
- network-manager/Dockerfile
|
||||
|
||||
- job:
|
||||
name: nebulous-overlay-network-manager-helm-lint
|
||||
|
Loading…
x
Reference in New Issue
Block a user