Java client for Kubernetes and OpenShift providing access to full REST APIs via a fluent DSL
—
This document covers OpenShift template operations, including parameter processing, template instantiation, and template instance management.
import io.fabric8.openshift.client.OpenShiftClient;
import io.fabric8.openshift.api.model.Template;
import io.fabric8.openshift.api.model.TemplateList;
import io.fabric8.openshift.api.model.TemplateInstance;
import io.fabric8.openshift.api.model.TemplateInstanceList;
import io.fabric8.openshift.api.model.BrokerTemplateInstance;
import io.fabric8.openshift.api.model.BrokerTemplateInstanceList;
import io.fabric8.openshift.api.model.Parameter;
import io.fabric8.openshift.client.dsl.TemplateResource;
import io.fabric8.kubernetes.client.dsl.ParameterMixedOperation;
import io.fabric8.kubernetes.client.dsl.Resource;
import io.fabric8.kubernetes.api.model.HasMetadata;
import io.fabric8.kubernetes.api.model.KubernetesResourceList;// List all templates in a namespace
TemplateList templates = client.templates()
.inNamespace("my-project")
.list();
// Get a specific template
Template template = client.templates()
.inNamespace("my-project")
.withName("my-app-template")
.get();
// List templates with label selector
TemplateList appTemplates = client.templates()
.inNamespace("my-project")
.withLabel("category", "web-apps")
.list();// Create a new template
Template newTemplate = new TemplateBuilder()
.withNewMetadata()
.withName("nodejs-app-template")
.withNamespace("my-project")
.addToLabels("category", "web-apps")
.addToAnnotations("description", "Node.js application template")
.endMetadata()
.addNewParameter()
.withName("APP_NAME")
.withDisplayName("Application Name")
.withDescription("The name of the application")
.withRequired(true)
.endParameter()
.addNewParameter()
.withName("IMAGE_TAG")
.withDisplayName("Image Tag")
.withDescription("The tag for the Docker image")
.withValue("latest")
.endParameter()
.addNewParameter()
.withName("REPLICAS")
.withDisplayName("Replica Count")
.withDescription("Number of application replicas")
.withValue("3")
.endParameter()
.addNewObject()
// DeploymentConfig object
.withNewRaw(Map.of(
"apiVersion", "apps.openshift.io/v1",
"kind", "DeploymentConfig",
"metadata", Map.of(
"name", "${APP_NAME}",
"labels", Map.of("app", "${APP_NAME}")
),
"spec", Map.of(
"replicas", "${{REPLICAS}}",
"selector", Map.of("app", "${APP_NAME}"),
"template", Map.of(
"metadata", Map.of(
"labels", Map.of("app", "${APP_NAME}")
),
"spec", Map.of(
"containers", List.of(Map.of(
"name", "${APP_NAME}",
"image", "nodejs:${IMAGE_TAG}",
"ports", List.of(Map.of("containerPort", 8080))
))
)
)
)
))
.endObject()
.addNewObject()
// Service object
.withNewRaw(Map.of(
"apiVersion", "v1",
"kind", "Service",
"metadata", Map.of(
"name", "${APP_NAME}",
"labels", Map.of("app", "${APP_NAME}")
),
"spec", Map.of(
"ports", List.of(Map.of(
"port", 8080,
"targetPort", 8080
)),
"selector", Map.of("app", "${APP_NAME}")
)
))
.endObject()
.build();
Template created = client.templates()
.inNamespace("my-project")
.create(newTemplate);// Get template parameters
Template template = client.templates()
.inNamespace("my-project")
.withName("my-app-template")
.get();
List<Parameter> parameters = template.getParameters();
for (Parameter param : parameters) {
System.out.println("Parameter: " + param.getName());
System.out.println(" Display Name: " + param.getDisplayName());
System.out.println(" Description: " + param.getDescription());
System.out.println(" Required: " + param.getRequired());
System.out.println(" Value: " + param.getValue());
System.out.println(" From: " + param.getFrom());
}// Process template with specific parameter values
Template processed = client.templates()
.inNamespace("my-project")
.withName("my-app-template")
.withParameter("APP_NAME", "my-nodejs-app")
.withParameter("IMAGE_TAG", "14-ubi8")
.withParameter("REPLICAS", "5")
.process();
// Process template with parameter map
Map<String, String> parameters = Map.of(
"APP_NAME", "my-nodejs-app",
"IMAGE_TAG", "14-ubi8",
"REPLICAS", "5"
);
Template processedWithMap = client.templates()
.inNamespace("my-project")
.withName("my-app-template")
.withParameters(parameters)
.process();// Process and get the objects
Template processed = client.templates()
.inNamespace("my-project")
.withName("my-app-template")
.withParameter("APP_NAME", "my-app")
.process();
// Extract and create objects from processed template
List<HasMetadata> objects = processed.getObjects();
for (HasMetadata object : objects) {
client.resource(object).createOrReplace();
}// Process template with parameter validation
Template template = client.templates()
.inNamespace("my-project")
.withName("my-app-template")
.get();
// Validate required parameters
List<Parameter> requiredParams = template.getParameters().stream()
.filter(Parameter::getRequired)
.collect(Collectors.toList());
Map<String, String> paramValues = new HashMap<>();
paramValues.put("APP_NAME", "validated-app");
paramValues.put("REPLICAS", "3");
// Check if all required parameters are provided
for (Parameter param : requiredParams) {
if (!paramValues.containsKey(param.getName())) {
throw new IllegalArgumentException(
"Required parameter missing: " + param.getName());
}
}
// Process with validated parameters
Template processed = client.templates()
.inNamespace("my-project")
.withName("my-app-template")
.withParameters(paramValues)
.process();// Create template instance
TemplateInstance templateInstance = new TemplateInstanceBuilder()
.withNewMetadata()
.withName("my-app-instance")
.withNamespace("my-project")
.endMetadata()
.withNewSpec()
.withNewTemplate()
.withNewMetadata()
.withName("my-app-template")
.withNamespace("my-project")
.endMetadata()
.endTemplate()
.addNewParameter()
.withName("APP_NAME")
.withValue("my-instance-app")
.endParameter()
.addNewParameter()
.withName("REPLICAS")
.withValue("2")
.endParameter()
.endSpec()
.build();
TemplateInstance created = client.templateInstances()
.inNamespace("my-project")
.create(templateInstance);// Get template instance status
TemplateInstance instance = client.templateInstances()
.inNamespace("my-project")
.withName("my-app-instance")
.get();
List<TemplateInstanceCondition> conditions = instance.getStatus().getConditions();
for (TemplateInstanceCondition condition : conditions) {
System.out.println("Condition: " + condition.getType());
System.out.println(" Status: " + condition.getStatus());
System.out.println(" Reason: " + condition.getReason());
System.out.println(" Message: " + condition.getMessage());
}
// Check if template instance is ready
boolean isReady = conditions.stream()
.anyMatch(condition ->
"Ready".equals(condition.getType()) &&
"True".equals(condition.getStatus()));// List template instances
TemplateInstanceList instances = client.templateInstances()
.inNamespace("my-project")
.list();
// Get objects created by template instance
TemplateInstance instance = client.templateInstances()
.inNamespace("my-project")
.withName("my-app-instance")
.get();
List<TemplateInstanceObject> createdObjects = instance.getStatus().getObjects();
for (TemplateInstanceObject obj : createdObjects) {
System.out.println("Created object: " + obj.getRef().getKind() +
"/" + obj.getRef().getName());
}// List broker template instances (cluster-scoped)
BrokerTemplateInstanceList brokerInstances = client.brokerTemplateInstances().list();
// Get specific broker template instance
BrokerTemplateInstance brokerInstance = client.brokerTemplateInstances()
.withName("cluster-template-instance")
.get();
// Create broker template instance
BrokerTemplateInstance newBrokerInstance = new BrokerTemplateInstanceBuilder()
.withNewMetadata()
.withName("shared-template-instance")
.endMetadata()
.withNewSpec()
.withNewTemplateInstance()
.withNewMetadata()
.withName("shared-app-instance")
.withNamespace("shared-project")
.endMetadata()
.withNewSpec()
.withNewTemplate()
.withNewMetadata()
.withName("shared-template")
.withNamespace("openshift")
.endMetadata()
.endTemplate()
.endSpec()
.endTemplateInstance()
.withNewBindingIDs("binding-12345")
.endSpec()
.build();
BrokerTemplateInstance created = client.brokerTemplateInstances()
.create(newBrokerInstance);// Watch template changes
client.templates()
.inNamespace("my-project")
.watch(new Watcher<Template>() {
@Override
public void eventReceived(Action action, Template template) {
System.out.println("Template " + action + ": " +
template.getMetadata().getName());
}
@Override
public void onClose(WatcherException cause) {
System.out.println("Template watch closed: " + cause.getMessage());
}
});
// Watch template instance changes
client.templateInstances()
.inNamespace("my-project")
.watch(new Watcher<TemplateInstance>() {
@Override
public void eventReceived(Action action, TemplateInstance instance) {
System.out.println("TemplateInstance " + action + ": " +
instance.getMetadata().getName());
if (instance.getStatus() != null) {
List<TemplateInstanceCondition> conditions =
instance.getStatus().getConditions();
conditions.forEach(condition ->
System.out.println(" " + condition.getType() +
": " + condition.getStatus()));
}
}
@Override
public void onClose(WatcherException cause) {
System.out.println("TemplateInstance watch closed: " + cause.getMessage());
}
});// Export template to YAML
Template template = client.templates()
.inNamespace("my-project")
.withName("my-app-template")
.get();
String templateYaml = Serialization.asYaml(template);
System.out.println(templateYaml);
// Import template from YAML
Template imported = Serialization.unmarshal(templateYaml, Template.class);
Template created = client.templates()
.inNamespace("target-project")
.create(imported);import io.fabric8.openshift.client.OpenShiftClient;
import io.fabric8.openshift.api.model.*;
public class TemplateManager {
private final OpenShiftClient client;
public TemplateManager(OpenShiftClient client) {
this.client = client;
}
public void deployFromTemplate(String namespace, String templateName,
Map<String, String> parameters) {
// 1. Get template
Template template = client.templates()
.inNamespace(namespace)
.withName(templateName)
.get();
if (template == null) {
throw new RuntimeException("Template not found: " + templateName);
}
// 2. Validate parameters
validateParameters(template, parameters);
// 3. Process template
Template processed = client.templates()
.inNamespace(namespace)
.withName(templateName)
.withParameters(parameters)
.process();
// 4. Create objects
List<HasMetadata> objects = processed.getObjects();
List<HasMetadata> created = new ArrayList<>();
for (HasMetadata object : objects) {
try {
HasMetadata createdObject = client.resource(object)
.createOrReplace();
created.add(createdObject);
System.out.println("Created: " + object.getKind() +
"/" + object.getMetadata().getName());
} catch (Exception e) {
System.err.println("Failed to create " + object.getKind() +
"/" + object.getMetadata().getName() + ": " + e.getMessage());
// Rollback created objects
rollbackCreatedObjects(created);
throw e;
}
}
System.out.println("Successfully deployed template: " + templateName);
}
private void validateParameters(Template template, Map<String, String> parameters) {
List<Parameter> templateParams = template.getParameters();
// Check required parameters
for (Parameter param : templateParams) {
if (param.getRequired() && !parameters.containsKey(param.getName())) {
throw new IllegalArgumentException(
"Required parameter missing: " + param.getName() +
" (" + param.getDisplayName() + ")");
}
}
// Set default values for missing optional parameters
for (Parameter param : templateParams) {
if (!parameters.containsKey(param.getName()) && param.getValue() != null) {
parameters.put(param.getName(), param.getValue());
}
}
}
private void rollbackCreatedObjects(List<HasMetadata> created) {
for (HasMetadata object : created) {
try {
client.resource(object).delete();
System.out.println("Rolled back: " + object.getKind() +
"/" + object.getMetadata().getName());
} catch (Exception e) {
System.err.println("Failed to rollback " + object.getKind() +
"/" + object.getMetadata().getName() + ": " + e.getMessage());
}
}
}
public TemplateInstance createTemplateInstance(String namespace, String templateName,
String instanceName,
Map<String, String> parameters) {
TemplateInstanceBuilder builder = new TemplateInstanceBuilder()
.withNewMetadata()
.withName(instanceName)
.withNamespace(namespace)
.endMetadata()
.withNewSpec()
.withNewTemplate()
.withNewMetadata()
.withName(templateName)
.withNamespace(namespace)
.endMetadata()
.endTemplate();
// Add parameters
for (Map.Entry<String, String> entry : parameters.entrySet()) {
builder.editSpec()
.addNewParameter()
.withName(entry.getKey())
.withValue(entry.getValue())
.endParameter()
.endSpec();
}
TemplateInstance instance = builder.build();
TemplateInstance created = client.templateInstances()
.inNamespace(namespace)
.create(instance);
// Wait for template instance to be ready
waitForTemplateInstanceReady(namespace, instanceName);
return created;
}
private void waitForTemplateInstanceReady(String namespace, String instanceName) {
client.templateInstances()
.inNamespace(namespace)
.withName(instanceName)
.waitUntilCondition(instance -> {
if (instance.getStatus() == null ||
instance.getStatus().getConditions() == null) {
return false;
}
return instance.getStatus().getConditions().stream()
.anyMatch(condition ->
"Ready".equals(condition.getType()) &&
"True".equals(condition.getStatus()));
}, 5, TimeUnit.MINUTES);
}
}public class TemplateLibrary {
private final OpenShiftClient client;
public TemplateLibrary(OpenShiftClient client) {
this.client = client;
}
public void installTemplateLibrary(String libraryNamespace,
String targetNamespace) {
// Get all templates from library namespace
TemplateList libraryTemplates = client.templates()
.inNamespace(libraryNamespace)
.list();
for (Template template : libraryTemplates.getItems()) {
// Clone template to target namespace
Template cloned = new TemplateBuilder(template)
.editMetadata()
.withNamespace(targetNamespace)
.withResourceVersion(null) // Clear resource version
.withUid(null) // Clear UID
.endMetadata()
.build();
try {
client.templates()
.inNamespace(targetNamespace)
.createOrReplace(cloned);
System.out.println("Installed template: " +
template.getMetadata().getName());
} catch (Exception e) {
System.err.println("Failed to install template " +
template.getMetadata().getName() + ": " + e.getMessage());
}
}
}
public List<Template> findTemplatesByCategory(String namespace, String category) {
return client.templates()
.inNamespace(namespace)
.withLabel("category", category)
.list()
.getItems();
}
}public class Template implements HasMetadata {
public ObjectMeta getMetadata();
public List<Parameter> getParameters();
public List<HasMetadata> getObjects();
public Map<String, String> getLabels();
public String getMessage();
}
public class Parameter {
public String getName();
public String getDisplayName();
public String getDescription();
public String getValue();
public Boolean getRequired();
public String getFrom();
public String getGenerate();
}public class TemplateInstance implements HasMetadata {
public ObjectMeta getMetadata();
public TemplateInstanceSpec getSpec();
public TemplateInstanceStatus getStatus();
}
public class TemplateInstanceSpec {
public TemplateInstanceRequester getRequester();
public Template getTemplate();
public List<Parameter> getParameters();
public ObjectReference getSecret();
}
public class TemplateInstanceStatus {
public List<TemplateInstanceCondition> getConditions();
public List<TemplateInstanceObject> getObjects();
}
public class TemplateInstanceCondition {
public String getType(); // InstantiateFailure, Ready
public String getStatus(); // True, False, Unknown
public String getLastTransitionTime();
public String getReason();
public String getMessage();
}
public class TemplateInstanceObject {
public ObjectReference getRef();
}public interface TemplateResource extends Resource<Template> {
Template process();
TemplateResource withParameter(String name, String value);
TemplateResource withParameters(Map<String, String> parameters);
}public class BrokerTemplateInstance implements HasMetadata {
public ObjectMeta getMetadata();
public BrokerTemplateInstanceSpec getSpec();
}
public class BrokerTemplateInstanceSpec {
public TemplateInstance getTemplateInstance();
public List<String> getBindingIDs();
}Install with Tessl CLI
npx tessl i tessl/maven-io-fabric8--kubernetes-client-project