Skip to content

Commit bf0fb2a

Browse files
committed
fix: have service selectors match templates, too (#882)
Signed-off-by: Andre Dietisheim <adietish@redhat.com>
1 parent 73b051c commit bf0fb2a

File tree

6 files changed

+253
-55
lines changed

6 files changed

+253
-55
lines changed

src/main/kotlin/com/redhat/devtools/intellij/kubernetes/editor/util/KubernetesTypeInfoUtils.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ private const val KIND_PERSISTENT_VOLUME = "PersistentVolume"
2121
private const val KIND_PERSISTENT_VOLUME_CLAIM = "PersistentVolumeClaim"
2222
private const val KIND_POD = "Pod"
2323
private const val KIND_POD_DISRUPTION_BUDGET = "PodDisruptionBudget"
24+
private const val KIND_REPLICATION_CONTROLLER = "ReplicationController"
2425
private const val KIND_REPLICA_SET = "ReplicaSet"
2526
private const val KIND_SERVICE = "Service"
2627
private const val KIND_STATEFUL_SET = "StatefulSet"
@@ -61,6 +62,10 @@ fun KubernetesTypeInfo.isPodDisruptionBudget(): Boolean {
6162
return this.kind == KIND_POD_DISRUPTION_BUDGET
6263
}
6364

65+
fun KubernetesTypeInfo.isReplicationController(): Boolean {
66+
return this.kind == KIND_REPLICATION_CONTROLLER
67+
}
68+
6469
fun KubernetesTypeInfo.isReplicaSet(): Boolean {
6570
return this.kind == KIND_REPLICA_SET
6671
}

src/main/kotlin/com/redhat/devtools/intellij/kubernetes/editor/util/ResourcePsiElementUtils.kt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ private const val KEY_LABELS = "labels"
2929
private const val KEY_SPEC = "spec"
3030
private const val KEY_SELECTOR = "selector"
3131
private const val KEY_TEMPLATE = "template"
32+
private const val KEY_JOB_TEMPLATE = "jobTemplate"
3233
private const val KEY_BINARY_DATA = "binaryData"
3334
private const val KEY_DATA = "data"
3435

@@ -210,6 +211,7 @@ fun JsonObject.getTemplate(): JsonObject? {
210211
return (this.findProperty(KEY_SPEC)?.value as? JsonObject?)
211212
?.findProperty(KEY_TEMPLATE)?.value as? JsonObject?
212213
}
214+
213215
fun PsiElement.hasTemplateLabels(): Boolean {
214216
return this.getTemplateLabels() != null
215217
}
@@ -223,12 +225,33 @@ fun PsiElement.getTemplateLabels(): PsiElement? {
223225
}
224226
}
225227

228+
fun PsiElement.getJobTemplate(): PsiElement? {
229+
return when(this) {
230+
is YAMLMapping -> this.getJobTemplate()
231+
is JsonObject -> this.getJobTemplate()
232+
else ->
233+
null
234+
}
235+
}
236+
237+
fun YAMLMapping.getJobTemplate(): YAMLMapping? {
238+
return (this.getKeyValueByKey(KEY_SPEC)?.value as? YAMLMapping)
239+
?.getKeyValueByKey(KEY_JOB_TEMPLATE)?.value as? YAMLMapping
240+
}
241+
242+
fun JsonObject.getJobTemplate(): JsonObject? {
243+
return (this.findProperty(KEY_SPEC)?.value as? JsonObject?)
244+
?.findProperty(KEY_JOB_TEMPLATE)?.value as? JsonObject?
245+
}
246+
226247
fun YAMLMapping.getTemplateLabels(): YAMLMapping? {
227248
return this.getTemplate()?.getLabels()
249+
?: getJobTemplate()?.getTemplate()?.getLabels()
228250
}
229251

230252
fun JsonObject.getTemplateLabels(): JsonObject? {
231253
return this.getTemplate()?.getLabels()
254+
?: getJobTemplate()?.getTemplate()?.getLabels()
232255
}
233256

234257
/**

src/main/kotlin/com/redhat/devtools/intellij/kubernetes/usage/LabelsFilter.kt

Lines changed: 26 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,15 @@ import com.intellij.psi.PsiElement
1414
import com.redhat.devtools.intellij.common.validation.KubernetesTypeInfo
1515
import com.redhat.devtools.intellij.kubernetes.editor.util.areMatchingMatchExpressions
1616
import com.redhat.devtools.intellij.kubernetes.editor.util.areMatchingMatchLabels
17+
import com.redhat.devtools.intellij.kubernetes.editor.util.getJobTemplate
1718
import com.redhat.devtools.intellij.kubernetes.editor.util.getKubernetesTypeInfo
1819
import com.redhat.devtools.intellij.kubernetes.editor.util.getLabels
1920
import com.redhat.devtools.intellij.kubernetes.editor.util.getResource
2021
import com.redhat.devtools.intellij.kubernetes.editor.util.getTemplateLabels
2122
import com.redhat.devtools.intellij.kubernetes.editor.util.hasMatchExpressions
2223
import com.redhat.devtools.intellij.kubernetes.editor.util.hasMatchLabels
2324
import com.redhat.devtools.intellij.kubernetes.editor.util.hasSelector
25+
import com.redhat.devtools.intellij.kubernetes.editor.util.hasTemplateLabels
2426
import com.redhat.devtools.intellij.kubernetes.editor.util.isCronJob
2527
import com.redhat.devtools.intellij.kubernetes.editor.util.isDaemonSet
2628
import com.redhat.devtools.intellij.kubernetes.editor.util.isDeployment
@@ -31,6 +33,7 @@ import com.redhat.devtools.intellij.kubernetes.editor.util.isPersistentVolumeCla
3133
import com.redhat.devtools.intellij.kubernetes.editor.util.isPod
3234
import com.redhat.devtools.intellij.kubernetes.editor.util.isPodDisruptionBudget
3335
import com.redhat.devtools.intellij.kubernetes.editor.util.isReplicaSet
36+
import com.redhat.devtools.intellij.kubernetes.editor.util.isReplicationController
3437
import com.redhat.devtools.intellij.kubernetes.editor.util.isService
3538
import com.redhat.devtools.intellij.kubernetes.editor.util.isStatefulSet
3639

@@ -90,64 +93,53 @@ class LabelsFilter(selector: PsiElement): PsiElementMappingsFilter {
9093
private fun canSelect(type: KubernetesTypeInfo): Boolean {
9194
val selectorType = selectorResourceType ?: return false
9295
return when {
93-
selectorType.isDeployment() ->
94-
type.isPod()
95-
|| type.isDeployment() // can select deployment template
96-
97-
selectorType.isCronJob() ->
98-
type.isPod()
99-
|| type.isCronJob() // template
100-
101-
selectorType.isDaemonSet() ->
102-
type.isPod()
103-
|| type.isDaemonSet() // template
104-
105-
selectorType.isJob() ->
106-
type.isPod()
107-
|| type.isJob() // template
108-
109-
selectorType.isReplicaSet() ->
110-
type.isPod()
111-
|| type.isReplicaSet() // template
112-
113-
selectorType.isStatefulSet() ->
114-
type.isPod()
115-
|| type.isStatefulSet() // template
116-
117-
selectorType.isNetworkPolicy()
96+
selectorType.isDaemonSet()
97+
|| selectorType.isDeployment()
98+
|| selectorType.isJob()
99+
|| selectorType.isNetworkPolicy()
118100
|| selectorType.isPodDisruptionBudget()
119-
|| selectorType.isService() ->
101+
|| selectorType.isReplicaSet()
102+
|| selectorType.isReplicationController()
103+
|| selectorType.isService()
104+
|| selectorType.isStatefulSet() ->
120105
type.isPod()
106+
|| hasPodTemplate(type)
121107

122108
selectorType.isPersistentVolumeClaim() ->
123109
type.isPersistentVolume()
124-
|| type.isPersistentVolumeClaim()
125110

126111
else ->
127112
false
128113
}
129114
}
130115

116+
private fun hasPodTemplate(type: KubernetesTypeInfo): Boolean {
117+
return type.isCronJob()
118+
|| type.isDaemonSet()
119+
|| type.isDeployment()
120+
|| type.isJob()
121+
|| type.isReplicaSet()
122+
|| type.isStatefulSet()
123+
}
124+
131125
override fun getMatchingElement(element: PsiElement): PsiElement? {
132126
val labeledType = element.getKubernetesTypeInfo() ?: return null
133127
return getLabels(labeledType, element, selectorResourceType)
134128
}
135129

136130
private fun getLabels(
137-
labeledType: KubernetesTypeInfo,
131+
labeledResourceType: KubernetesTypeInfo,
138132
labeledResource: PsiElement,
139133
selectorResourceType: KubernetesTypeInfo?
140134
): PsiElement? {
141135
return when {
142136
selectorResourceType == null ->
143137
null
144138

145-
(selectorResourceType.isCronJob() && labeledType.isCronJob())
146-
|| (selectorResourceType.isDaemonSet() && labeledType.isDaemonSet())
147-
|| (selectorResourceType.isDeployment() && labeledType.isDeployment())
148-
|| (selectorResourceType.isJob() && labeledType.isJob())
149-
|| (selectorResourceType.isReplicaSet() && labeledType.isReplicaSet())
150-
|| (selectorResourceType.isStatefulSet() && labeledType.isStatefulSet()) ->
139+
labeledResourceType.isCronJob() ->
140+
labeledResource.getJobTemplate()?.getTemplateLabels()
141+
142+
labeledResource.hasTemplateLabels() ->
151143
labeledResource.getTemplateLabels()
152144

153145
else ->

src/test/kotlin/com/redhat/devtools/intellij/kubernetes/editor/mocks/ResourcePsiElementMocks.kt

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ private const val KEY_METADATA = "metadata"
3535
private const val KEY_SELECTOR = "selector"
3636
private const val KEY_SPEC = "spec"
3737
private const val KEY_TEMPLATE = "template"
38+
private const val KEY_JOB_TEMPLATE = "jobTemplate"
3839

3940
fun YAMLMapping.createLabels(labelsChildren: YAMLMapping): YAMLKeyValue {
4041
val metadataChildren = mock<YAMLMapping>()
@@ -54,23 +55,25 @@ fun JsonObject.createLabels(labelsChildren: JsonObject): JsonProperty {
5455
}
5556

5657
fun YAMLMapping.createTemplate(templateChildren: YAMLMapping): YAMLKeyValue {
57-
var spec = getKeyValueByKey(KEY_SPEC)
58-
if (spec == null) {
59-
val specMapping = mock<YAMLMapping>()
60-
spec = createYAMLKeyValue(KEY_SPEC, specMapping, this)
61-
}
58+
val spec = getOrCreateSpec()
6259
return createYAMLKeyValue(KEY_TEMPLATE, templateChildren, spec.value as YAMLMapping)
6360
}
6461

6562
fun JsonObject.createTemplate(templateChildren: JsonObject): JsonProperty {
66-
var spec = findProperty(KEY_SPEC)
67-
if (spec == null) {
68-
val specMapping = mock<JsonObject>()
69-
spec = createJsonProperty(KEY_SPEC, specMapping, this)
70-
}
63+
val spec = getOrCreateSpec()
7164
return createJsonProperty(KEY_TEMPLATE, templateChildren, spec.value as JsonObject)
7265
}
7366

67+
fun YAMLMapping.createJobTemplate(templateChildren: YAMLMapping): YAMLKeyValue {
68+
val spec = getOrCreateSpec()
69+
return createYAMLKeyValue(KEY_JOB_TEMPLATE, templateChildren, spec.value as YAMLMapping)
70+
}
71+
72+
fun JsonObject.createJobTemplate(templateChildren: JsonObject): JsonProperty {
73+
val spec = getOrCreateSpec()
74+
return createJsonProperty(KEY_JOB_TEMPLATE, templateChildren, spec.value as JsonObject)
75+
}
76+
7477
fun YAMLMapping.createMatchLabels(matchLabels: YAMLMapping): YAMLKeyValue {
7578
var selectorChildren = getSelector()
7679
if (selectorChildren == null) {
@@ -119,21 +122,32 @@ fun createYAMLSequenceItem(key: String, operator: String, values: List<String>):
119122
}
120123

121124
fun YAMLMapping.createSelector(selectorChildren: YAMLMapping = mock()): YAMLKeyValue {
125+
val spec = getOrCreateSpec()
126+
return createYAMLKeyValue(KEY_SELECTOR, selectorChildren, spec.value as YAMLMapping)
127+
}
128+
129+
private fun YAMLMapping.getOrCreateSpec(): YAMLKeyValue {
122130
var spec = getKeyValueByKey(KEY_SPEC)
123131
if (spec == null) {
124132
val specChildren = mock<YAMLMapping>()
125133
spec = createYAMLKeyValue(KEY_SPEC, specChildren, this)
126134
}
127-
return createYAMLKeyValue(KEY_SELECTOR, selectorChildren, spec.value as YAMLMapping)
135+
return spec
128136
}
129137

138+
130139
fun JsonObject.createSelector(selectorChildren: JsonObject = mock()): JsonProperty {
140+
val spec = getOrCreateSpec()
141+
return createJsonProperty(KEY_SELECTOR, selectorChildren, spec.value as JsonObject)
142+
}
143+
144+
private fun JsonObject.getOrCreateSpec(): JsonProperty {
131145
var spec = findProperty(KEY_SPEC)
132146
if (spec == null) {
133-
val specChildren = mock<JsonObject>()
134-
spec = createJsonProperty(KEY_SPEC, specChildren, this)
147+
val specChild = mock<JsonObject>()
148+
spec = createJsonProperty(KEY_SPEC, specChild, this)
135149
}
136-
return createJsonProperty(KEY_SELECTOR, selectorChildren, spec.value as JsonObject)
150+
return spec
137151
}
138152

139153
fun YAMLMapping.createMetadata(): YAMLMapping {

src/test/kotlin/com/redhat/devtools/intellij/kubernetes/editor/util/ResourcePsiElementUtilsTest.kt

Lines changed: 83 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import com.nhaarman.mockitokotlin2.mock
1919
import com.nhaarman.mockitokotlin2.never
2020
import com.nhaarman.mockitokotlin2.whenever
2121
import com.redhat.devtools.intellij.common.validation.KubernetesTypeInfo
22+
import com.redhat.devtools.intellij.kubernetes.editor.mocks.createJobTemplate
2223
import com.redhat.devtools.intellij.kubernetes.editor.mocks.createJsonObject
2324
import com.redhat.devtools.intellij.kubernetes.editor.mocks.createJsonProperty
2425
import com.redhat.devtools.intellij.kubernetes.editor.mocks.createLabels
@@ -35,6 +36,7 @@ import org.jetbrains.yaml.psi.YAMLMapping
3536
import org.junit.Before
3637
import org.junit.Test
3738
import org.mockito.MockedStatic
39+
import kotlin.collections.listOf
3840

3941
class ResourcePsiElementUtilsTest {
4042

@@ -294,6 +296,19 @@ class ResourcePsiElementUtilsTest {
294296
assertThat(result).isSameAs(templateMapping)
295297
}
296298

299+
@Test
300+
fun `#getJobTemplate for YAML returns jobTemplate mapping`() {
301+
// given
302+
val specMapping = mock<YAMLMapping>()
303+
createYAMLKeyValue("spec", specMapping, yamlElement)
304+
val templateMapping = mock<YAMLMapping>()
305+
createYAMLKeyValue("jobTemplate", templateMapping, specMapping)
306+
// when
307+
val result = yamlElement.getJobTemplate()
308+
// then
309+
assertThat(result).isSameAs(templateMapping)
310+
}
311+
297312
@Test
298313
fun `#getTemplateLabel for YAML returns template labels`() {
299314
// given
@@ -319,10 +334,43 @@ class ResourcePsiElementUtilsTest {
319334
assertThat(found).isSameAs(templateLabels)
320335
}
321336

337+
@Test
338+
fun `#getJobTemplateLabel for YAML returns template labels`() {
339+
// given
340+
val jobTemplateLabels = createYAMLMapping(listOf(
341+
createYAMLKeyValue("jedi", "skywalker")
342+
))
343+
yamlElement.createJobTemplate(
344+
createYAMLMapping(listOf(
345+
createYAMLKeyValue("spec",
346+
createYAMLMapping(listOf(
347+
createYAMLKeyValue("template",
348+
createYAMLMapping(listOf(
349+
createYAMLKeyValue(
350+
"metadata",
351+
createYAMLMapping(listOf(
352+
createYAMLKeyValue(
353+
"labels",
354+
jobTemplateLabels
355+
)
356+
))
357+
)
358+
))
359+
)
360+
))
361+
)
362+
))
363+
)
364+
// when
365+
val found = yamlElement.getJobTemplate()?.getTemplateLabels()
366+
// then
367+
assertThat(found).isSameAs(jobTemplateLabels)
368+
}
369+
322370
@Test
323371
fun `#getTemplateLabel for Json returns template labels`() {
324372
// given
325-
val templateLabels = createJsonObject(listOf(
373+
val jobTemplateLabels = createJsonObject(listOf(
326374
createJsonProperty("jedi", "skywalker")
327375
))
328376
jsonElement.createTemplate(
@@ -332,7 +380,7 @@ class ResourcePsiElementUtilsTest {
332380
createJsonObject(listOf(
333381
createJsonProperty(
334382
"labels",
335-
templateLabels
383+
jobTemplateLabels
336384
)
337385
))
338386
)
@@ -341,6 +389,39 @@ class ResourcePsiElementUtilsTest {
341389
// when
342390
val found = jsonElement.getTemplateLabels()
343391
// then
392+
assertThat(found).isSameAs(jobTemplateLabels)
393+
}
394+
395+
@Test
396+
fun `#getJobTemplateLabel for Json returns template labels`() {
397+
// given
398+
val templateLabels = createJsonObject(listOf(
399+
createJsonProperty("jedi", "skywalker")
400+
))
401+
jsonElement.createJobTemplate(
402+
createJsonObject(listOf(
403+
createJsonProperty("spec",
404+
createJsonObject(listOf(
405+
createJsonProperty("template",
406+
createJsonObject(listOf(
407+
createJsonProperty(
408+
"metadata",
409+
createJsonObject(listOf(
410+
createJsonProperty(
411+
"labels",
412+
templateLabels
413+
)
414+
))
415+
)
416+
))
417+
)
418+
))
419+
)
420+
))
421+
)
422+
// when
423+
val found = jsonElement.getJobTemplate()?.getTemplateLabels()
424+
// then
344425
assertThat(found).isSameAs(templateLabels)
345426
}
346427

0 commit comments

Comments
 (0)