first code commit

This commit is contained in:
Sander Hautvast 2021-07-12 14:19:53 +02:00
parent 6e10b7e9eb
commit 7ee55ca4a8
13 changed files with 1448 additions and 0 deletions

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
target/
*.iml
.idea/

2
README.md Normal file
View file

@ -0,0 +1,2 @@
Cleaner for yaml files that openshift has created using oc get [resource] -o yaml.
NB. Work in progress: it works fine, but it might need adding more remove actions for certain outputs.

55
pom.xml Normal file
View file

@ -0,0 +1,55 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>nl.sander</groupId>
<artifactId>yaml-cleaner</artifactId>
<version>0.1-SNAPSHOT</version>
<name>yaml-cleaner</name>
<properties>
<jackson.version>2.10.4</jackson.version>
</properties>
<dependencies>
<!-- YAML -->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- Allow use of LocalDate -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.14</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>11</release>
</configuration>
</plugin>
</plugins>
</build>
</project>

View file

@ -0,0 +1,64 @@
package nl.sander;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import java.io.File;
import java.io.IOException;
import java.util.Map;
public class Cleaner {
private final String yamlFile;
private final ObjectMapper objectMapper;
public Cleaner(String filename) {
this.yamlFile = filename;
objectMapper = new ObjectMapper(new YAMLFactory());
objectMapper.findAndRegisterModules();
}
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("usage: nl.sander.Cleaner <file>");
System.exit(-1);
}
String filename = args[0];
new Cleaner(filename).run();
}
private void run() {
try {
Object resource = objectMapper.readValue(new File(yamlFile), Object.class);
Map<String, Object> cleaned = clean(YamlObject.of(resource));
objectMapper.writeValue(new File(yamlFile + "_cleaned"), cleaned);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private Map<String, Object> clean(YamlObject resource) {
resource.get("items")
.forEach(item -> {
YamlObject metadata = item.get("metadata");
metadata.remove("managedFields");
metadata.clear("annotations");
metadata.remove("creationTimestamp");
metadata.get("labels").removeIf("_key!=app");
metadata.remove("selfLink");
metadata.remove("namespace");
metadata.remove("resourceVersion");
metadata.remove("uid");
YamlObject spec = item.get("spec");
spec.clear("template/metadata/annotations");
spec.remove("template/spec/containers/0/image");
spec.remove("template/metadata/creationTimestamp");
spec.remove("triggers/1/imageChangeParams/lastTriggeredImage");
spec.removeIf("triggers/1/imageChangeParams/from/namespace != openshift");
item.remove("status");
});
return resource.asMap();
}
}

View file

@ -0,0 +1,79 @@
package nl.sander;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Function;
@SuppressWarnings("unchecked")
public class Union {
private final List<Class<?>> types = new ArrayList<>();
private Object value;
public Union(Class<?>... types) {
if (Arrays.stream(types).distinct().count() != types.length) {
throw new IllegalArgumentException("types must be unique");
} else {
for (Class<?> left : types) {
for (Class<?> right : types) {
if (left != right && (left.isAssignableFrom(right) || right.isAssignableFrom(left))) {
throw new IllegalArgumentException("types must not belong to same class hierarchy");
}
}
}
this.types.addAll(Arrays.asList(types));
}
}
public void set(Object newValue) {
if (newValue == null) {
throw new NullPointerException();
}
checkType(newValue.getClass());
this.value = newValue;
}
public <T> T get() {
return (T) this.value;
}
public <T> void when(Class<T> type, Consumer<T> consumer) {
checkType(type);
if (type.isAssignableFrom(value.getClass())) {
consumer.accept((T) value);
}
}
public <T, R> Optional<R> map(Class<T> type, Function<T, R> function) {
checkType(type);
if (type.isAssignableFrom(value.getClass())) {
return Optional.ofNullable(function.apply((T) value));
} else {
return Optional.empty();
}
}
private void checkType(Class<?> someType) {
Class<?> selectedType = null;
for (Class<?> type : types) {
if (type.isAssignableFrom(someType)) {
selectedType = type;
}
}
if (selectedType == null) {
throw new IllegalArgumentException("unknown type for this union: " + someType.getName());
}
}
@Override
public String toString() {
return "Union{ value=" + value.getClass() + '}';
}
}

View file

@ -0,0 +1,128 @@
package nl.sander;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
//this is almost exactly unlike xpath
public class YamlObject {
private final Union union = new Union(Map.class, List.class, String.class);
public static YamlObject of(Object value) {
YamlObject yamlObject = new YamlObject();
yamlObject.union.set(value);
return yamlObject;
}
public YamlObject get(String path) {
YamlObject result = this;
for (String element : path.split("/")) {
result = result.doGget(element);
}
return result;
}
private YamlObject doGget(String key) {
Optional<YamlObject> optionalYamlObject = union.map(List.class, l -> YamlObject.of(l.get(Integer.parseInt(key))));
return optionalYamlObject
.orElseGet(() -> union.map(Map.class, m -> YamlObject.of(m.get(key)))
.orElseThrow(() -> new IllegalArgumentException("Not a collection object: " + union)));
}
public void clear(String path) {
get(path).clear();
}
public void clear() {
union.when(Map.class, Map::clear);
union.when(List.class, List::clear);
}
public void remove(String path) {
executeOn(path, (fetchedObject, lastPathElement) -> {
fetchedObject.union.when(Map.class, m -> m.remove(lastPathElement));
fetchedObject.union.when(List.class, l -> l.remove(Integer.parseInt(lastPathElement)));
});
}
private void executeOn(String path, BiConsumer<YamlObject, String> consumer) {
if (path.contains("/")) {
while (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}
int lastSlash = path.lastIndexOf('/');
String head = path.substring(0, lastSlash);
YamlObject object = get(head);
String tail = path.substring(lastSlash + 1);
consumer.accept(object, tail);
} else {
consumer.accept(this, path);
}
}
public void remove(int index) {
union.when(List.class, l -> l.remove(index));
}
public YamlObject retain(String... keys) {
List<String> keyList = Arrays.asList(keys);
union.when(Map.class, m -> m.keySet().removeIf(key -> !keyList.contains(key)));
return this;
}
public Map<String, Object> asMap() {
return union.map(Map.class, m -> (Map<String, Object>) m).orElseThrow(() -> new RuntimeException("Not a map"));
}
public void removeIf(String path) {
executeOn(path, this::removeIf);
}
private void removeIf(YamlObject fetchedYamlObject, String expression) {
boolean opEquals;
if (expression.contains("==")) {
opEquals = true;
} else if (expression.contains("!=")) {
opEquals = false;
} else {
throw new IllegalArgumentException("syntax exception");
}
String[] tokens = expression.split("[!=]=");
String key = tokens[0].trim();
String operand = tokens[1].trim();
if (key.equals("_key") || key.equals("_value")) {
fetchedYamlObject.union.when(Map.class, m -> {
for (Iterator<Map.Entry<?, ?>> iterator = m.entrySet().iterator(); iterator.hasNext(); ) {
Map.Entry<?, ?> entry = iterator.next();
Object selector;
if (key.equals("_key")) {
selector = entry.getKey();
} else {
selector = entry.getValue();
}
if ((opEquals && selector.equals(operand)) || (!opEquals && !selector.equals(operand))) {
iterator.remove();
}
}
});
} else {
String value = fetchedYamlObject.get(key).toString();
boolean remove = (operand.equals(value) && opEquals) || (!operand.equals(value) && !opEquals);
if (remove) {
fetchedYamlObject.union.when(Map.class, m -> m.remove(key));
}
}
}
public void forEach(Consumer<YamlObject> consumer) {
union.when(List.class, list -> list.forEach(item -> consumer.accept(YamlObject.of(item))));
}
@Override
public String toString() {
return union.map(String.class, m -> m).orElse(super.toString());
}
}

View file

@ -0,0 +1,34 @@
package nl.sander;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class UnionTest {
@Test
public void testGet() {
Union stringIntegerUnion = new Union(String.class, Integer.class, Long.class);
stringIntegerUnion.set("2");
assertEquals("2", stringIntegerUnion.get());
}
@Test
public void testGet2() {
Union stringIntegerUnion = new Union(String.class, Integer.class, Long.class);
stringIntegerUnion.set(1);
int value = stringIntegerUnion.get();
assertEquals(1, value);
}
@Test
public void testMap() {
Union union = new Union(String.class, Integer.class);
union.set(1);
StringBuilder result = new StringBuilder();
union.when(Integer.class, v -> result.append("int ").append(v));
union.when(String.class, v -> result.append("string ").append(v));
assertEquals("int 1", result.toString());
}
}

View file

@ -0,0 +1,127 @@
package nl.sander;
import org.junit.jupiter.api.Test;
import java.util.HashMap;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class YamlObjectTest {
@Test
public void testSimpleRemove() {
Map<Object, Object> mapValue = new HashMap<>();
mapValue.put("app", "simple");
mapValue.put("app.name", "noname");
YamlObject yamlObject = YamlObject.of(mapValue);
yamlObject.remove("app.name");
assertEquals(1, mapValue.size());
assertTrue(mapValue.containsKey("app"));
}
@Test
public void testRemoveIf_notremoved() {
Map<Object, Object> mapValue = new HashMap<>();
mapValue.put("app", "simple");
mapValue.put("app.name", "noname");
YamlObject yamlObject = YamlObject.of(mapValue);
yamlObject.removeIf("app.name == somename");
assertEquals(2, mapValue.size());
assertTrue(mapValue.containsKey("app"));
assertTrue(mapValue.containsKey("app.name"));
}
@Test
public void testRemoveIf_removed() {
Map<Object, Object> mapValue = new HashMap<>();
mapValue.put("app", "simple");
mapValue.put("app.name", "noname");
YamlObject yamlObject = YamlObject.of(mapValue);
yamlObject.removeIf("app.name == noname");
assertEquals(1, mapValue.size());
assertTrue(mapValue.containsKey("app"));
}
@Test
public void testRemoveIf_lookForKey() {
Map<Object, Object> mapValue = new HashMap<>();
mapValue.put("app", "simple");
mapValue.put("app.name", "noname");
YamlObject yamlObject = YamlObject.of(mapValue);
yamlObject.removeIf("_key==app.name");
assertEquals(1, mapValue.size());
assertTrue(mapValue.containsKey("app"));
}
@Test
public void testRemoveIf_lookForKey_negative() {
Map<Object, Object> mapValue = new HashMap<>();
mapValue.put("app", "simple");
mapValue.put("app.name", "noname");
YamlObject yamlObject = YamlObject.of(mapValue);
yamlObject.removeIf("_key!=app");
assertEquals(1, mapValue.size());
assertTrue(mapValue.containsKey("app"));
}
@Test
public void testRemoveIf_lookForValue() {
Map<Object, Object> mapValue = new HashMap<>();
mapValue.put("app", "simple");
mapValue.put("app.name", "noname");
YamlObject yamlObject = YamlObject.of(mapValue);
yamlObject.removeIf("_value==noname");
assertEquals(1, mapValue.size());
assertTrue(mapValue.containsKey("app"));
}
@Test
public void testRemoveIf_lookForValue_negative() {
Map<Object, Object> mapValue = new HashMap<>();
mapValue.put("app", "simple");
mapValue.put("app.name", "noname");
YamlObject yamlObject = YamlObject.of(mapValue);
yamlObject.removeIf("_value != simple");
assertEquals(1, mapValue.size());
assertTrue(mapValue.containsKey("app"));
}
@Test
public void testCompoundRemove() {
Map<Object, Object> spec = new HashMap<>();
spec.put("app", "simple");
spec.put("app.name", "noname");
Map<Object, Object> item = new HashMap<>();
item.put("spec", spec);
YamlObject yamlObject = YamlObject.of(item);
yamlObject.remove("spec/app.name");
assertEquals(1, spec.size());
assertTrue(spec.containsKey("app"));
}
@Test
public void testCompoundRemoveIf_lookForValue_negative() {
Map<Object, Object> labels = new HashMap<>();
labels.put("app", "simple");
labels.put("app.name", "noname");
Map<Object, Object> item = new HashMap<>();
item.put("labels", labels);
YamlObject yamlObject = YamlObject.of(item);
yamlObject.removeIf("labels/_value != simple");
assertEquals(1, labels.size());
assertTrue(labels.containsKey("app"));
}
}

468
src/test/resources/dc.yaml Normal file
View file

@ -0,0 +1,468 @@
apiVersion: v1
items:
- apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
annotations:
openshift.io/generated-by: OpenShiftNewApp
creationTimestamp: "2021-07-07T13:42:16Z"
generation: 2
labels:
app: quotesapi
app.kubernetes.io/component: quotesapi
app.kubernetes.io/instance: quotesapi
managedFields:
- apiVersion: apps.openshift.io/v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.: {}
f:openshift.io/generated-by: {}
f:labels:
.: {}
f:app: {}
f:app.kubernetes.io/component: {}
f:app.kubernetes.io/instance: {}
f:spec:
f:replicas: {}
f:selector:
.: {}
f:deploymentconfig: {}
f:strategy:
f:activeDeadlineSeconds: {}
f:rollingParams:
.: {}
f:intervalSeconds: {}
f:maxSurge: {}
f:maxUnavailable: {}
f:timeoutSeconds: {}
f:updatePeriodSeconds: {}
f:type: {}
f:template:
.: {}
f:metadata:
.: {}
f:annotations:
.: {}
f:openshift.io/generated-by: {}
f:creationTimestamp: {}
f:labels:
.: {}
f:deploymentconfig: {}
f:spec:
.: {}
f:containers:
.: {}
k:{"name":"quotesapi"}:
.: {}
f:env:
.: {}
k:{"name":"DATABASE_NAME"}:
.: {}
f:name: {}
f:value: {}
k:{"name":"DATABASE_PASSWORD"}:
.: {}
f:name: {}
f:value: {}
k:{"name":"DATABASE_SERVICE_NAME"}:
.: {}
f:name: {}
f:value: {}
k:{"name":"DATABASE_USER"}:
.: {}
f:name: {}
f:value: {}
f:imagePullPolicy: {}
f:name: {}
f:ports:
.: {}
k:{"containerPort":8080,"protocol":"TCP"}:
.: {}
f:containerPort: {}
f:protocol: {}
k:{"containerPort":8443,"protocol":"TCP"}:
.: {}
f:containerPort: {}
f:protocol: {}
f:resources: {}
f:terminationMessagePath: {}
f:terminationMessagePolicy: {}
f:dnsPolicy: {}
f:restartPolicy: {}
f:schedulerName: {}
f:securityContext: {}
f:terminationGracePeriodSeconds: {}
manager: oc
operation: Update
time: "2021-07-07T13:42:16Z"
- apiVersion: apps.openshift.io/v1
fieldsType: FieldsV1
fieldsV1:
f:spec:
f:template:
f:spec:
f:containers:
k:{"name":"quotesapi"}:
f:image: {}
f:triggers: {}
f:status:
f:availableReplicas: {}
f:conditions:
.: {}
k:{"type":"Available"}:
.: {}
f:lastTransitionTime: {}
f:lastUpdateTime: {}
f:message: {}
f:status: {}
f:type: {}
k:{"type":"Progressing"}:
.: {}
f:lastTransitionTime: {}
f:lastUpdateTime: {}
f:message: {}
f:reason: {}
f:status: {}
f:type: {}
f:details:
.: {}
f:causes: {}
f:message: {}
f:latestVersion: {}
f:observedGeneration: {}
f:readyReplicas: {}
f:replicas: {}
f:unavailableReplicas: {}
f:updatedReplicas: {}
manager: openshift-controller-manager
operation: Update
time: "2021-07-07T13:42:57Z"
name: quotesapi
namespace: zqjsga-quotes-dev
resourceVersion: "80364062"
selfLink: /apis/apps.openshift.io/v1/namespaces/zqjsga-quotes-dev/deploymentconfigs/quotesapi
uid: 7f381c32-7b5b-4b5c-83ef-b0ec0bf4f35e
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
deploymentconfig: quotesapi
strategy:
activeDeadlineSeconds: 21600
resources: {}
rollingParams:
intervalSeconds: 1
maxSurge: 25%
maxUnavailable: 25%
timeoutSeconds: 600
updatePeriodSeconds: 1
type: Rolling
template:
metadata:
annotations:
openshift.io/generated-by: OpenShiftNewApp
creationTimestamp: null
labels:
deploymentconfig: quotesapi
spec:
containers:
- env:
- name: DATABASE_NAME
value: quotesdb
- name: DATABASE_PASSWORD
value: redhat
- name: DATABASE_SERVICE_NAME
value: quotesdb
- name: DATABASE_USER
value: quoteapp
image: image-registry.openshift-image-registry.svc:5000/zqjsga-quotes-dev/quotesapi@sha256:680b28722da34dc9a3749f9055877291d7613f576926b253626b8056db6934e9
imagePullPolicy: Always
name: quotesapi
ports:
- containerPort: 8080
protocol: TCP
- containerPort: 8443
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
test: false
triggers:
- type: ConfigChange
- imageChangeParams:
automatic: true
containerNames:
- quotesapi
from:
kind: ImageStreamTag
name: quotesapi:latest
namespace: zqjsga-quotes-dev
lastTriggeredImage: image-registry.openshift-image-registry.svc:5000/zqjsga-quotes-dev/quotesapi@sha256:680b28722da34dc9a3749f9055877291d7613f576926b253626b8056db6934e9
type: ImageChange
status:
availableReplicas: 1
conditions:
- lastTransitionTime: "2021-07-07T13:42:57Z"
lastUpdateTime: "2021-07-07T13:42:57Z"
message: Deployment config has minimum availability.
status: "True"
type: Available
- lastTransitionTime: "2021-07-07T13:42:54Z"
lastUpdateTime: "2021-07-07T13:42:57Z"
message: replication controller "quotesapi-1" successfully rolled out
reason: NewReplicationControllerAvailable
status: "True"
type: Progressing
details:
causes:
- type: ConfigChange
message: config change
latestVersion: 1
observedGeneration: 2
readyReplicas: 1
replicas: 1
unavailableReplicas: 0
updatedReplicas: 1
- apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
annotations:
openshift.io/generated-by: OpenShiftNewApp
creationTimestamp: "2021-07-07T13:42:06Z"
generation: 3
labels:
app: quotesdb
app.kubernetes.io/component: quotesdb
app.kubernetes.io/instance: quotesdb
app.kubernetes.io/name: mysql
managedFields:
- apiVersion: apps.openshift.io/v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.: {}
f:openshift.io/generated-by: {}
f:labels:
.: {}
f:app: {}
f:app.kubernetes.io/component: {}
f:app.kubernetes.io/instance: {}
f:app.kubernetes.io/name: {}
f:spec:
f:replicas: {}
f:selector:
.: {}
f:deploymentconfig: {}
f:strategy:
f:activeDeadlineSeconds: {}
f:rollingParams:
.: {}
f:intervalSeconds: {}
f:maxSurge: {}
f:maxUnavailable: {}
f:timeoutSeconds: {}
f:updatePeriodSeconds: {}
f:type: {}
f:template:
.: {}
f:metadata:
.: {}
f:annotations:
.: {}
f:openshift.io/generated-by: {}
f:creationTimestamp: {}
f:labels:
.: {}
f:deploymentconfig: {}
f:spec:
.: {}
f:containers:
.: {}
k:{"name":"quotesdb"}:
.: {}
f:env:
.: {}
k:{"name":"MYSQL_DATABASE"}:
.: {}
f:name: {}
f:value: {}
k:{"name":"MYSQL_PASSWORD"}:
.: {}
f:name: {}
f:value: {}
k:{"name":"MYSQL_USER"}:
.: {}
f:name: {}
f:value: {}
f:imagePullPolicy: {}
f:name: {}
f:ports:
.: {}
k:{"containerPort":3306,"protocol":"TCP"}:
.: {}
f:containerPort: {}
f:protocol: {}
f:resources: {}
f:terminationMessagePath: {}
f:terminationMessagePolicy: {}
f:dnsPolicy: {}
f:restartPolicy: {}
f:schedulerName: {}
f:securityContext: {}
f:terminationGracePeriodSeconds: {}
f:volumes:
.: {}
k:{"name":"quotesdb-volume-1"}:
.: {}
f:name: {}
f:persistentVolumeClaim:
.: {}
f:claimName: {}
manager: oc
operation: Update
time: "2021-07-07T13:42:07Z"
- apiVersion: apps.openshift.io/v1
fieldsType: FieldsV1
fieldsV1:
f:spec:
f:template:
f:spec:
f:containers:
k:{"name":"quotesdb"}:
f:image: {}
f:triggers: {}
f:status:
f:availableReplicas: {}
f:conditions:
.: {}
k:{"type":"Available"}:
.: {}
f:lastTransitionTime: {}
f:lastUpdateTime: {}
f:message: {}
f:status: {}
f:type: {}
k:{"type":"Progressing"}:
.: {}
f:lastTransitionTime: {}
f:lastUpdateTime: {}
f:message: {}
f:reason: {}
f:status: {}
f:type: {}
f:details:
.: {}
f:causes: {}
f:message: {}
f:latestVersion: {}
f:observedGeneration: {}
f:readyReplicas: {}
f:replicas: {}
f:unavailableReplicas: {}
f:updatedReplicas: {}
manager: openshift-controller-manager
operation: Update
time: "2021-07-07T13:42:15Z"
name: quotesdb
namespace: zqjsga-quotes-dev
resourceVersion: "80363661"
selfLink: /apis/apps.openshift.io/v1/namespaces/zqjsga-quotes-dev/deploymentconfigs/quotesdb
uid: 14d73674-2626-4f0f-ac65-683b72e62acd
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
deploymentconfig: quotesdb
strategy:
activeDeadlineSeconds: 21600
resources: {}
rollingParams:
intervalSeconds: 1
maxSurge: 25%
maxUnavailable: 25%
timeoutSeconds: 600
updatePeriodSeconds: 1
type: Rolling
template:
metadata:
annotations:
openshift.io/generated-by: OpenShiftNewApp
creationTimestamp: null
labels:
deploymentconfig: quotesdb
spec:
containers:
- env:
- name: MYSQL_DATABASE
value: quotesdb
- name: MYSQL_PASSWORD
value: redhat
- name: MYSQL_USER
value: quoteapp
image: image-registry.openshift-image-registry.svc:5000/openshift/mysql@sha256:9a781abe7581cc141e14a7e404ec34125b3e89c008b14f4e7b41e094fd3049fe
imagePullPolicy: IfNotPresent
name: quotesdb
ports:
- containerPort: 3306
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- name: quotesdb-volume-1
persistentVolumeClaim:
claimName: quotesdb-claim
test: false
triggers:
- type: ConfigChange
- imageChangeParams:
automatic: true
containerNames:
- quotesdb
from:
kind: ImageStreamTag
name: mysql:5.7
namespace: openshift
lastTriggeredImage: image-registry.openshift-image-registry.svc:5000/openshift/mysql@sha256:9a781abe7581cc141e14a7e404ec34125b3e89c008b14f4e7b41e094fd3049fe
type: ImageChange
status:
availableReplicas: 1
conditions:
- lastTransitionTime: "2021-07-07T13:42:14Z"
lastUpdateTime: "2021-07-07T13:42:14Z"
message: Deployment config has minimum availability.
status: "True"
type: Available
- lastTransitionTime: "2021-07-07T13:42:15Z"
lastUpdateTime: "2021-07-07T13:42:15Z"
message: replication controller "quotesdb-1" successfully rolled out
reason: NewReplicationControllerAvailable
status: "True"
type: Progressing
details:
causes:
- type: ConfigChange
message: config change
latestVersion: 1
observedGeneration: 3
readyReplicas: 1
replicas: 1
unavailableReplicas: 0
updatedReplicas: 1
kind: List
metadata:
resourceVersion: ""
selfLink: ""

View file

@ -0,0 +1,138 @@
---
apiVersion: "v1"
items:
- apiVersion: "apps.openshift.io/v1"
kind: "DeploymentConfig"
metadata:
annotations: {}
generation: 2
labels:
app: "quotesapi"
name: "quotesapi"
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
deploymentconfig: "quotesapi"
strategy:
activeDeadlineSeconds: 21600
resources: {}
rollingParams:
intervalSeconds: 1
maxSurge: "25%"
maxUnavailable: "25%"
timeoutSeconds: 600
updatePeriodSeconds: 1
type: "Rolling"
template:
metadata:
annotations: {}
labels:
deploymentconfig: "quotesapi"
spec:
containers:
- env:
- name: "DATABASE_NAME"
value: "quotesdb"
- name: "DATABASE_PASSWORD"
value: "redhat"
- name: "DATABASE_SERVICE_NAME"
value: "quotesdb"
- name: "DATABASE_USER"
value: "quoteapp"
imagePullPolicy: "Always"
name: "quotesapi"
ports:
- containerPort: 8080
protocol: "TCP"
- containerPort: 8443
protocol: "TCP"
resources: {}
terminationMessagePath: "/dev/termination-log"
terminationMessagePolicy: "File"
dnsPolicy: "ClusterFirst"
restartPolicy: "Always"
schedulerName: "default-scheduler"
securityContext: {}
terminationGracePeriodSeconds: 30
test: false
triggers:
- type: "ConfigChange"
- imageChangeParams:
automatic: true
containerNames:
- "quotesapi"
from:
kind: "ImageStreamTag"
name: "quotesapi:latest"
type: "ImageChange"
- apiVersion: "apps.openshift.io/v1"
kind: "DeploymentConfig"
metadata:
annotations: {}
generation: 3
labels:
app: "quotesdb"
name: "quotesdb"
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
deploymentconfig: "quotesdb"
strategy:
activeDeadlineSeconds: 21600
resources: {}
rollingParams:
intervalSeconds: 1
maxSurge: "25%"
maxUnavailable: "25%"
timeoutSeconds: 600
updatePeriodSeconds: 1
type: "Rolling"
template:
metadata:
annotations: {}
labels:
deploymentconfig: "quotesdb"
spec:
containers:
- env:
- name: "MYSQL_DATABASE"
value: "quotesdb"
- name: "MYSQL_PASSWORD"
value: "redhat"
- name: "MYSQL_USER"
value: "quoteapp"
imagePullPolicy: "IfNotPresent"
name: "quotesdb"
ports:
- containerPort: 3306
protocol: "TCP"
resources: {}
terminationMessagePath: "/dev/termination-log"
terminationMessagePolicy: "File"
dnsPolicy: "ClusterFirst"
restartPolicy: "Always"
schedulerName: "default-scheduler"
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- name: "quotesdb-volume-1"
persistentVolumeClaim:
claimName: "quotesdb-claim"
test: false
triggers:
- type: "ConfigChange"
- imageChangeParams:
automatic: true
containerNames:
- "quotesdb"
from:
kind: "ImageStreamTag"
name: "mysql:5.7"
namespace: "openshift"
type: "ImageChange"
kind: "List"
metadata:
resourceVersion: ""
selfLink: ""

View file

@ -0,0 +1,130 @@
---
apiVersion: "v1"
items:
- apiVersion: "apps.openshift.io/v1"
kind: "DeploymentConfig"
metadata:
labels:
app: "quotesapi"
name: "quotesapi"
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
deploymentconfig: "quotesapi"
strategy:
activeDeadlineSeconds: 21600
resources: {}
rollingParams:
intervalSeconds: 1
maxSurge: "25%"
maxUnavailable: "25%"
timeoutSeconds: 600
updatePeriodSeconds: 1
type: "Rolling"
template:
metadata:
annotations: {}
labels:
deploymentconfig: "quotesapi"
spec:
containers:
- env:
- name: "DATABASE_NAME"
value: "quotesdb"
- name: "DATABASE_PASSWORD"
value: "redhat"
- name: "DATABASE_SERVICE_NAME"
value: "quotesdb"
- name: "DATABASE_USER"
value: "quoteapp"
imagePullPolicy: "Always"
name: "quotesapi"
ports:
- containerPort: 8080
protocol: "TCP"
- containerPort: 8443
protocol: "TCP"
resources: {}
terminationMessagePath: "/dev/termination-log"
terminationMessagePolicy: "File"
dnsPolicy: "ClusterFirst"
restartPolicy: "Always"
schedulerName: "default-scheduler"
securityContext: {}
terminationGracePeriodSeconds: 30
test: false
triggers:
- type: "ConfigChange"
- imageChangeParams:
automatic: true
containerNames:
- "quotesapi"
from:
kind: "ImageStreamTag"
name: "quotesapi:latest"
type: "ImageChange"
- apiVersion: "apps.openshift.io/v1"
kind: "DeploymentConfig"
metadata:
labels:
app: "quotesdb"
name: "quotesdb"
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
deploymentconfig: "quotesdb"
strategy:
activeDeadlineSeconds: 21600
resources: {}
rollingParams:
intervalSeconds: 1
maxSurge: "25%"
maxUnavailable: "25%"
timeoutSeconds: 600
updatePeriodSeconds: 1
type: "Rolling"
template:
metadata:
annotations: {}
labels:
deploymentconfig: "quotesdb"
spec:
containers:
- env:
- name: "MYSQL_DATABASE"
value: "quotesdb"
- name: "MYSQL_PASSWORD"
value: "redhat"
- name: "MYSQL_USER"
value: "quoteapp"
imagePullPolicy: "IfNotPresent"
name: "quotesdb"
ports:
- containerPort: 3306
protocol: "TCP"
resources: {}
terminationMessagePath: "/dev/termination-log"
terminationMessagePolicy: "File"
dnsPolicy: "ClusterFirst"
restartPolicy: "Always"
schedulerName: "default-scheduler"
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- name: "quotesdb-volume-1"
persistentVolumeClaim:
claimName: "quotesdb-claim"
test: false
triggers:
- type: "ConfigChange"
- imageChangeParams:
automatic: true
containerNames:
- "quotesdb"
from:
kind: "ImageStreamTag"
name: "mysql:5.7"
namespace: "openshift"
type: "ImageChange"

View file

@ -0,0 +1,86 @@
apiVersion: v1
items:
- apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
annotations:
openshift.io/generated-by: OpenShiftNewApp
creationTimestamp: "2021-07-07T13:42:16Z"
generation: 1
labels:
app: quotesapi
app.kubernetes.io/component: quotesapi
app.kubernetes.io/instance: quotesapi
managedFields:
- apiVersion: image.openshift.io/v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.: {}
f:openshift.io/generated-by: {}
f:labels:
.: {}
f:app: {}
f:app.kubernetes.io/component: {}
f:app.kubernetes.io/instance: {}
manager: oc
operation: Update
time: "2021-07-07T13:42:16Z"
name: quotesapi
namespace: zqjsga-quotes-dev
resourceVersion: "80363950"
selfLink: /apis/image.openshift.io/v1/namespaces/zqjsga-quotes-dev/imagestreams/quotesapi
uid: 93275b73-9ccd-437d-8a7c-ab4c18824ea5
spec:
lookupPolicy:
local: false
status:
dockerImageRepository: image-registry.openshift-image-registry.svc:5000/zqjsga-quotes-dev/quotesapi
publicDockerImageRepository: default-route-openshift-image-registry.apps.eu45.prod.nextcle.com/zqjsga-quotes-dev/quotesapi
tags:
- items:
- created: "2021-07-07T13:42:50Z"
dockerImageReference: image-registry.openshift-image-registry.svc:5000/zqjsga-quotes-dev/quotesapi@sha256:680b28722da34dc9a3749f9055877291d7613f576926b253626b8056db6934e9
generation: 1
image: sha256:680b28722da34dc9a3749f9055877291d7613f576926b253626b8056db6934e9
tag: latest
- apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
annotations:
openshift.io/image.dockerRepositoryCheck: "2021-07-07T13:42:07Z"
creationTimestamp: "2021-07-07T13:42:06Z"
generation: 2
name: quotesdb
namespace: zqjsga-quotes-dev
resourceVersion: "80363561"
selfLink: /apis/image.openshift.io/v1/namespaces/zqjsga-quotes-dev/imagestreams/quotesdb
uid: 7d8a7e6a-4254-4e9b-bbbf-63244dbf9304
spec:
lookupPolicy:
local: false
tags:
- annotations: null
from:
kind: DockerImage
name: image-registry.openshift-image-registry.svc:5000/openshift/mysql:5.7
generation: 2
importPolicy: {}
name: "5.7"
referencePolicy:
type: Source
status:
dockerImageRepository: image-registry.openshift-image-registry.svc:5000/zqjsga-quotes-dev/quotesdb
publicDockerImageRepository: default-route-openshift-image-registry.apps.eu45.prod.nextcle.com/zqjsga-quotes-dev/quotesdb
tags:
- items:
- created: "2021-07-07T13:42:07Z"
dockerImageReference: image-registry.openshift-image-registry.svc:5000/openshift/mysql@sha256:9a781abe7581cc141e14a7e404ec34125b3e89c008b14f4e7b41e094fd3049fe
generation: 2
image: sha256:9a781abe7581cc141e14a7e404ec34125b3e89c008b14f4e7b41e094fd3049fe
tag: "5.7"
kind: List
metadata:
resourceVersion: ""
selfLink: ""

134
src/test/resources/svc.yaml Normal file
View file

@ -0,0 +1,134 @@
apiVersion: v1
items:
- apiVersion: v1
kind: Service
metadata:
annotations:
openshift.io/generated-by: OpenShiftNewApp
creationTimestamp: "2021-07-07T13:42:16Z"
labels:
app: quotesapi
app.kubernetes.io/component: quotesapi
app.kubernetes.io/instance: quotesapi
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.: {}
f:openshift.io/generated-by: {}
f:labels:
.: {}
f:app: {}
f:app.kubernetes.io/component: {}
f:app.kubernetes.io/instance: {}
f:spec:
f:ports:
.: {}
k:{"port":8080,"protocol":"TCP"}:
.: {}
f:name: {}
f:port: {}
f:protocol: {}
f:targetPort: {}
k:{"port":8443,"protocol":"TCP"}:
.: {}
f:name: {}
f:port: {}
f:protocol: {}
f:targetPort: {}
f:selector:
.: {}
f:deploymentconfig: {}
f:sessionAffinity: {}
f:type: {}
manager: oc
operation: Update
time: "2021-07-07T13:42:16Z"
name: quotesapi
namespace: zqjsga-quotes-dev
resourceVersion: "80363671"
selfLink: /api/v1/namespaces/zqjsga-quotes-dev/services/quotesapi
uid: 79787337-8ab1-4427-bca3-615ea74d8322
spec:
clusterIP: 172.30.129.174
ports:
- name: 8080-tcp
port: 8080
protocol: TCP
targetPort: 8080
- name: 8443-tcp
port: 8443
protocol: TCP
targetPort: 8443
selector:
deploymentconfig: quotesapi
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
- apiVersion: v1
kind: Service
metadata:
annotations:
openshift.io/generated-by: OpenShiftNewApp
creationTimestamp: "2021-07-07T13:42:06Z"
labels:
app: quotesdb
app.kubernetes.io/component: quotesdb
app.kubernetes.io/instance: quotesdb
app.kubernetes.io/name: mysql
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:metadata:
f:annotations:
.: {}
f:openshift.io/generated-by: {}
f:labels:
.: {}
f:app: {}
f:app.kubernetes.io/component: {}
f:app.kubernetes.io/instance: {}
f:app.kubernetes.io/name: {}
f:spec:
f:ports:
.: {}
k:{"port":3306,"protocol":"TCP"}:
.: {}
f:name: {}
f:port: {}
f:protocol: {}
f:targetPort: {}
f:selector:
.: {}
f:deploymentconfig: {}
f:sessionAffinity: {}
f:type: {}
manager: oc
operation: Update
time: "2021-07-07T13:42:06Z"
name: quotesdb
namespace: zqjsga-quotes-dev
resourceVersion: "80363551"
selfLink: /api/v1/namespaces/zqjsga-quotes-dev/services/quotesdb
uid: cf3fbd0a-aa1e-4f4e-b1c3-193713867475
spec:
clusterIP: 172.30.126.53
ports:
- name: 3306-tcp
port: 3306
protocol: TCP
targetPort: 3306
selector:
deploymentconfig: quotesdb
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
kind: List
metadata:
resourceVersion: ""
selfLink: ""