Skip to content

Commit

Permalink
Fix Kind extension to generate manifests (#1072)
Browse files Browse the repository at this point in the history
* Fix Kind extension to generate manifests

Plus, add the Kind page into the dekorate site. 
This pull request is related to quarkusio/quarkus#28078

* Include ports and service type into the kind annotations

* changes in documentation
  • Loading branch information
Sgitario authored Oct 5, 2022
1 parent 590708a commit 53f2842
Show file tree
Hide file tree
Showing 20 changed files with 583 additions and 36 deletions.
47 changes: 26 additions & 21 deletions annotations/kind-annotations/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,12 @@ limitations under the License.
<artifactId>docker-annotations</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<dependency>
<groupId>io.dekorate</groupId>
<artifactId>kubernetes-annotations</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>io.sundr</groupId>
<artifactId>builder-annotations</artifactId>
<scope>compile</scope>
Expand All @@ -60,7 +65,7 @@ limitations under the License.
<artifactId>sundr-codegen-velocity</artifactId>
<scope>compile</scope>
<optional>true</optional>
</dependency>
</dependency>
<dependency>
<groupId>io.dekorate</groupId>
<artifactId>dekorate-templates</artifactId>
Expand Down Expand Up @@ -115,7 +120,7 @@ limitations under the License.
</annotationProcessors>
</configuration>
</plugin>
<plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>${version.maven-shade-plugin}</version>
Expand All @@ -138,7 +143,7 @@ limitations under the License.
<filter>
<artifact>*:*</artifact>
<includes>
<include>io/dekorate/kubernetes/annotation/**</include>
<include>io/dekorate/kind/annotation/**</include>
<include>META-INF/MANIFEST.MF</include>
</includes>
</filter>
Expand All @@ -158,14 +163,14 @@ limitations under the License.
<filter>
<artifact>*:*</artifact>
<includes>
<include>io/dekorate/kubernetes/adapter/**</include>
<include>io/dekorate/kubernetes/apt/**</include>
<include>io/dekorate/kubernetes/config/**</include>
<include>io/dekorate/kubernetes/configurator/**</include>
<include>io/dekorate/kubernetes/decorator/**</include>
<include>io/dekorate/kubernetes/manifest/**</include>
<include>io/dekorate/kubernetes/hook/**</include>
<include>io/dekorate/kubernetes/listener/**</include>
<include>io/dekorate/kind/adapter/**</include>
<include>io/dekorate/kind/apt/**</include>
<include>io/dekorate/kind/config/**</include>
<include>io/dekorate/kind/configurator/**</include>
<include>io/dekorate/kind/decorator/**</include>
<include>io/dekorate/kind/manifest/**</include>
<include>io/dekorate/kind/hook/**</include>
<include>io/dekorate/kind/listener/**</include>
<include>META-INF/services/*</include>
<include>META-INF/MANIFEST.MF</include>
</includes>
Expand All @@ -186,14 +191,14 @@ limitations under the License.
<filter>
<artifact>*:*</artifact>
<includes>
<include>io/dekorate/kubernetes/adapter/**</include>
<include>io/dekorate/kubernetes/annotation/**</include>
<include>io/dekorate/kubernetes/config/**</include>
<include>io/dekorate/kubernetes/configurator/**</include>
<include>io/dekorate/kubernetes/decorator/**</include>
<include>io/dekorate/kubernetes/manifest/**</include>
<include>io/dekorate/kubernetes/hook/**</include>
<include>io/dekorate/kubernetes/listener/**</include>
<include>io/dekorate/kind/adapter/**</include>
<include>io/dekorate/kind/annotation/**</include>
<include>io/dekorate/kind/config/**</include>
<include>io/dekorate/kind/configurator/**</include>
<include>io/dekorate/kind/decorator/**</include>
<include>io/dekorate/kind/manifest/**</include>
<include>io/dekorate/kind/hook/**</include>
<include>io/dekorate/kind/listener/**</include>
<include>META-INF/services/io.dekorate.*</include>
<include>META-INF/MANIFEST.MF</include>
</includes>
Expand All @@ -203,6 +208,6 @@ limitations under the License.
</execution>
</executions>
</plugin>
</plugins>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,37 @@
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import io.dekorate.kubernetes.annotation.ImagePullPolicy;
import io.dekorate.kubernetes.annotation.Port;
import io.dekorate.kubernetes.annotation.ServiceType;
import io.dekorate.kubernetes.config.BaseConfig;
import io.sundr.builder.annotations.Adapter;
import io.sundr.builder.annotations.Buildable;
import io.sundr.builder.annotations.Pojo;

@Buildable(builderPackage = "io.fabric8.kubernetes.api.builder")
@Pojo(name = "KindLoadConfig", relativePath = "../config", autobox = true, mutable = true, superClass = BaseConfig.class, withStaticBuilderMethod = true, withStaticAdapterMethod = false, adapter = @Adapter(name = "KindLoadConfigAdapter", relativePath = "../adapter", withMapAdapterMethod = true))
@Pojo(name = "KindConfig", relativePath = "../config", autobox = true, mutable = true, superClass = BaseConfig.class, withStaticBuilderMethod = true, withStaticAdapterMethod = false, adapter = @Adapter(name = "KindConfigAdapter", relativePath = "../adapter", withMapAdapterMethod = true))
@Target({ ElementType.CONSTRUCTOR, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface Kind {

boolean enabled() default true;

/**
* Image pull policy.
*
* @return The image pull policy.
*/
ImagePullPolicy imagePullPolicy() default ImagePullPolicy.IfNotPresent;

/**
* The application ports.
*/
Port[] ports() default {};

/**
* The type of service that will be generated for the application.
*/
ServiceType serviceType() default ServiceType.NodePort;

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,36 +15,37 @@
*/
package io.dekorate.kind.apt;

import static io.dekorate.kind.config.KindConfigGenerator.KIND;

import java.util.HashSet;
import java.util.Set;

import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;

import io.dekorate.Logger;
import io.dekorate.LoggerFactory;
import io.dekorate.doc.Description;
import io.dekorate.kind.annotation.Kind;
import io.dekorate.processor.AbstractAnnotationProcessor;

@Description("Generates kubernetes manifests.")
@SupportedAnnotationTypes("io.dekorate.kind.annotation.Kind")
public class KindAnnotationProcessor extends AbstractAnnotationProcessor {

private final Logger LOGGER = LoggerFactory.getLogger();

public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
if (roundEnv.processingOver()) {
getSession().close();
return true;
}
Set<Element> mainClasses = new HashSet<>();
for (TypeElement typeElement : annotations) {
for (Element mainClass : roundEnv.getElementsAnnotatedWith(typeElement)) {
LOGGER.info("Found @Kind on: " + mainClass.toString());
process("kind", mainClass, Kind.class);
mainClasses.add(mainClass);
}
}

for (Element mainClass : mainClasses) {
process(KIND, mainClass, Kind.class);
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class DefaultKindConfigGenerator implements KindConfigGenerator {
public DefaultKindConfigGenerator(ConfigurationRegistry configurationRegistry) {
this.configurationRegistry = configurationRegistry;
this.configurationRegistry.add(new ApplyKindImageAutoloadConfiguration());
add(new DefaultConfiguration<KindLoadConfig>(KindLoadConfig.newKindLoadConfigBuilderFromDefaults()));
add(new DefaultConfiguration<KindConfig>(KindConfig.newKindConfigBuilderFromDefaults()));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import io.dekorate.config.AnnotationConfiguration;
import io.dekorate.config.ConfigurationSupplier;
import io.dekorate.config.PropertyConfiguration;
import io.dekorate.kind.adapter.KindLoadConfigAdapter;
import io.dekorate.kind.adapter.KindConfigAdapter;
import io.dekorate.kubernetes.config.Configuration;

public interface KindConfigGenerator extends ConfigurationGenerator, WithProject {
Expand All @@ -34,20 +34,20 @@ default String getKey() {
}

default Class<? extends Configuration> getConfigType() {
return KindLoadConfig.class;
return KindConfig.class;
}

@Override
default void addAnnotationConfiguration(Map map) {
add(new AnnotationConfiguration<>(KindLoadConfigAdapter.newBuilder(propertiesMap(map, KindLoadConfig.class))));
add(new AnnotationConfiguration<>(KindConfigAdapter.newBuilder(propertiesMap(map, KindConfig.class))));
}

@Override
default void addPropertyConfiguration(Map map) {
add(new PropertyConfiguration<>(KindLoadConfigAdapter.newBuilder(propertiesMap(map, KindLoadConfig.class))));
add(new PropertyConfiguration<>(KindConfigAdapter.newBuilder(propertiesMap(map, KindConfig.class))));
}

default void add(ConfigurationSupplier<KindLoadConfig> config) {
default void add(ConfigurationSupplier<KindConfig> config) {
getConfigurationRegistry().add(config);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* Copyright 2018 The original authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/

package io.dekorate.kind.decorator;

import io.dekorate.kubernetes.config.Port;
import io.dekorate.kubernetes.decorator.NamedResourceDecorator;
import io.dekorate.utils.Ports;
import io.fabric8.kubernetes.api.model.ObjectMeta;
import io.fabric8.kubernetes.api.model.ServicePortFluent;

public class ApplyPortToKindServiceDecorator extends NamedResourceDecorator<ServicePortFluent> {

private final Port port;

public ApplyPortToKindServiceDecorator(String name, Port port) {
super(name);
this.port = port;
}

@Override
public void andThenVisit(ServicePortFluent servicePort, ObjectMeta resourceMeta) {
if (port.getNodePort() > 0) {
servicePort.withNodePort(port.getNodePort());
} else {
servicePort.withNodePort(Ports.calculateNodePort(getName(), port));
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Copyright 2018 The original authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
**/

package io.dekorate.kind.decorator;

import io.dekorate.kind.config.KindConfig;
import io.dekorate.kubernetes.decorator.NamedResourceDecorator;
import io.fabric8.kubernetes.api.model.ObjectMeta;
import io.fabric8.kubernetes.api.model.ServiceSpecFluent;

public class ApplyServiceTypeToKindServiceDecorator extends NamedResourceDecorator<ServiceSpecFluent> {

private final KindConfig config;

public ApplyServiceTypeToKindServiceDecorator(String name, KindConfig config) {
super(name);
this.config = config;
}

@Override
public void andThenVisit(ServiceSpecFluent spec, ObjectMeta resourceMeta) {
spec.withType(config.getServiceType() != null ? config.getServiceType().name() : "NodePort");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package io.dekorate.kind.manifest;

import java.util.Arrays;

import io.dekorate.ConfigurationRegistry;
import io.dekorate.ResourceRegistry;
import io.dekorate.kind.config.KindConfig;
import io.dekorate.kind.decorator.ApplyPortToKindServiceDecorator;
import io.dekorate.kind.decorator.ApplyServiceTypeToKindServiceDecorator;
import io.dekorate.kubernetes.config.KubernetesConfig;
import io.dekorate.kubernetes.decorator.AddServiceResourceDecorator;
import io.dekorate.kubernetes.decorator.ApplyImagePullPolicyDecorator;
import io.dekorate.kubernetes.manifest.KubernetesManifestGenerator;

public class KindManifestGenerator extends KubernetesManifestGenerator {

private static final String KIND = "kind";

public KindManifestGenerator() {
this(new ResourceRegistry(), new ConfigurationRegistry());
}

public KindManifestGenerator(ResourceRegistry resourceRegistry, ConfigurationRegistry configurationRegistry) {
super(resourceRegistry, configurationRegistry);
}

@Override
public int order() {
return 400;
}

@Override
public String getKey() {
return KIND;
}

@Override
protected void addDecorators(String group, KubernetesConfig config) {
super.addDecorators(group, config);
if (config.getPorts().length > 0) {
resourceRegistry.decorate(group, new AddServiceResourceDecorator(config));
}
}

@Override
public void generate(KubernetesConfig kubernetesConfig) {
initializeRegistry(kubernetesConfig);
addDecorators(KIND, kubernetesConfig);

configurationRegistry.get(KindConfig.class).ifPresent(c -> {
resourceRegistry.decorate(KIND, new ApplyImagePullPolicyDecorator(kubernetesConfig.getName(), c.getImagePullPolicy()));
resourceRegistry.decorate(KIND, new ApplyServiceTypeToKindServiceDecorator(kubernetesConfig.getName(), c));
// Check if MinikubeConfig defines port, else fallback to KubernetesConfig
if (c.getPorts().length > 0) {
Arrays.stream(c.getPorts()).forEach(p -> {
resourceRegistry.decorate(KIND, new ApplyPortToKindServiceDecorator(kubernetesConfig.getName(), p));
});
} else {
Arrays.stream(kubernetesConfig.getPorts()).forEach(p -> {
resourceRegistry.decorate(KIND, new ApplyPortToKindServiceDecorator(kubernetesConfig.getName(), p));
});
}
});
}
}
Loading

0 comments on commit 53f2842

Please sign in to comment.