Skip to content

Commit bc8c3d2

Browse files
committed
Ref #27576: allow to override instance using cookie and query param
1 parent fee0f9d commit bc8c3d2

3 files changed

Lines changed: 76 additions & 61 deletions

File tree

.editorconfig

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,18 @@ end_of_line = lf
55
trim_trailing_whitespace = true
66
insert_final_newline = true
77

8+
89
[*.kt]
910
ij_kotlin_call_parameters_new_line_after_left_paren = false
1011
ij_kotlin_call_parameters_right_paren_on_new_line = false
1112
ij_kotlin_method_parameters_new_line_after_left_paren = false
1213
ij_kotlin_method_parameters_right_paren_on_new_line = false
1314
ij_any_wrap_long_lines = false
14-
ij_formatter_off_tag = "@formatter:off"
15-
ij_formatter_on_tag = "@formatter:on"
1615
ij_kotlin_name_count_to_use_star_import = 50000
1716
ij_kotlin_name_count_to_use_star_import_for_members = 50000
17+
ij_formatter_tags_enabled = true
18+
ij_formatter_off_tag = @formatter:off
19+
ij_formatter_on_tag = @formatter:on
1820
max_line_length = 256
1921
indent_style = space
2022
indent_size = 4

src/main/kotlin/eu/openanalytics/shinyproxyoperator/components/ResourceNameFactory.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ object ResourceNameFactory {
4646
return "sp-${shinyProxy.metadata.name}-rs-${shinyProxyInstance.hashOfSpec}".take(KUBE_RESOURCE_NAME_MAX_LENGTH)
4747
}
4848

49-
fun createNameForIngress(shinyProxy: ShinyProxy, shinyProxyInstance: ShinyProxyInstance): String {
50-
return "sp-${shinyProxy.metadata.name}-ing-${shinyProxyInstance.hashOfSpec}".take(KUBE_RESOURCE_NAME_MAX_LENGTH)
49+
fun createNameForIngress(shinyProxy: ShinyProxy, routeName: String, shinyProxyInstance: ShinyProxyInstance): String {
50+
return "sp-${shinyProxy.metadata.name}-ing-${routeName}-${shinyProxyInstance.hashOfSpec}".take(KUBE_RESOURCE_NAME_MAX_LENGTH)
5151
}
5252

5353
}

src/main/kotlin/eu/openanalytics/shinyproxyoperator/ingress/skipper/IngressFactory.kt

Lines changed: 70 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -42,75 +42,88 @@ class IngressFactory(private val kubeClient: KubernetesClient) {
4242

4343
val isLatest = shinyProxyInstance.isLatestInstance
4444

45-
val cookiePath = if (shinyProxy.subPath != "") {
46-
shinyProxy.subPath
47-
} else {
48-
"/"
49-
}
45+
val routes = createRoutes(isLatest, hashOfSpec, shinyProxy)
5046

51-
val security = if (Operator.getOperatorInstance().disableSecureCookies) {
52-
""
53-
} else {
54-
"Secure;"
47+
val labels = LabelFactory.labelsForShinyProxyInstance(shinyProxy, shinyProxyInstance).toMutableMap()
48+
labels[LabelFactory.INGRESS_IS_LATEST] = isLatest.toString()
49+
50+
for ((routeName, routeAnnotations) in routes) {
51+
52+
//@formatter:off
53+
val ingressDefinition = IngressBuilder()
54+
.withNewMetadata()
55+
.withName(ResourceNameFactory.createNameForIngress(shinyProxy, routeName, shinyProxyInstance))
56+
.withLabels<String, String>(labels)
57+
.addNewOwnerReference()
58+
.withController(true)
59+
.withKind("ReplicaSet")
60+
.withApiVersion("apps/v1")
61+
.withName(ResourceNameFactory.createNameForReplicaSet(shinyProxy, shinyProxyInstance))
62+
.withNewUid(replicaSet.metadata.uid)
63+
.endOwnerReference()
64+
.withAnnotations<String, String>(routeAnnotations)
65+
.endMetadata()
66+
.withNewSpec()
67+
.addNewRule()
68+
.withHost(shinyProxy.fqdn)
69+
.withNewHttp()
70+
.addToPaths(createPathV1(shinyProxy, shinyProxyInstance))
71+
.endHttp()
72+
.endRule()
73+
.endSpec()
74+
.build()
75+
//@formatter:on
76+
77+
val createdIngress = kubeClient.network().ingress().inNamespace(shinyProxy.metadata.namespace).createOrReplace(ingressDefinition)
78+
logger.debug { "${shinyProxy.logPrefix(shinyProxyInstance)} [Component/Ingress] Created ${createdIngress.metadata.name} [latest=$isLatest]" }
5579
}
5680

57-
val annotations = if (isLatest) {
58-
mapOf(
59-
"zalando.org/skipper-predicate" to "True()",
60-
"zalando.org/skipper-filter" to
61-
"""setRequestHeader("X-ShinyProxy-Instance", "$hashOfSpec")""" +
62-
""" -> """ +
63-
"""setRequestHeader("X-ShinyProxy-Latest-Instance", "${shinyProxy.hashOfCurrentSpec}")""" +
64-
""" -> """ +
65-
"""appendResponseHeader("Set-Cookie", "sp-instance=$hashOfSpec; $security Path=$cookiePath")""" +
66-
""" -> """ +
67-
"""appendResponseHeader("Set-Cookie", "sp-latest-instance=${shinyProxy.hashOfCurrentSpec}; $security Path=$cookiePath")"""
81+
}
6882

83+
private fun createRoutes(isLatest: Boolean, hashOfSpec: String, shinyProxy: ShinyProxy): Map<String, Map<String, String>> {
84+
return if (isLatest) {
85+
mapOf(
86+
"" to createRoute(true, hashOfSpec, shinyProxy, "True()"),
87+
"cookie-override" to createRoute(true, hashOfSpec, shinyProxy, """Cookie("sp-instance-override", "$hashOfSpec") && Weight(20)""""),
88+
"query-override" to createRoute(true, hashOfSpec, shinyProxy, """QueryParam("sp_instance_override", "$hashOfSpec") && Weight(20)""""),
6989
)
7090
} else {
7191
mapOf(
72-
"zalando.org/skipper-predicate" to """True() && Cookie("sp-instance", "$hashOfSpec")""",
73-
"zalando.org/skipper-filter" to
74-
"""setRequestHeader("X-ShinyProxy-Instance", "$hashOfSpec")""" +
75-
""" -> """ +
76-
"""setRequestHeader("X-ShinyProxy-Latest-Instance", "${shinyProxy.hashOfCurrentSpec}")""" +
77-
""" -> """ +
78-
"""appendResponseHeader("Set-Cookie", "sp-latest-instance=${shinyProxy.hashOfCurrentSpec}; $security Path=$cookiePath")"""
92+
"" to createRoute(false, hashOfSpec, shinyProxy, """Cookie("sp-instance", "$hashOfSpec") && Weight(10)"""),
93+
"cookie-override" to createRoute(false, hashOfSpec, shinyProxy, """Cookie("sp-instance-override", "$hashOfSpec") && Weight(20)"""),
94+
"query-override" to createRoute(false, hashOfSpec, shinyProxy, """QueryParam("sp_instance_override", "$hashOfSpec") && Weight(20)"""),
7995
)
8096
}
97+
}
8198

82-
val labels = LabelFactory.labelsForShinyProxyInstance(shinyProxy, shinyProxyInstance).toMutableMap()
83-
labels[LabelFactory.INGRESS_IS_LATEST] = isLatest.toString()
99+
private fun createRoute(isLatest: Boolean, hashOfSpec: String, shinyProxy: ShinyProxy, predicate: String): Map<String, String> {
100+
val security = if (Operator.getOperatorInstance().disableSecureCookies) {
101+
""
102+
} else {
103+
"Secure;"
104+
}
84105

85-
//@formatter:off
86-
val ingressDefinition = IngressBuilder()
87-
.withNewMetadata()
88-
.withName(ResourceNameFactory.createNameForIngress(shinyProxy, shinyProxyInstance))
89-
.withLabels<String, String>(labels)
90-
.addNewOwnerReference()
91-
.withController(true)
92-
.withKind("ReplicaSet")
93-
.withApiVersion("apps/v1")
94-
.withName(ResourceNameFactory.createNameForReplicaSet(shinyProxy, shinyProxyInstance))
95-
.withNewUid(replicaSet.metadata.uid)
96-
.endOwnerReference()
97-
.withAnnotations<String, String>(annotations)
98-
.endMetadata()
99-
.withNewSpec()
100-
.addNewRule()
101-
.withHost(shinyProxy.fqdn)
102-
.withNewHttp()
103-
.addToPaths(createPathV1(shinyProxy, shinyProxyInstance))
104-
.endHttp()
105-
.endRule()
106-
.withIngressClassName("skipper")
107-
.endSpec()
108-
.build()
109-
//@formatter:on
106+
val cookiePath = if (shinyProxy.subPath != "") {
107+
shinyProxy.subPath
108+
} else {
109+
"/"
110+
}
111+
return mapOf(
112+
"zalando.org/skipper-predicate" to predicate,
113+
"zalando.org/skipper-filter" to
114+
"""setRequestHeader("X-ShinyProxy-Instance", "$hashOfSpec")""" +
115+
""" -> """ +
116+
"""setRequestHeader("X-ShinyProxy-Latest-Instance", "${shinyProxy.hashOfCurrentSpec}")""" +
117+
if (isLatest) {
118+
""" -> """ +
119+
"""appendResponseHeader("Set-Cookie", "sp-instance=$hashOfSpec; $security Path=$cookiePath")"""
120+
} else {
121+
""
122+
} +
123+
""" -> """ +
124+
"""appendResponseHeader("Set-Cookie", "sp-latest-instance=${shinyProxy.hashOfCurrentSpec}; $security Path=$cookiePath")"""
125+
)
110126

111-
val createdIngress =
112-
kubeClient.network().v1().ingresses().inNamespace(shinyProxy.metadata.namespace).createOrReplace(ingressDefinition)
113-
logger.debug { "${shinyProxy.logPrefix(shinyProxyInstance)} [Component/Ingress] Created ${createdIngress.metadata.name} [latest=$isLatest]" }
114127
}
115128

116129
private fun createPathV1 (shinyProxy: ShinyProxy, shinyProxyInstance: ShinyProxyInstance): HTTPIngressPath {

0 commit comments

Comments
 (0)