Skip to content
Snippets Groups Projects
Commit 8895622f authored by trantzas's avatar trantzas Committed by tranoris
Browse files

added some documentation under #2

parents 9ceb63c1 e172b97d
No related branches found
No related tags found
1 merge request!8Merging 2024Q2_RC into main, creating 2024Q2 Release
......@@ -2,5 +2,5 @@ FROM ibm-semeru-runtimes:open-17.0.7_7-jdk
MAINTAINER openslice.io
RUN mkdir /opt/shareclasses
RUN mkdir -p /opt/openslice/lib/
COPY target/org.etsi.osl.cridge-1.2.0-SNAPSHOT-exec.jar /opt/openslice/lib/
CMD ["java", "-Xshareclasses:cacheDir=/opt/shareclasses", "-jar", "/opt/openslice/lib/org.etsi.osl.cridge-1.2.0-SNAPSHOT-exec.jar"]
COPY target/org.etsi.osl.cridge-1.0.0-SNAPSHOT-exec.jar /opt/openslice/lib/
CMD ["java", "-Xshareclasses:cacheDir=/opt/shareclasses", "-jar", "/opt/openslice/lib/org.etsi.osl.cridge-1.0.0-SNAPSHOT-exec.jar"]
@startuml
actor Participant as caller
boundary OSLAPI as oslapirest
control OSLC as oslapi
control OSOM as osom
control CRIDGE as cridge
control MGMK8S as mgtk8s
control ARGOCD as argo
control K8SaaSCRD as k88ascrd
caller -> oslapirest : Create Service Order for K8SaaS spec\n (With ACKNOWLEDGED state)
oslapirest -> oslapi: Create\nService\nOrder
osom -> oslapi: Fetch ACK\norders
activate osom
osom -> osom: Process orders
osom -> cridge: Deploy CR App
note right
This CR is matched with equivalent
Resource in RI (ref resourceId)
end note
cridge -// mgtk8s: Create CR
note right
here we label this CR with resourceId
end note
cridge -> cridge: Start watching\nSO namespace
cridge -> osom: response OK
osom -> oslapi: Order is INPROGRESS \n (services are created\nin RESERVED)
mgtk8s -> argo: Create CR
argo -> k88ascrd: Create CR
argo -// mgtk8s: CR status
mgtk8s -// cridge: CRs watch
group sync and reconciliation
cridge -// oslapi: Update equivalent resource in RI of this CR\n(ref resourceId)
oslapi -> oslapi: EVENT_RESOURCE_STATE_CHANGED
mgtk8s -// cridge: Secrets watch
cridge -// oslapi: Add/Update equivalent secret resource in RI of this CR\n(ref resourceId)
note right
org.etsi.osl.* labels are added
so this resource can be managed by OSL
end note
oslapi -> oslapi: EVENT_RESOURCE_STATE_CHANGED
note left
SIM638 needs to take this event in case
this Resource is related
to a specific supporting resource
(see resourceStateChangedEvent() and
updateResourceFromKubernetesLabel() )
Any resources that has characteristic org.etsi.osl.serviceId equals to a service
are automatically added as supportingResources of this Service
end note
end
osom -> osom: Wait all Active or Failures
note left
Wait for all services and
underlying resources
to be Active or Failed
end note
osom -> osom: Order is COMPLETED
osom -> oslapi: Order is COMPLETED
deactivate osom
group sync and reconciliation (continuous process)
mgtk8s -// cridge: CRs watch
cridge -// oslapi: Update equivalent resource in RI of this CR\n(ref resourceId)
oslapi -> oslapi: EVENT_RESOURCE_STATE_CHANGED
mgtk8s -// cridge: Secrets watch
cridge -// oslapi: Add/Update equivalent secret resource in RI of this CR\n(ref resourceId)
oslapi -> oslapi: EVENT_RESOURCE_STATE_CHANGED
end
caller -> oslapirest : request Service Order (by id)
activate caller
caller <- oslapirest : Service Order
caller -> caller : examine supportingService list
caller -> oslapirest : request Service (by id)
activate caller #FFDDDD
group focus only on the Resource Facing Service
caller -> caller : examine supportingResource list of this RFS
caller -> oslapirest : request Resource (by id) (tf-output@...)
caller <- oslapirest : Resource from Inventory
caller -> caller :get characteristics kubeconf
caller -> oslapirest : request Resource (by id) (tfstate-...)
caller <- oslapirest : Resource from Inventory
caller -> caller :get characteristic tfstate
end
deactivate caller
deactivate caller
@enduml
@startuml
participant "WatcherService" as Watcher
participant "SharedInformerFactory" as InformerFactory
participant "SharedIndexInformer<CRD>" as IndexInformer
participant "CustomResourceDefinition" as CRD
participant "ResourceEventHandler<CRD>" as EventHandler
database "CatalogClient" as Catalog
Watcher -> InformerFactory : getKubernetesClient().informers()
activate InformerFactory
InformerFactory --> Watcher : sharedInformerFactory
deactivate InformerFactory
Watcher -> IndexInformer : sharedInformerFactory.sharedIndexInformerFor(CRD, 30 * 1000L)
activate IndexInformer
IndexInformer --> Watcher : shixInformer
deactivate IndexInformer
Watcher -> IndexInformer : addEventHandler(new ResourceEventHandler<CRD>())
activate IndexInformer
IndexInformer -> EventHandler : onAdd(CRD)
activate EventHandler
EventHandler -> Catalog : createOrUpdateResourceSpecByNameCategoryVersion()
EventHandler -> Catalog : createOrUpdateResourceByNameCategoryVersion()
activate Catalog
Catalog --> EventHandler : Response
deactivate Catalog
EventHandler --> IndexInformer : onAdd Completed
EventHandler -> Watcher : createCRDSharedIndexInformer
deactivate EventHandler
IndexInformer -> EventHandler : onUpdate(oldCRD, newCRD)
activate EventHandler
EventHandler --> IndexInformer : onUpdate Completed
deactivate EventHandler
IndexInformer -> EventHandler : onDelete(CRD, deletedFinalStateUnknown)
activate EventHandler
EventHandler --> IndexInformer : onDelete Completed
deactivate EventHandler
deactivate IndexInformer
@enduml
\ No newline at end of file
@startuml
queue MQ
control "KubernetesClientResource" as KubeClientResource
participant "KubernetesClient" as KubeClient
entity "GenericKubernetesResource" as ResourceObj
participant "Namespace" as NamespaceDB
MQ -> KubeClientResource : deployCR(headers, crspec)
alt check if this cridge can handle the CRSPEC\ncurrentContextCluster, clusterMasterURL
KubeClientResource --> MQ : Response (SEE OTHER)
end
activate KubeClientResource
KubeClientResource -> KubeClient : new KubernetesClientBuilder()
activate KubeClient
KubeClient --> KubeClientResource : k8s
deactivate KubeClient
KubeClientResource -> NamespaceDB : Try creating Namespace
activate NamespaceDB
NamespaceDB --> KubeClientResource : Namespace Created / Exists
deactivate NamespaceDB
KubeClientResource -> KubeClientResource : createWatchersFornamespace()
activate KubeClientResource
KubeClientResource -> SharedInformer : KubernetesClient.secrets().inNamespace(nameSpacename).inform(new ResourceEventHandler<>())
loop For each Secret Event
SharedInformer -> EventHandler : onAdd()/onUpdate()/onDelete()
activate EventHandler
EventHandler -> KubeClientResource : updateKubernetesSecretResourceInOSLCatalog
deactivate EventHandler
end
deactivate KubeClientResource
KubeClientResource -> ResourceObj : k8s.resource(gkr)
activate ResourceObj
ResourceObj --> KubeClientResource : Creation Response
deactivate ResourceObj
KubeClientResource --> MQ : Response (OK / FAIL)
deactivate KubeClientResource
@enduml
......@@ -9,8 +9,8 @@
<relativePath>../org.etsi.osl.main</relativePath>
</parent>
<artifactId>org.etsi.osl.cridge</artifactId>
<artifactId>org.etsi.osl.cridge</artifactId>
<name>org.etsi.osl.cridge</name>
<url>http://openslice.io</url>
......@@ -103,12 +103,12 @@
<dependency>
<groupId>org.etsi.osl</groupId>
<artifactId>org.etsi.osl.model.tmf</artifactId>
<version>${project.version}</version>
<version>${org.etsi.osl.model.tmf.version}</version>
</dependency>
<dependency>
<groupId>org.etsi.osl</groupId>
<artifactId>org.etsi.osl.model.k8s</artifactId>
<version>${project.version}</version>
<version>${org.etsi.osl.model.k8s.version}</version>
</dependency>
......
___ ____ _ _
/ _ \ _ __ ___ _ __ / ___|| (_) ___ ___
| | | | '_ \ / _ \ '_ \\___ \| | |/ __/ _ \
| |_| | |_) | __/ | | |___) | | | (_| __/
\___/| .__/ \___|_| |_|____/|_|_|\___\___|
|_|
__ __________________
/ / __ __ / __/_ __/ __/ _/
/ _ \/ // / / _/ / / _\ \_/ /
/_.__/\_, / /___/ /_/ /___/___/
/___/
\ No newline at end of file
package org.etsi.osl.cridge;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import io.fabric8.kubernetes.api.model.GenericKubernetesResource;
import io.fabric8.kubernetes.api.model.GenericKubernetesResourceBuilder;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
import io.fabric8.kubernetes.client.dsl.base.ResourceDefinitionContext;
import io.fabric8.kubernetes.client.dsl.Resource;
public class CreateResource {
public static void main(String[] args) {
try (final KubernetesClient k8s = new KubernetesClientBuilder().build()) {
/**
* 1st approach with GenericKubernetesResource
*/
// ResourceDefinitionContext context = new ResourceDefinitionContext.Builder()
// .withGroup("stable.example.com")
// .withVersion("v1")
// .withKind("CronTab")
// .withPlural("crontabs")
// .withNamespaced(true)
// .build();
//
// k8s.genericKubernetesResources(context)
// .inNamespace("default")
// .resource(genericKubernetesResource)
// .create();
/**
* 2nd approach with GenericKubernetesResource
*/
Map<String, Object> spec = new HashMap<>();
spec.put("title", "my-awesome-book title");
spec.put("author", "TestAuthor");
spec.put("isbn", "0077000007");
GenericKubernetesResource genericKubernetesResource = new GenericKubernetesResourceBuilder()
.withApiVersion("testing.fabric8.io/v1alpha1").withKind("Book").withNewMetadata()
.withName("my-new-book-object-" + UUID.randomUUID().toString()).withNamespace("testakis")
.endMetadata().addToAdditionalProperties("spec", spec).build();
Resource<GenericKubernetesResource> dummyObject = k8s.resource(genericKubernetesResource);
// Create Custom Resource
dummyObject.create();
}
}
}
package org.etsi.osl.cridge;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import io.fabric8.kubernetes.api.model.GenericKubernetesResource;
import io.fabric8.kubernetes.api.model.GenericKubernetesResourceBuilder;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
import io.fabric8.kubernetes.client.dsl.base.ResourceDefinitionContext;
import io.fabric8.kubernetes.client.utils.Serialization;
import io.fabric8.kubernetes.client.dsl.Resource;
public class CreateResourceArgoJenkins {
// @formatter:off
public static void main(String[] args) {
try (final KubernetesClient k8s = new KubernetesClientBuilder().build()) {
String yamlfile =
"""
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: openslice-jenkins
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
destination:
namespace: default #update namespace name if you wish
name: in-cluster #update cluster name if its different
source:
repoURL: https://charts.jenkins.io
targetRevision: "4.6.1"
chart: jenkins
helm:
values: |
controller:
service:
type: ClusterIP
operation:
initiatedBy:
username: %s
sync:
prune: true
syncStrategy:
hook: {}
""".formatted( "myuser" );
System.out.println( yamlfile );
GenericKubernetesResource gkr = Serialization.unmarshal(yamlfile);
Resource<GenericKubernetesResource> dummyObject = k8s.resource( gkr );
dummyObject.create();
/*
* to delete we need:
* kubectl patch app openslice-jenkins -n argocd -p '{"metadata": {"finalizers": ["resources-finalizer.argocd.argoproj.io"]}}' --type merge
* kubectl delete app openslice-jenkins -n argocd
*/
}
}
}
package org.etsi.osl.cridge;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import org.apache.camel.util.json.JsonObject;
import io.fabric8.kubernetes.api.model.GenericKubernetesResource;
import io.fabric8.kubernetes.api.model.GenericKubernetesResourceBuilder;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
import io.fabric8.kubernetes.client.dsl.base.ResourceDefinitionContext;
import io.fabric8.kubernetes.client.utils.Serialization;
import io.fabric8.kubernetes.client.dsl.Resource;
public class CreateResourceArgoJenkinsProgram {
// @formatter:off
public static void main(String[] args) {
try (final KubernetesClient k8s = new KubernetesClientBuilder().build()) {
JsonObject objSpec = new JsonObject();
objSpec.put("project", "default");
//obj.put("num", Integer.valueOf(100));
JsonObject objdestination = new JsonObject();
objdestination.put("namespace", "default");
objdestination.put("name", "in-cluster");
objSpec.put("destination", objdestination);
JsonObject objsource = new JsonObject();
objsource.put("repoURL", "https://charts.jenkins.io");
objsource.put("targetRevision", "4.6.1");
objsource.put("chart", "jenkins");
JsonObject objvalues = new JsonObject();
objvalues.put("values", "controller:\n service:\n type: ClusterIP\n");
objsource.put("helm", objvalues);
objSpec.put("source", objsource);
JsonObject objOperation = new JsonObject();
JsonObject intiby = (new JsonObject());
intiby.put("username", "testadmin");
objOperation.put("initiatedBy", intiby);
JsonObject objsync = new JsonObject();
objsync.put("prune", Boolean.valueOf(true));
JsonObject syncStrategy = (new JsonObject());
syncStrategy.put("hook", new JsonObject());
objsync.put("syncStrategy", syncStrategy );
objOperation.put("sync", objsync );
GenericKubernetesResource genericKubernetesResource = new GenericKubernetesResourceBuilder()
.withApiVersion("argoproj.io/v1alpha1")
.withKind("Application")
.withNewMetadata()
.withName( "openslice-jenkins" )
.withNamespace( "argocd" )
.addToFinalizers("resources-finalizer.argocd.argoproj.io")
.endMetadata()
.addToAdditionalProperties("spec", objSpec)
.addToAdditionalProperties("operation", objOperation)
.build();
System.out.println( Serialization.asYaml( genericKubernetesResource ) );
System.out.println( "=============as Json===========================" );
System.out.println( Serialization.asJson( genericKubernetesResource ) );
Resource<GenericKubernetesResource> dummyObject = k8s.resource(genericKubernetesResource);
// Create Custom Resource
dummyObject.create();
/*
* to delete we need:
* kubectl patch app ingress-nginx -n argocd -p '{"metadata": {"finalizers": ["resources-finalizer.argocd.argoproj.io"]}}' --type merge
* kubectl delete app ingress-nginx -n argocd
*/
}
}
}
/**
*
*
{
"apiVersion": "argoproj.io/v1alpha1",
"kind": "Application",
"metadata": {
"finalizers": [
"resources-finalizer.argocd.argoproj.io"
],
"name": "openslice-jenkins",
"namespace": "argocd"
},
"spec": {
"project": "default",
"destination": {
"namespace": "default",
"name": "in-cluster"
},
"source": {
"repoURL": "https://charts.jenkins.io",
"targetRevision": "4.6.1",
"chart": "jenkins",
"helm": {
"values": "controller:\n service:\n type: ClusterIP\n"
}
}
},
"operation": {
"initiatedBy": {
"username": "testadmin"
},
"sync": {
"prune": true,
"syncStrategy": {
"hook": {}
}
}
}
}
*
*/
package org.etsi.osl.cridge;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import io.fabric8.kubernetes.api.model.GenericKubernetesResource;
import io.fabric8.kubernetes.api.model.GenericKubernetesResourceBuilder;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
import io.fabric8.kubernetes.client.dsl.base.ResourceDefinitionContext;
import io.fabric8.kubernetes.client.utils.Serialization;
import io.fabric8.kubernetes.client.dsl.Resource;
public class CreateResourceArgoNginx {
// @formatter:off
public static void main(String[] args) {
try (final KubernetesClient k8s = new KubernetesClientBuilder().build()) {
String yamlfile =
"""
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: ingress-nginx
namespace: argocd
spec:
project: default
destination:
namespace: default
#update namespace name if you wish
name: in-cluster #update cluster name if its different
source:
repoURL: https://kubernetes.github.io/ingress-nginx
targetRevision: "4.4.0"
chart: ingress-nginx
helm:
values: |
controller:
service:
type: ClusterIP
operation:
initiatedBy:
username: %s
sync:
prune: true
syncStrategy:
hook: {}
""".formatted( "myuser" );
System.out.println( yamlfile );
GenericKubernetesResource gkr = Serialization.unmarshal(yamlfile);
Resource<GenericKubernetesResource> dummyObject = k8s.resource( gkr );
dummyObject.create();
/*
* to delete we need:
* kubectl patch app ingress-nginx -n argocd -p '{"metadata": {"finalizers": ["resources-finalizer.argocd.argoproj.io"]}}' --type merge
* kubectl delete app ingress-nginx -n argocd
*/
}
}
}
package org.etsi.osl.cridge;
import io.fabric8.kubernetes.api.model.ConfigMap;
import io.fabric8.kubernetes.api.model.Namespace;
import io.fabric8.kubernetes.api.model.NamespaceBuilder;
import io.fabric8.kubernetes.api.model.Secret;
import io.fabric8.kubernetes.api.model.Service;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
import io.fabric8.kubernetes.client.Watch;
import io.fabric8.kubernetes.client.Watcher;
import io.fabric8.kubernetes.client.WatcherException;
import io.fabric8.kubernetes.client.Watcher.Action;
import io.fabric8.kubernetes.client.utils.Serialization;
public class GetResourcesOfNamespace {
// @formatter:off
public static void main(String[] args) throws InterruptedException {
try (final KubernetesClient k8s = new KubernetesClientBuilder().build()) {
Namespace ns = new NamespaceBuilder()
.withNewMetadata()
.withName( "opencrdtest" )
.endMetadata().build();
for (Secret secret : k8s.secrets().inNamespace("opencrdtest").list().getItems() ) {
System.out.println( Serialization.asYaml( secret ) );
}
for (Service secret : k8s.services().inNamespace("opencrdtest").list().getItems() ) {
System.out.println( Serialization.asYaml( secret ) );
}
for (ConfigMap secret : k8s.configMaps().inNamespace("opencrdtest").list().getItems() ) {
System.out.println( Serialization.asYaml( secret ) );
}
}
try (final KubernetesClient k8s = new KubernetesClientBuilder().build()) {
Watch watch = k8s.secrets().inNamespace( "16cce858-2f99-4f8f-afe6-9e1f21a78880").watch( new Watcher<>() {
@Override
public void eventReceived(Action action, Secret resource) {
System.out.println(String.format("%s Namespace watcher Resource Kind:%s Name:%s UID:%s Namespace:%s", action.name(),
resource.getKind(),
resource.getMetadata().getName(),
resource.getMetadata().getUid(),
resource.getMetadata().getNamespace()));
//ADDED, DELETED, MODIFIED, BOOKMARK, ERROR
}
@Override
public void onClose(WatcherException cause) {
System.out.println(String.format("Closing resources Watcher of nameSpace due to %s "+cause.getMessage()));
return;
}
});
Thread.sleep(60 * 1000L);
watch.close();
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment