Release/1.14 (#12)
* Removed extra = in newVersion. Added target to release action to use the correct branch (#7) Signed-off-by: Knut-Erik Johnsen <abstract@knut-erik.org> * Feature/update workflows (#11) * Removed extra = in newVersion. Added target to release action to use the correct branch Signed-off-by: Knut-Erik Johnsen <abstract@knut-erik.org> * Downgraded grpc to same version as the used springboot starter. Added javadoc. Removed componentscan since it's bad practie Signed-off-by: Knut-Erik Johnsen <abstract@knut-erik.org> --------- Signed-off-by: Knut-Erik Johnsen <abstract@knut-erik.org> --------- Signed-off-by: Knut-Erik Johnsen <abstract@knut-erik.org>
This commit is contained in:
parent
22907e78a0
commit
f25bf16b83
|
@ -1,9 +1,48 @@
|
|||
package io.crossplane.compositefunctions.starter.config;
|
||||
|
||||
import io.crossplane.compositefunctions.starter.conversion.CrossplaneExtraResourcesService;
|
||||
import io.crossplane.compositefunctions.starter.conversion.CrossplaneObservableService;
|
||||
import io.crossplane.compositefunctions.starter.conversion.CrossplaneResourceService;
|
||||
import org.checkerframework.checker.units.qual.C;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
/**
|
||||
* Autoconfiguration for the crossplane services.
|
||||
*/
|
||||
@AutoConfiguration
|
||||
@ComponentScan(basePackages = {"io.crossplane.compositefunctions.starter.conversion"})
|
||||
public class CrossplaneServiceConfiguration {
|
||||
|
||||
|
||||
/**
|
||||
* Set up services for working with extra resources
|
||||
* @return the crossplaneExtraResourcesService
|
||||
* @since 1.15
|
||||
*/
|
||||
@Bean
|
||||
public CrossplaneExtraResourcesService crossplaneExtraResourcesService() {
|
||||
return new CrossplaneExtraResourcesService();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up services for working with observed resources
|
||||
* @return the crossplaneObservableService
|
||||
* @since 1.14
|
||||
*/
|
||||
@Bean
|
||||
public CrossplaneObservableService crossplaneObservableService() {
|
||||
return new CrossplaneObservableService();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up services for working with default resources
|
||||
* @return the crossplaneResourceService
|
||||
* @since 1.15
|
||||
*/
|
||||
@Bean
|
||||
public CrossplaneResourceService crossplaneResourceService() {
|
||||
return new CrossplaneResourceService();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,15 +10,20 @@ import io.fabric8.kubernetes.api.model.HasMetadata;
|
|||
import io.fabric8.kubernetes.client.utils.Serialization;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
|
||||
@Component
|
||||
/**
|
||||
* Class that helps with the extra resources map and also to create ResourceSelector in order to get extra resources
|
||||
* to the function
|
||||
*
|
||||
* Commented out in 1.14
|
||||
*
|
||||
* @since 1.15
|
||||
*/
|
||||
public class CrossplaneExtraResourcesService {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(CrossplaneExtraResourcesService.class);
|
||||
|
|
|
@ -8,16 +8,25 @@ import io.crossplane.compositefunctions.starter.exception.CrossplaneUnmarshallEx
|
|||
import io.fabric8.kubernetes.client.utils.Serialization;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
/**
|
||||
* Class with helper methods for observable resources.
|
||||
*/
|
||||
public class CrossplaneObservableService {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(CrossplaneObservableService.class);
|
||||
private final JsonFormat.Printer printer = JsonFormat.printer();
|
||||
|
||||
/**
|
||||
* Retrieve a resource from the observedstate and convert in into class T
|
||||
* @param resourceName The resource name to find in the observed state
|
||||
* @param observedState The observed state from the crossplane input
|
||||
* @param clazz The class/type to create
|
||||
* @return An instance of class T from the observed state
|
||||
* @param <T> The class/type to create
|
||||
*/
|
||||
public <T> Optional<T> getObservableResource(String resourceName, State observedState, Class<T> clazz) {
|
||||
Resource observedResource = observedState.getResourcesOrDefault(resourceName, null);
|
||||
Optional<T> result = Optional.empty();
|
||||
|
|
|
@ -4,15 +4,23 @@ import com.google.protobuf.util.JsonFormat;
|
|||
import io.crossplane.compositefunctions.protobuf.State;
|
||||
import io.crossplane.compositefunctions.starter.exception.CrossplaneUnmarshallException;
|
||||
import io.fabric8.kubernetes.client.utils.Serialization;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Component
|
||||
/**
|
||||
* Class with helper methods for default resources.
|
||||
*/
|
||||
public class CrossplaneResourceService {
|
||||
|
||||
final JsonFormat.Printer printer = JsonFormat.printer();
|
||||
|
||||
/**
|
||||
* Converts the incoming Composite to instance of class T
|
||||
* @param observedState The observed state from the crossplane input
|
||||
* @param clazz The class/type to create
|
||||
* @return An instance of class T from the observed state
|
||||
* @param <T> The class/type to create
|
||||
*/
|
||||
public <T> Optional<T> getResource(State observedState, Class<T> clazz) {
|
||||
try {
|
||||
String resource = printer.print(observedState.getComposite().getResource());
|
||||
|
|
|
@ -1,11 +1,23 @@
|
|||
package io.crossplane.compositefunctions.starter.exception;
|
||||
|
||||
/**
|
||||
* Exception for unexpected items encountered when converting
|
||||
*/
|
||||
public class CrossplaneUnexpectedItemsException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Constructor with message
|
||||
* @param message The exception message
|
||||
*/
|
||||
public CrossplaneUnexpectedItemsException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with message and cause
|
||||
* @param message The exception message
|
||||
* @param cause The throwable that caused the exception
|
||||
*/
|
||||
public CrossplaneUnexpectedItemsException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,23 @@
|
|||
package io.crossplane.compositefunctions.starter.exception;
|
||||
|
||||
/**
|
||||
* Exception for errors when unmarhsalling
|
||||
*/
|
||||
public class CrossplaneUnmarshallException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Constructor with message
|
||||
* @param message The exception message
|
||||
*/
|
||||
public CrossplaneUnmarshallException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor with message and cause
|
||||
* @param message The exception message
|
||||
* @param cause The throwable that caused the exception
|
||||
*/
|
||||
public CrossplaneUnmarshallException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
|
|
@ -3,6 +3,10 @@ package io.crossplane.compositefunctions.starter.registration;
|
|||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.fabric8.kubernetes.api.model.ObjectMeta;
|
||||
|
||||
/**
|
||||
* Class to aid in setting up autoregistration. Used to ignore the default
|
||||
* fields when creating the openapiv3schema
|
||||
*/
|
||||
public abstract class CrossplaneCompositeResourceMixin {
|
||||
|
||||
@JsonIgnore
|
||||
|
|
|
@ -19,22 +19,33 @@ import io.fabric8.kubernetes.client.dsl.Resource;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static io.crossplane.compositefunctions.starter.registration.CrossplanJsonSchemaGenerator.getOpenAPIV3Schema;
|
||||
import static io.crossplane.compositefunctions.starter.registration.CrossplaneJsonSchemaGenerator.getOpenAPIV3Schema;
|
||||
|
||||
/**
|
||||
* Service that can register the composite resource together with a function,
|
||||
* which can also add other function to the pipeline definition
|
||||
*/
|
||||
public class CrossplaneCompositeResourceService {
|
||||
|
||||
|
||||
|
||||
public static <T extends CustomResource<?, Void>> void registerOrUpdateCompositeResource(String functionName,
|
||||
List<String> additionalFunctions,
|
||||
T functionDefinition,
|
||||
/**
|
||||
* Register or update the composite resource definition using the provided client.
|
||||
* The client needs access to register the types
|
||||
*
|
||||
* @param pipelineFunctions A list of functionnames to add to the composition pipeline
|
||||
* @param compositionDefinition The object that has the composition definiton
|
||||
* @param kubernetesClient The client to use to register the definition
|
||||
* @param <T> Must extend CustomResource
|
||||
*/
|
||||
public static <T extends CustomResource<?, Void>> void registerOrUpdateCompositeResource(List<String> pipelineFunctions,
|
||||
T compositionDefinition,
|
||||
KubernetesClient kubernetesClient) {
|
||||
|
||||
CompositeResourceDefinition compositeResourceDefinition = createCompositeResourceDefinition(functionDefinition);
|
||||
CompositeResourceDefinition compositeResourceDefinition = createCompositeResourceDefinition(compositionDefinition);
|
||||
|
||||
registerOrUpdateCompositeResourceDefinition(compositeResourceDefinition, kubernetesClient);
|
||||
|
||||
Composition composition = createCompositionDefinition(functionName, additionalFunctions, functionDefinition);
|
||||
Composition composition = createCompositionDefinition(pipelineFunctions, compositionDefinition);
|
||||
|
||||
registerOrUpdateCompositeResourceDefinition(composition, kubernetesClient);
|
||||
|
||||
|
@ -52,41 +63,49 @@ public class CrossplaneCompositeResourceService {
|
|||
}
|
||||
}
|
||||
|
||||
public static <T extends CustomResource<?, Void>> CompositeResourceDefinition createCompositeResourceDefinition(T functionDefinition) { //}, Class functionMixin) {
|
||||
/**
|
||||
* Create a CompositeResourceDefinition based on the provided CustomResource
|
||||
* If Namespaced, ClaimNames will be added in addition to Names.
|
||||
*
|
||||
* @param compositionDefinition The composition definition
|
||||
* @return A CompositeResourceDefintion based on the provided CustomResource
|
||||
* @param <T> Must extend CustomResource
|
||||
*/
|
||||
public static <T extends CustomResource<?, Void>> CompositeResourceDefinition createCompositeResourceDefinition(T compositionDefinition) { //}, Class functionMixin) {
|
||||
|
||||
CompositeResourceDefinition compositeResourceDefinition = new CompositeResourceDefinition();
|
||||
compositeResourceDefinition.setMetadata(CrossplaneMetadataBuilder.createMetadata(functionDefinition.getCRDName()));
|
||||
compositeResourceDefinition.setMetadata(CrossplaneMetadataBuilder.createMetadata(compositionDefinition.getCRDName()));
|
||||
|
||||
CompositeResourceDefinitionSpec spec = new CompositeResourceDefinitionSpec();
|
||||
spec.setGroup(functionDefinition.getGroup());
|
||||
spec.setGroup(compositionDefinition.getGroup());
|
||||
|
||||
String namePrefix = "";
|
||||
|
||||
if (functionDefinition instanceof Namespaced) {
|
||||
if (compositionDefinition instanceof Namespaced) {
|
||||
ClaimNames claimNames = new ClaimNames();
|
||||
claimNames.setKind(functionDefinition.getKind());
|
||||
claimNames.setPlural(functionDefinition.getPlural());
|
||||
claimNames.setSingular(functionDefinition.getSingular());
|
||||
claimNames.setKind(compositionDefinition.getKind());
|
||||
claimNames.setPlural(compositionDefinition.getPlural());
|
||||
claimNames.setSingular(compositionDefinition.getSingular());
|
||||
spec.setClaimNames(claimNames);
|
||||
namePrefix = "x";
|
||||
}
|
||||
|
||||
Names names = new Names();
|
||||
names.setKind(namePrefix + functionDefinition.getKind());
|
||||
names.setPlural(namePrefix + functionDefinition.getPlural());
|
||||
names.setSingular(namePrefix + functionDefinition.getSingular());
|
||||
names.setKind(namePrefix + compositionDefinition.getKind());
|
||||
names.setPlural(namePrefix + compositionDefinition.getPlural());
|
||||
names.setSingular(namePrefix + compositionDefinition.getSingular());
|
||||
spec.setNames(names);
|
||||
|
||||
Versions versions = new Versions();
|
||||
versions.setName(functionDefinition.getVersion());
|
||||
versions.setName(compositionDefinition.getVersion());
|
||||
|
||||
// This is not 100%. isStorage vs referencable. Need to check the crossplan docs
|
||||
versions.setReferenceable(functionDefinition.isStorage());
|
||||
versions.setServed(functionDefinition.isServed());
|
||||
versions.setReferenceable(compositionDefinition.isStorage());
|
||||
versions.setServed(compositionDefinition.isServed());
|
||||
|
||||
|
||||
Schema schema = new Schema();
|
||||
schema.setOpenAPIV3Schema(getOpenAPIV3Schema(functionDefinition.getClass(), CrossplaneCompositeResourceMixin.class));
|
||||
schema.setOpenAPIV3Schema(getOpenAPIV3Schema(compositionDefinition.getClass(), CrossplaneCompositeResourceMixin.class));
|
||||
|
||||
versions.setSchema(schema);
|
||||
spec.setVersions(List.of(versions));
|
||||
|
@ -108,26 +127,23 @@ public class CrossplaneCompositeResourceService {
|
|||
}
|
||||
|
||||
private static <T extends CustomResource<?, Void>> Composition createCompositionDefinition(
|
||||
String functionName, List<String> additionalFunctions,
|
||||
T functionDefinition) {
|
||||
List<String> pipelineFunctions, T compositionDefinition) {
|
||||
|
||||
Composition composition = new Composition();
|
||||
|
||||
composition.setMetadata(CrossplaneMetadataBuilder.createMetadata(functionDefinition.getKind().toLowerCase() + "-composition"));
|
||||
composition.setMetadata(CrossplaneMetadataBuilder.createMetadata(compositionDefinition.getKind().toLowerCase() + "-composition"));
|
||||
CompositionSpec compositionSpec = new CompositionSpec();
|
||||
|
||||
CompositeTypeRef compositeTypeRef = new CompositeTypeRef();
|
||||
compositeTypeRef.setKind(functionDefinition.getKind());
|
||||
compositeTypeRef.setApiVersion(functionDefinition.getApiVersion());
|
||||
compositeTypeRef.setKind(compositionDefinition.getKind());
|
||||
compositeTypeRef.setApiVersion(compositionDefinition.getApiVersion());
|
||||
|
||||
compositionSpec.setCompositeTypeRef(compositeTypeRef);
|
||||
compositionSpec.setMode(CompositionSpec.Mode.PIPELINE);
|
||||
|
||||
List<Pipeline> pipelineList = new ArrayList<>();
|
||||
|
||||
pipelineList.add(createPipeline(functionName));
|
||||
|
||||
additionalFunctions.forEach(s -> pipelineList.add(createPipeline(s)));
|
||||
pipelineFunctions.forEach(s -> pipelineList.add(createPipeline(s)));
|
||||
|
||||
compositionSpec.setPipeline(pipelineList);
|
||||
composition.setSpec(compositionSpec);
|
||||
|
|
|
@ -12,8 +12,17 @@ import io.fabric8.kubernetes.api.model.apiextensions.v1.JSONSchemaProps;
|
|||
import java.io.IOException;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class CrossplanJsonSchemaGenerator {
|
||||
/**
|
||||
* Generator of OpenApiV3Schema used when creating CompositeResourceDefinition
|
||||
*/
|
||||
public class CrossplaneJsonSchemaGenerator {
|
||||
|
||||
/**
|
||||
* Create the OpenApiV3Schema
|
||||
* @param clazz The class to create the schema from
|
||||
* @param mixin A mixin to use when Jackson maps the class
|
||||
* @return A OpenAPIV3Schema based on the given class
|
||||
*/
|
||||
public static OpenAPIV3Schema getOpenAPIV3Schema(Class clazz, Class mixin) {
|
||||
try {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
|
@ -52,6 +61,11 @@ public class CrossplanJsonSchemaGenerator {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the JSONSchemaProps from the class
|
||||
* @param clazz The class to get the schema from
|
||||
* @return The schemaprops based on the provided class
|
||||
*/
|
||||
public static JSONSchemaProps getJsonSchema(Class clazz) {
|
||||
try {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
|
@ -73,7 +87,9 @@ public class CrossplanJsonSchemaGenerator {
|
|||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class just use to ignore the ID property that automatically gets added.
|
||||
*/
|
||||
private abstract class IdIgnorer {
|
||||
|
||||
@JsonIgnore
|
|
@ -6,24 +6,51 @@ import io.fabric8.kubernetes.api.model.ObjectMetaBuilder;
|
|||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Convinience methods to create the Metadata object in any kubernetes resource
|
||||
*/
|
||||
public class CrossplaneMetadataBuilder {
|
||||
|
||||
private CrossplaneMetadataBuilder() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create metadata with name
|
||||
* @param name The name of the resource
|
||||
* @return The metdata object based on the input
|
||||
*/
|
||||
public static ObjectMeta createMetadata(String name) {
|
||||
return createMetadata(name, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create metadata with name and namespace
|
||||
* @param name The name of the resource
|
||||
* @param namespace The namespace of the resource
|
||||
* @return The metdata object based on the input
|
||||
*/
|
||||
public static ObjectMeta createMetadata(String name, String namespace) {
|
||||
return createMetadata(name, namespace, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create metadata with name, namespace and annotations
|
||||
* @param name The name of the resource
|
||||
* @param namespace The namespace of the resource
|
||||
* @param annotations Annotations to add to the metadata
|
||||
* @return The metdata object based on the input
|
||||
*/
|
||||
public static ObjectMeta createMetadata(String name, String namespace, Map<String, String> annotations) {
|
||||
return new ObjectMetaBuilder().withName(name).withNamespace(namespace).withAnnotations(annotations).build();
|
||||
}
|
||||
|
||||
|
||||
public static ObjectMeta createMetadata(String name) {
|
||||
return createMetadata(name, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add extra metadata to a Metadata object
|
||||
* @param annotations The extra metadata to add
|
||||
* @param objectMeta The metadata object to add it to
|
||||
* @return The metadata with the added annotations
|
||||
*/
|
||||
public static ObjectMeta addAnnotations(Map<String, String> annotations, ObjectMeta objectMeta) {
|
||||
|
||||
Map<String, String> existingAnnotations = objectMeta.getAnnotations();
|
||||
|
|
41
pom.xml
41
pom.xml
|
@ -29,7 +29,7 @@
|
|||
<kubernetes-client.version>6.13.0</kubernetes-client.version>
|
||||
<os-maven-plugin.version>1.7.1</os-maven-plugin.version>
|
||||
<protobuf.version>3.25.1</protobuf.version>
|
||||
<grpc.version>1.64.0</grpc.version>
|
||||
<grpc.version>1.63.0</grpc.version>
|
||||
<jakarta-annotation.version>1.3.5</jakarta-annotation.version>
|
||||
<slf4j.version>2.0.13</slf4j.version>
|
||||
<jackson-databind.version>2.17.1</jackson-databind.version>
|
||||
|
@ -100,43 +100,10 @@
|
|||
<!-- Protobuf -->
|
||||
<dependency>
|
||||
<groupId>io.grpc</groupId>
|
||||
<artifactId>grpc-protobuf</artifactId>
|
||||
<version>${grpc.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.grpc</groupId>
|
||||
<artifactId>grpc-stub</artifactId>
|
||||
<version>${grpc.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.grpc</groupId>
|
||||
<artifactId>grpc-core</artifactId>
|
||||
<version>${grpc.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.grpc</groupId>
|
||||
<artifactId>grpc-api</artifactId>
|
||||
<version>${grpc.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.grpc</groupId>
|
||||
<artifactId>grpc-util</artifactId>
|
||||
<version>${grpc.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.grpc</groupId>
|
||||
<artifactId>grpc-services</artifactId>
|
||||
<version>${grpc.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.grpc</groupId>
|
||||
<artifactId>grpc-inprocess</artifactId>
|
||||
<version>${grpc.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.grpc</groupId>
|
||||
<artifactId>grpc-netty-shaded</artifactId>
|
||||
<artifactId>grpc-bom</artifactId>
|
||||
<version>${grpc.version}</version>
|
||||
<scope>import</scope>
|
||||
<type>pom</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>jakarta.annotation</groupId>
|
||||
|
|
Loading…
Reference in New Issue