Skip to content

Commit 967bf19

Browse files
authored
Merge branch 'master' into wait
2 parents 7498c51 + bde7b96 commit 967bf19

File tree

9 files changed

+271
-80
lines changed

9 files changed

+271
-80
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* Fix #3225: Pod metric does not have corresponding label selector variant
1717
* Fix #3243: pipes provided to exec command are no longer closed on connection close, so that client can fully read the buffer after the command finishes.
1818
* Fix #3271: waitUntilReady and waitUntilCondition should handle resource too old
19+
* Fix #3272: prevent index npe after informer sees an empty list
1920

2021
#### Improvements
2122
* Fix #3078: adding javadocs to further clarify patch, edit, replace, etc. and note the possibility of items being modified.
@@ -50,6 +51,8 @@
5051
* Add DSL support for OpenShift Whereabouts CNI Model `whereabouts.cni.cncf.io` to OpenShiftClient DSL
5152
* Add DSL support for OpenShift Kube Storage Version Migrator resources in OpenShiftClient DSL
5253
* Fix #3228: Add support for Dynamic informers for custom resources in KubernetesClient
54+
* Add DSL support for ClusterInterceptors to TektonClient
55+
5356

5457
#### _**Note**_: Breaking changes in the API
5558
##### DSL Changes:

README.md

Lines changed: 59 additions & 59 deletions
Large diffs are not rendered by default.

extensions/tekton/client/src/main/java/io/fabric8/tekton/client/V1alpha1APIGroupClient.java

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,7 @@
2222
import io.fabric8.kubernetes.client.dsl.Resource;
2323
import io.fabric8.tekton.client.dsl.V1alpha1APIGroupDSL;
2424
import io.fabric8.tekton.client.internal.v1alpha1.*;
25-
import io.fabric8.tekton.pipeline.v1alpha1.ClusterTask;
26-
import io.fabric8.tekton.pipeline.v1alpha1.ClusterTaskList;
27-
import io.fabric8.tekton.pipeline.v1alpha1.Condition;
28-
import io.fabric8.tekton.pipeline.v1alpha1.ConditionList;
29-
import io.fabric8.tekton.pipeline.v1alpha1.Pipeline;
30-
import io.fabric8.tekton.pipeline.v1alpha1.PipelineList;
31-
import io.fabric8.tekton.pipeline.v1alpha1.PipelineRun;
32-
import io.fabric8.tekton.pipeline.v1alpha1.PipelineRunList;
33-
import io.fabric8.tekton.pipeline.v1alpha1.Task;
34-
import io.fabric8.tekton.pipeline.v1alpha1.TaskList;
35-
import io.fabric8.tekton.pipeline.v1alpha1.TaskRun;
36-
import io.fabric8.tekton.pipeline.v1alpha1.TaskRunList;
25+
import io.fabric8.tekton.pipeline.v1alpha1.*;
3726
import io.fabric8.tekton.resource.v1alpha1.PipelineResource;
3827
import io.fabric8.tekton.resource.v1alpha1.PipelineResourceList;
3928
import io.fabric8.tekton.triggers.v1alpha1.*;
@@ -107,4 +96,9 @@ public NonNamespaceOperation<ClusterTask, ClusterTaskList, Resource<ClusterTask>
10796
public NonNamespaceOperation<ClusterTriggerBinding, ClusterTriggerBindingList, Resource<ClusterTriggerBinding>> clusterTriggerBindings() {
10897
return new ClusterTriggerBindingOperationsImpl(this.getHttpClient(),this.getConfiguration());
10998
}
99+
100+
@Override
101+
public NonNamespaceOperation<ClusterInterceptor, ClusterInterceptorList, Resource<ClusterInterceptor>> clusterInterceptors() {
102+
return new ClusterInterceptorOperationsImpl(this.getHttpClient(), this.getConfiguration());
103+
}
110104
}

extensions/tekton/client/src/main/java/io/fabric8/tekton/client/dsl/V1alpha1APIGroupDSL.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,11 @@ public interface V1alpha1APIGroupDSL extends Client {
119119
* @return MixedOperation for ClusterTriggerBinding class
120120
*/
121121
NonNamespaceOperation<ClusterTriggerBinding, ClusterTriggerBindingList, Resource<ClusterTriggerBinding>> clusterTriggerBindings();
122+
123+
/**
124+
* API entrypoint for ClusterInterceptor(triggers.tekton.dev/v1alpha1)
125+
*
126+
* @return MixedOperation for ClusterInterceptor class
127+
*/
128+
NonNamespaceOperation<ClusterInterceptor, ClusterInterceptorList, Resource<ClusterInterceptor>> clusterInterceptors();
122129
}

extensions/tekton/generator-triggers/cmd/generate/generate.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ func main() {
3535
reflect.TypeOf(triggers.TriggerBindingList{}): schemagen.Namespaced,
3636
reflect.TypeOf(triggers.EventListenerList{}): schemagen.Namespaced,
3737
reflect.TypeOf(triggers.ClusterTriggerBindingList{}): schemagen.Cluster,
38+
reflect.TypeOf(triggers.ClusterInterceptorList{}): schemagen.Cluster,
3839
}
3940

4041
// constraints and patterns for fields

extensions/tekton/model-triggers/src/main/java/io/fabric8/tekton/TektonTriggersResourceMappingProvider.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public TektonTriggersResourceMappingProvider() {
3131
mappings.put("triggers.tekton.dev/v1alpha1#EventListener", io.fabric8.tekton.triggers.v1alpha1.EventListener.class);
3232
mappings.put("triggers.tekton.dev/v1alpha1#ClusterTriggerBinding", io.fabric8.tekton.triggers.v1alpha1.ClusterTriggerBinding.class);
3333
mappings.put("triggers.tekton.dev/v1alpha1#Trigger", io.fabric8.tekton.triggers.v1alpha1.Trigger.class);
34+
mappings.put("triggers.tekton.dev/v1alpha1#ClusterInterceptor", io.fabric8.tekton.triggers.v1alpha1.ClusterInterceptor.class);
3435
}
3536

3637
public Map<String, Class<? extends KubernetesResource>> getMappings() {

extensions/tekton/model-triggers/src/main/resources/schema/tekton-schema-triggers.json

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,124 @@
5757
"io.fabric8.kubernetes.api.model.KubernetesResource"
5858
]
5959
},
60+
"github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ClientConfig": {
61+
"type": "object",
62+
"properties": {
63+
"service": {
64+
"$ref": "#/definitions/github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ServiceReference",
65+
"existingJavaType": "io.fabric8.tekton.triggers.v1alpha1.ServiceReference"
66+
},
67+
"url": {
68+
"existingJavaType": "java.lang.String"
69+
}
70+
},
71+
"javaType": "io.fabric8.tekton.triggers.v1alpha1.ClientConfig",
72+
"javaInterfaces": [
73+
"io.fabric8.kubernetes.api.model.KubernetesResource"
74+
]
75+
},
76+
"github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ClusterInterceptor": {
77+
"type": "object",
78+
"properties": {
79+
"apiVersion": {
80+
"type": "string",
81+
"default": "triggers.tekton.dev/v1alpha1",
82+
"required": true
83+
},
84+
"kind": {
85+
"type": "string",
86+
"default": "ClusterInterceptor",
87+
"required": true
88+
},
89+
"metadata": {
90+
"existingJavaType": "io.fabric8.kubernetes.api.model.ObjectMeta"
91+
},
92+
"spec": {
93+
"$ref": "#/definitions/github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ClusterInterceptorSpec",
94+
"existingJavaType": "io.fabric8.tekton.triggers.v1alpha1.ClusterInterceptorSpec"
95+
},
96+
"status": {
97+
"$ref": "#/definitions/github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ClusterInterceptorStatus",
98+
"existingJavaType": "io.fabric8.tekton.triggers.v1alpha1.ClusterInterceptorStatus"
99+
}
100+
},
101+
"javaType": "io.fabric8.tekton.triggers.v1alpha1.ClusterInterceptor",
102+
"javaInterfaces": [
103+
"io.fabric8.kubernetes.api.model.HasMetadata"
104+
]
105+
},
106+
"github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ClusterInterceptorList": {
107+
"type": "object",
108+
"properties": {
109+
"apiVersion": {
110+
"type": "string",
111+
"default": "triggers.tekton.dev/v1alpha1",
112+
"required": true
113+
},
114+
"items": {
115+
"type": "array",
116+
"items": {
117+
"$ref": "#/definitions/github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ClusterInterceptor",
118+
"existingJavaType": "io.fabric8.tekton.triggers.v1alpha1.ClusterInterceptor"
119+
}
120+
},
121+
"kind": {
122+
"type": "string",
123+
"default": "ClusterInterceptorList",
124+
"required": true
125+
},
126+
"metadata": {
127+
"existingJavaType": "io.fabric8.kubernetes.api.model.ListMeta"
128+
}
129+
},
130+
"javaType": "io.fabric8.tekton.triggers.v1alpha1.ClusterInterceptorList",
131+
"javaInterfaces": [
132+
"io.fabric8.kubernetes.api.model.KubernetesResource",
133+
"io.fabric8.kubernetes.api.model.KubernetesResourceList\u003cio.fabric8.tekton.triggers.v1alpha1.ClusterInterceptor\u003e"
134+
]
135+
},
136+
"github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ClusterInterceptorSpec": {
137+
"type": "object",
138+
"properties": {
139+
"clientConfig": {
140+
"$ref": "#/definitions/github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ClientConfig",
141+
"existingJavaType": "io.fabric8.tekton.triggers.v1alpha1.ClientConfig"
142+
}
143+
},
144+
"javaType": "io.fabric8.tekton.triggers.v1alpha1.ClusterInterceptorSpec",
145+
"javaInterfaces": [
146+
"io.fabric8.kubernetes.api.model.KubernetesResource"
147+
]
148+
},
149+
"github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ClusterInterceptorStatus": {
150+
"type": "object",
151+
"properties": {
152+
"address": {
153+
"$ref": "#/definitions/knative_dev_pkg_apis_duck_v1_Addressable",
154+
"existingJavaType": "io.fabric8.tekton.triggers.internal.knative.pkg.apis.duck.v1.Addressable"
155+
},
156+
"annotations": {
157+
"type": "object",
158+
"existingJavaType": "java.util.Map\u003cString,String\u003e"
159+
},
160+
"conditions": {
161+
"type": "array",
162+
"javaOmitEmpty": true,
163+
"items": {
164+
"$ref": "#/definitions/knative_dev_pkg_apis_Condition",
165+
"existingJavaType": "io.fabric8.tekton.triggers.internal.knative.pkg.apis.Condition"
166+
}
167+
},
168+
"observedGeneration": {
169+
"type": "integer",
170+
"existingJavaType": "Long"
171+
}
172+
},
173+
"javaType": "io.fabric8.tekton.triggers.v1alpha1.ClusterInterceptorStatus",
174+
"javaInterfaces": [
175+
"io.fabric8.kubernetes.api.model.KubernetesResource"
176+
]
177+
},
60178
"github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ClusterTriggerBinding": {
61179
"type": "object",
62180
"properties": {
@@ -496,6 +614,28 @@
496614
"io.fabric8.kubernetes.api.model.KubernetesResource"
497615
]
498616
},
617+
"github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ServiceReference": {
618+
"type": "object",
619+
"properties": {
620+
"name": {
621+
"type": "string"
622+
},
623+
"namespace": {
624+
"type": "string"
625+
},
626+
"path": {
627+
"type": "string"
628+
},
629+
"port": {
630+
"type": "integer",
631+
"existingJavaType": "Integer"
632+
}
633+
},
634+
"javaType": "io.fabric8.tekton.triggers.v1alpha1.ServiceReference",
635+
"javaInterfaces": [
636+
"io.fabric8.kubernetes.api.model.KubernetesResource"
637+
]
638+
},
499639
"github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_Trigger": {
500640
"type": "object",
501641
"properties": {
@@ -908,6 +1048,18 @@
9081048
"io.fabric8.kubernetes.api.model.KubernetesResource"
9091049
]
9101050
},
1051+
"knative_dev_pkg_apis_duck_v1_Addressable": {
1052+
"type": "object",
1053+
"properties": {
1054+
"url": {
1055+
"existingJavaType": "java.lang.String"
1056+
}
1057+
},
1058+
"javaType": "io.fabric8.tekton.triggers.internal.knative.pkg.apis.duck.v1.Addressable",
1059+
"javaInterfaces": [
1060+
"io.fabric8.kubernetes.api.model.KubernetesResource"
1061+
]
1062+
},
9111063
"knative_dev_pkg_apis_duck_v1_PodSpecable": {
9121064
"type": "object",
9131065
"properties": {
@@ -966,6 +1118,26 @@
9661118
"$ref": "#/definitions/github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_CELOverlay",
9671119
"existingJavaType": "io.fabric8.tekton.triggers.v1alpha1.CELOverlay"
9681120
},
1121+
"github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ClientConfig": {
1122+
"$ref": "#/definitions/github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ClientConfig",
1123+
"existingJavaType": "io.fabric8.tekton.triggers.v1alpha1.ClientConfig"
1124+
},
1125+
"github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ClusterInterceptor": {
1126+
"$ref": "#/definitions/github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ClusterInterceptor",
1127+
"existingJavaType": "io.fabric8.tekton.triggers.v1alpha1.ClusterInterceptor"
1128+
},
1129+
"github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ClusterInterceptorList": {
1130+
"$ref": "#/definitions/github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ClusterInterceptorList",
1131+
"existingJavaType": "io.fabric8.tekton.triggers.v1alpha1.ClusterInterceptorList"
1132+
},
1133+
"github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ClusterInterceptorSpec": {
1134+
"$ref": "#/definitions/github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ClusterInterceptorSpec",
1135+
"existingJavaType": "io.fabric8.tekton.triggers.v1alpha1.ClusterInterceptorSpec"
1136+
},
1137+
"github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ClusterInterceptorStatus": {
1138+
"$ref": "#/definitions/github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ClusterInterceptorStatus",
1139+
"existingJavaType": "io.fabric8.tekton.triggers.v1alpha1.ClusterInterceptorStatus"
1140+
},
9691141
"github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ClusterTriggerBinding": {
9701142
"$ref": "#/definitions/github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ClusterTriggerBinding",
9711143
"existingJavaType": "io.fabric8.tekton.triggers.v1alpha1.ClusterTriggerBinding"
@@ -1042,6 +1214,10 @@
10421214
"$ref": "#/definitions/github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_SecretRef",
10431215
"existingJavaType": "io.fabric8.tekton.triggers.v1alpha1.SecretRef"
10441216
},
1217+
"github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ServiceReference": {
1218+
"$ref": "#/definitions/github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_ServiceReference",
1219+
"existingJavaType": "io.fabric8.tekton.triggers.v1alpha1.ServiceReference"
1220+
},
10451221
"github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_Trigger": {
10461222
"$ref": "#/definitions/github_com_tektoncd_triggers_pkg_apis_triggers_v1alpha1_Trigger",
10471223
"existingJavaType": "io.fabric8.tekton.triggers.v1alpha1.Trigger"
@@ -1106,6 +1282,10 @@
11061282
"$ref": "#/definitions/knative_dev_pkg_apis_Condition",
11071283
"existingJavaType": "io.fabric8.tekton.triggers.internal.knative.pkg.apis.Condition"
11081284
},
1285+
"knative_dev_pkg_apis_duck_v1_Addressable": {
1286+
"$ref": "#/definitions/knative_dev_pkg_apis_duck_v1_Addressable",
1287+
"existingJavaType": "io.fabric8.tekton.triggers.internal.knative.pkg.apis.duck.v1.Addressable"
1288+
},
11091289
"knative_dev_pkg_apis_duck_v1_PodSpecable": {
11101290
"$ref": "#/definitions/knative_dev_pkg_apis_duck_v1_PodSpecable",
11111291
"existingJavaType": "io.fabric8.tekton.triggers.internal.knative.pkg.apis.duck.v1.PodSpecable"

kubernetes-client/src/main/java/io/fabric8/kubernetes/client/informers/cache/Cache.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,13 @@ public class Cache<T> implements Indexer<T> {
4444
public static final String NAMESPACE_INDEX = "namespace";
4545

4646
// indexers stores index functions by their names
47-
private Map<String, Function<T, List<String>>> indexers = new HashMap<>();
47+
private final Map<String, Function<T, List<String>>> indexers = new HashMap<>();
4848

4949
// items stores object instances
5050
private volatile ConcurrentHashMap<String, T> items = new ConcurrentHashMap<>();
5151

5252
// indices stores objects' key by their indices
53-
private Map<String, Map<String, Set<String>>> indices = new HashMap<>();
53+
private final Map<String, Map<String, Set<String>>> indices = new HashMap<>();
5454

5555
private BooleanSupplier isRunning = () -> false;
5656

@@ -74,12 +74,12 @@ public void setIsRunning(BooleanSupplier isRunning) {
7474
* @return registered indexers
7575
*/
7676
@Override
77-
public Map<String, Function<T, List<String>>> getIndexers() {
78-
return indexers;
77+
public synchronized Map<String, Function<T, List<String>>> getIndexers() {
78+
return Collections.unmodifiableMap(indexers);
7979
}
8080

8181
@Override
82-
public void addIndexers(Map<String, Function<T, List<String>>> indexersNew) {
82+
public synchronized void addIndexers(Map<String, Function<T, List<String>>> indexersNew) {
8383
if (isRunning.getAsBoolean()) {
8484
throw new IllegalStateException("Cannot add indexers to a running informer.");
8585
}
@@ -147,7 +147,7 @@ public synchronized Map<String, T> replace(List<T> list) {
147147
this.items = newItems;
148148

149149
// rebuild any index
150-
this.indices = new HashMap<>();
150+
this.indices.values().stream().forEach(Map::clear);
151151
for (Map.Entry<String, T> itemEntry : items.entrySet()) {
152152
this.updateIndices(null, itemEntry.getValue(), itemEntry.getKey());
153153
}
@@ -294,7 +294,7 @@ public synchronized List<T> byIndex(String indexName, String indexKey) {
294294
* @param newObj new object
295295
* @param key the key
296296
*/
297-
public void updateIndices(T oldObj, T newObj, String key) {
297+
void updateIndices(T oldObj, T newObj, String key) {
298298
if (oldObj != null) {
299299
deleteFromIndices(oldObj, key);
300300
}
@@ -307,7 +307,7 @@ public void updateIndices(T oldObj, T newObj, String key) {
307307
continue;
308308
}
309309

310-
Map<String, Set<String>> index = this.indices.computeIfAbsent(indexName, k -> new HashMap<>());
310+
Map<String, Set<String>> index = this.indices.get(indexName);
311311
for (String indexValue : indexValues) {
312312
Set<String> indexSet = index.computeIfAbsent(indexValue, k -> new HashSet<>());
313313
indexSet.add(key);
@@ -350,7 +350,7 @@ private void deleteFromIndices(T oldObj, String key) {
350350
* @param indexName the index name
351351
* @param indexFunc the index func
352352
*/
353-
public void addIndexFunc(String indexName, Function<T, List<String>> indexFunc) {
353+
public synchronized void addIndexFunc(String indexName, Function<T, List<String>> indexFunc) {
354354
this.indices.put(indexName, new HashMap<>());
355355
this.indexers.put(indexName, indexFunc);
356356
}

kubernetes-client/src/test/java/io/fabric8/kubernetes/client/informers/cache/CacheTest.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@
2020
import org.junit.jupiter.api.Test;
2121

2222
import java.util.Arrays;
23+
import java.util.Collections;
2324
import java.util.HashMap;
2425
import java.util.List;
2526
import java.util.Map;
2627
import java.util.function.Function;
2728

2829
import static org.junit.jupiter.api.Assertions.assertEquals;
30+
import static org.junit.jupiter.api.Assertions.assertNull;
2931

3032
class CacheTest {
3133
private static Cache cache = new Cache("mock", CacheTest::mockIndexFunction, CacheTest::mockKeyFunction);
@@ -49,6 +51,9 @@ void testCacheIndex() {
4951
List<String> allExistingKeys = cache.listKeys();
5052
assertEquals(1, allExistingKeys.size());
5153
assertEquals(key, allExistingKeys.get(0));
54+
55+
cache.replace(Collections.emptyList());
56+
assertEquals(0, cache.byIndex("mock", "y").size());
5257
}
5358

5459
@Test

0 commit comments

Comments
 (0)