diff --git a/docs/charts/index.yaml b/docs/charts/index.yaml index 03a90ce7ae0..90a62d4d3cd 100644 --- a/docs/charts/index.yaml +++ b/docs/charts/index.yaml @@ -3,9 +3,9 @@ entries: weblogic-operator: - apiVersion: v1 appVersion: 3.2.0 - created: "2021-01-04T15:48:07.645132-05:00" + created: "2021-01-13T12:37:48.514056-05:00" description: Helm chart for configuring the WebLogic operator. - digest: faeabc3c35c580909ff3d35b44b0467bd7cb4376bbd54689df92a44295d9b37f + digest: 77bf9ae96371e779d6fd6faae1966d057d54571f651ec11babd8bc1d86e590af name: weblogic-operator type: application urls: @@ -13,7 +13,7 @@ entries: version: 3.2.0 - apiVersion: v1 appVersion: 3.1.1 - created: "2021-01-04T15:48:07.64427-05:00" + created: "2021-01-13T12:37:48.513192-05:00" description: Helm chart for configuring the WebLogic operator. digest: 202d148fd3db1ce45d22d4eab3e84bea9bf774addd9e0bc65f9312207a6e4968 name: weblogic-operator @@ -23,7 +23,7 @@ entries: version: 3.1.1 - apiVersion: v1 appVersion: 3.1.0 - created: "2021-01-04T15:48:07.643256-05:00" + created: "2021-01-13T12:37:48.512149-05:00" description: Helm chart for configuring the WebLogic operator. digest: acf600d0951dc3d8a0b05b35f3b9b1e62d827ef483fa863b0e37054ebb61f853 name: weblogic-operator @@ -32,7 +32,7 @@ entries: - https://oracle.github.io/weblogic-kubernetes-operator/charts/weblogic-operator-3.1.0.tgz version: 3.1.0 - apiVersion: v1 - created: "2021-01-04T15:48:07.642209-05:00" + created: "2021-01-13T12:37:48.510828-05:00" description: Helm chart for configuring the WebLogic operator. digest: 5d3a79a55132c33afd5d2d30e398c3cc508d77c9352129f2e8e127db5f1dcf19 name: weblogic-operator @@ -40,7 +40,7 @@ entries: - https://oracle.github.io/weblogic-kubernetes-operator/charts/weblogic-operator-3.0.4.tgz version: 3.0.4 - apiVersion: v1 - created: "2021-01-04T15:48:07.641293-05:00" + created: "2021-01-13T12:37:48.510041-05:00" description: Helm chart for configuring the WebLogic operator. digest: c6aeefca88eaa0d431dba66ee5705391c92468f26b27c5af92815ec3c3000406 name: weblogic-operator @@ -48,7 +48,7 @@ entries: - https://oracle.github.io/weblogic-kubernetes-operator/charts/weblogic-operator-3.0.3.tgz version: 3.0.3 - apiVersion: v1 - created: "2021-01-04T15:48:07.640176-05:00" + created: "2021-01-13T12:37:48.508963-05:00" description: Helm chart for configuring the WebLogic operator. digest: 84b5989fe8f2392d2b3b0f721bdab1562566d7d885324beafd9fc9e658b13cd3 name: weblogic-operator @@ -56,7 +56,7 @@ entries: - https://oracle.github.io/weblogic-kubernetes-operator/charts/weblogic-operator-3.0.2.tgz version: 3.0.2 - apiVersion: v1 - created: "2021-01-04T15:48:07.639261-05:00" + created: "2021-01-13T12:37:48.508139-05:00" description: Helm chart for configuring the WebLogic operator. digest: e7654ad3f2168f54b3a4b133bf8a86ea12bc474e5ee1d3ab14e1cf53012e9772 name: weblogic-operator @@ -64,7 +64,7 @@ entries: - https://oracle.github.io/weblogic-kubernetes-operator/charts/weblogic-operator-3.0.1.tgz version: 3.0.1 - apiVersion: v1 - created: "2021-01-04T15:48:07.638382-05:00" + created: "2021-01-13T12:37:48.507336-05:00" description: Helm chart for configuring the WebLogic operator. digest: 5c7c0d3ae797e98592b6fd2191b104f515d6649d0060af0a3ffef215d4c69864 name: weblogic-operator @@ -72,7 +72,7 @@ entries: - https://oracle.github.io/weblogic-kubernetes-operator/charts/weblogic-operator-3.0.0.tgz version: 3.0.0 - apiVersion: v1 - created: "2021-01-04T15:48:07.637498-05:00" + created: "2021-01-13T12:37:48.506585-05:00" description: Helm chart for configuring the WebLogic operator. digest: 5f4cd8f4f3282b52b5e90a1169f26986e8272671845053606ade9c855fb04151 name: weblogic-operator @@ -80,7 +80,7 @@ entries: - https://oracle.github.io/weblogic-kubernetes-operator/charts/weblogic-operator-3.0.0-rc1.tgz version: 3.0.0-rc1 - apiVersion: v1 - created: "2021-01-04T15:48:07.636461-05:00" + created: "2021-01-13T12:37:48.505796-05:00" description: Helm chart for configuring the WebLogic operator. digest: d441888a8deae1b1339e7585e3b437dfd2533303e46e842d7378e16db665e234 name: weblogic-operator @@ -88,7 +88,7 @@ entries: - https://oracle.github.io/weblogic-kubernetes-operator/charts/weblogic-operator-2.6.0.tgz version: 2.6.0 - apiVersion: v1 - created: "2021-01-04T15:48:07.635531-05:00" + created: "2021-01-13T12:37:48.50504-05:00" description: Helm chart for configuring the WebLogic operator. digest: fe41421b7dc45dc8a3b2888d3a626a37f5d3c8e1fa292fb6699deedc5e1db33d name: weblogic-operator @@ -96,7 +96,7 @@ entries: - https://oracle.github.io/weblogic-kubernetes-operator/charts/weblogic-operator-2.5.0.tgz version: 2.5.0 - apiVersion: v1 - created: "2021-01-04T15:48:07.633853-05:00" + created: "2021-01-13T12:37:48.504032-05:00" description: Helm chart for configuring the WebLogic operator. digest: b36bd32083f67453a62d089a2c09ce38e6655d88ac8a7b38691230c55c40e672 name: weblogic-operator @@ -104,7 +104,7 @@ entries: - https://oracle.github.io/weblogic-kubernetes-operator/charts/weblogic-operator-2.4.0.tgz version: 2.4.0 - apiVersion: v1 - created: "2021-01-04T15:48:07.632814-05:00" + created: "2021-01-13T12:37:48.503154-05:00" description: Helm chart for configuring the WebLogic operator. digest: a3eafe4c2c6ff49384e56421201e59a3737d651af8d5b605b87a19eb1f6f1dc3 name: weblogic-operator @@ -112,7 +112,7 @@ entries: - https://oracle.github.io/weblogic-kubernetes-operator/charts/weblogic-operator-2.3.1.tgz version: 2.3.1 - apiVersion: v1 - created: "2021-01-04T15:48:07.630402-05:00" + created: "2021-01-13T12:37:48.49981-05:00" description: Helm chart for configuring the WebLogic operator. digest: cbc6caaa6eb28e3c7e906ede14b2ae511a0b35fc12a8e3ab629155b09993e8b2 name: weblogic-operator @@ -120,7 +120,7 @@ entries: - https://oracle.github.io/weblogic-kubernetes-operator/charts/weblogic-operator-2.3.0.tgz version: 2.3.0 - apiVersion: v1 - created: "2021-01-04T15:48:07.629526-05:00" + created: "2021-01-13T12:37:48.498485-05:00" description: Helm chart for configuring the WebLogic operator. digest: 23d5a1c554fa8211cc1e86b7ade09460917cb2069e68fb4bfdddafc8db44fdcd name: weblogic-operator @@ -128,7 +128,7 @@ entries: - https://oracle.github.io/weblogic-kubernetes-operator/charts/weblogic-operator-2.2.1.tgz version: 2.2.1 - apiVersion: v1 - created: "2021-01-04T15:48:07.628426-05:00" + created: "2021-01-13T12:37:48.497434-05:00" description: Helm chart for configuring the WebLogic operator. digest: bba303686cb55d84fe8c0d693a2436e7e686b028085b56e012f6381699a3911f name: weblogic-operator @@ -136,7 +136,7 @@ entries: - https://oracle.github.io/weblogic-kubernetes-operator/charts/weblogic-operator-2.2.0.tgz version: 2.2.0 - apiVersion: v1 - created: "2021-01-04T15:48:07.626313-05:00" + created: "2021-01-13T12:37:48.494398-05:00" description: Helm chart for configuring the WebLogic operator. digest: 391e23c0969ada5f0cd2a088ddc6f11f237f57521801ed3925db2149a8437a0d name: weblogic-operator @@ -144,11 +144,11 @@ entries: - https://oracle.github.io/weblogic-kubernetes-operator/charts/weblogic-operator-2.1.tgz version: "2.1" - apiVersion: v1 - created: "2021-01-04T15:48:07.6254-05:00" + created: "2021-01-13T12:37:48.493567-05:00" description: Helm chart for configuring the WebLogic operator. digest: 298acda78ab73db6b7ba6f2752311bfa40c65874e03fb196b70976192211c1a5 name: weblogic-operator urls: - https://oracle.github.io/weblogic-kubernetes-operator/charts/weblogic-operator-2.0.1.tgz version: 2.0.1 -generated: "2021-01-04T15:48:07.623889-05:00" +generated: "2021-01-13T12:37:48.491609-05:00" diff --git a/docs/charts/weblogic-operator-3.2.0.tgz b/docs/charts/weblogic-operator-3.2.0.tgz index 580e8ef132e..c0ebc7afa7e 100644 Binary files a/docs/charts/weblogic-operator-3.2.0.tgz and b/docs/charts/weblogic-operator-3.2.0.tgz differ diff --git a/kubernetes/charts/weblogic-operator/templates/_domain-namespaces.tpl b/kubernetes/charts/weblogic-operator/templates/_domain-namespaces.tpl index cfc5b8d0d48..08988c28dea 100644 --- a/kubernetes/charts/weblogic-operator/templates/_domain-namespaces.tpl +++ b/kubernetes/charts/weblogic-operator/templates/_domain-namespaces.tpl @@ -17,7 +17,7 @@ {{- $args := include "utils.cloneDictionary" . | fromYaml -}} {{- /* Split terms on commas not contained in parentheses. Unfortunately, the regular expression - support included with Helm tempalates does not include lookarounds. + support included with Helm templates does not include lookarounds. */ -}} {{- $working := dict "rejected" (list) "terms" (list $args.domainNamespaceLabelSelector) }} {{- if contains "," $args.domainNamespaceLabelSelector }} diff --git a/kubernetes/charts/weblogic-operator/templates/_operator-role.tpl b/kubernetes/charts/weblogic-operator/templates/_operator-role.tpl index 22cb6a26f7f..cb05180c987 100644 --- a/kubernetes/charts/weblogic-operator/templates/_operator-role.tpl +++ b/kubernetes/charts/weblogic-operator/templates/_operator-role.tpl @@ -12,6 +12,9 @@ metadata: weblogic.operatorName: {{ .Release.Namespace | quote }} rules: - apiGroups: [""] - resources: ["secrets", "configmaps", "events"] + resources: ["secrets", "configmaps"] + verbs: ["get", "list", "watch"] +- apiGroups: [""] + resources: ["events"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete", "deletecollection"] {{- end }} diff --git a/operator/src/main/java/oracle/kubernetes/operator/DomainRecheck.java b/operator/src/main/java/oracle/kubernetes/operator/DomainRecheck.java index a50f595dc68..ad5a7ae5340 100644 --- a/operator/src/main/java/oracle/kubernetes/operator/DomainRecheck.java +++ b/operator/src/main/java/oracle/kubernetes/operator/DomainRecheck.java @@ -10,6 +10,7 @@ import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Nonnull; @@ -17,6 +18,7 @@ import io.kubernetes.client.openapi.models.V1Namespace; import io.kubernetes.client.openapi.models.V1NamespaceList; import io.kubernetes.client.openapi.models.V1ObjectMeta; +import io.kubernetes.client.openapi.models.V1SubjectRulesReviewStatus; import oracle.kubernetes.operator.calls.CallResponse; import oracle.kubernetes.operator.helpers.CallBuilder; import oracle.kubernetes.operator.helpers.EventHelper; @@ -61,11 +63,11 @@ class DomainRecheck { } NamespaceRulesReviewStep createOperatorNamespaceReview() { - return new NamespaceRulesReviewStep(getOperatorNamespace()); + return new NamespaceRulesReviewStep(getOperatorNamespace(), false); } NamespaceRulesReviewStep createNamespaceReview(String namespace) { - return new NamespaceRulesReviewStep(namespace); + return new NamespaceRulesReviewStep(namespace, true); } Step createReadNamespacesStep() { @@ -78,9 +80,11 @@ Step createReadNamespacesStep() { */ class NamespaceRulesReviewStep extends Step { private final String ns; + private final boolean isDomainNamespace; - private NamespaceRulesReviewStep(@Nonnull String ns) { + private NamespaceRulesReviewStep(@Nonnull String ns, boolean isDomainNamespace) { this.ns = ns; + this.isDomainNamespace = isDomainNamespace; } @Override @@ -93,19 +97,24 @@ public NextAction apply(Packet packet) { LoggingContext.LOGGING_CONTEXT_KEY, Component.createFor(new LoggingContext().namespace(ns))); - nss.getRulesReviewStatus().updateAndGet(prev -> { + V1SubjectRulesReviewStatus status = nss.getRulesReviewStatus().updateAndGet(prev -> { if (prev != null) { return prev; } try { - return HealthCheckHelper.getAccessAuthorizations(ns); + return HealthCheckHelper.getSelfSubjectRulesReviewStatus(ns); } catch (Throwable e) { LOGGER.warning(MessageKeys.EXCEPTION, e); } return null; }); + AtomicBoolean guard = isDomainNamespace ? nss.verifiedAsDomainNamespace() : nss.verifiedAsOperatorNamespace(); + if (!guard.getAndSet(true)) { + HealthCheckHelper.verifyAccess(status, ns, isDomainNamespace); + } + return doNext(packet); } diff --git a/operator/src/main/java/oracle/kubernetes/operator/NamespaceStatus.java b/operator/src/main/java/oracle/kubernetes/operator/NamespaceStatus.java index 457bcb6cc84..5443bfd4c5f 100644 --- a/operator/src/main/java/oracle/kubernetes/operator/NamespaceStatus.java +++ b/operator/src/main/java/oracle/kubernetes/operator/NamespaceStatus.java @@ -11,11 +11,21 @@ public class NamespaceStatus { private final AtomicBoolean isNamespaceStarting = new AtomicBoolean(false); private final AtomicReference rulesReviewStatus = new AtomicReference<>(); + private final AtomicBoolean verifiedAsOperatorNamespace = new AtomicBoolean(false); + private final AtomicBoolean verifiedAsDomainNamespace = new AtomicBoolean(false); public AtomicBoolean isNamespaceStarting() { return isNamespaceStarting; } + public AtomicBoolean verifiedAsOperatorNamespace() { + return verifiedAsOperatorNamespace; + } + + public AtomicBoolean verifiedAsDomainNamespace() { + return verifiedAsDomainNamespace; + } + public AtomicReference getRulesReviewStatus() { return rulesReviewStatus; } diff --git a/operator/src/main/java/oracle/kubernetes/operator/helpers/HealthCheckHelper.java b/operator/src/main/java/oracle/kubernetes/operator/helpers/HealthCheckHelper.java index 34d8fa7c0b8..58d14789552 100644 --- a/operator/src/main/java/oracle/kubernetes/operator/helpers/HealthCheckHelper.java +++ b/operator/src/main/java/oracle/kubernetes/operator/helpers/HealthCheckHelper.java @@ -6,6 +6,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import javax.annotation.Nonnull; import io.kubernetes.client.openapi.models.V1ResourceRule; @@ -20,15 +21,15 @@ import oracle.kubernetes.operator.logging.LoggingFactory; import oracle.kubernetes.operator.logging.MessageKeys; -import static oracle.kubernetes.operator.helpers.NamespaceHelper.getOperatorNamespace; - /** A Helper Class for checking the health of the WebLogic Operator. */ public final class HealthCheckHelper { private static final LoggingFacade LOGGER = LoggingFactory.getLogger("Operator", "Operator"); private static final Map - namespaceAccessChecks = new HashMap<>(); + domainNamespaceAccessChecks = new HashMap<>(); + private static final Map + operatorNamespaceAccessChecks = new HashMap<>(); private static final Map clusterAccessChecks = new HashMap<>(); @@ -84,58 +85,71 @@ public final class HealthCheckHelper { clusterAccessChecks.put(Resource.NAMESPACES, glwOperations); clusterAccessChecks.put(Resource.CRDS, crdOperations); - namespaceAccessChecks.put(Resource.DOMAINS, glwupOperations); - namespaceAccessChecks.put(Resource.DOMAINSTATUSES, glwupOperations); - - namespaceAccessChecks.put(Resource.TOKENREVIEWS, cOperations); - namespaceAccessChecks.put(Resource.SELFSUBJECTRULESREVIEWS, cOperations); + domainNamespaceAccessChecks.put(Resource.DOMAINS, glwupOperations); + domainNamespaceAccessChecks.put(Resource.DOMAINSTATUSES, glwupOperations); - namespaceAccessChecks.put(Resource.SERVICES, crudOperations); - namespaceAccessChecks.put(Resource.CONFIGMAPS, crudOperations); - namespaceAccessChecks.put(Resource.PODS, crudOperations); - namespaceAccessChecks.put(Resource.EVENTS, crudOperations); + domainNamespaceAccessChecks.put(Resource.SELFSUBJECTRULESREVIEWS, cOperations); - namespaceAccessChecks.put(Resource.SECRETS, glwOperations); + domainNamespaceAccessChecks.put(Resource.SERVICES, crudOperations); + domainNamespaceAccessChecks.put(Resource.CONFIGMAPS, crudOperations); + domainNamespaceAccessChecks.put(Resource.PODS, crudOperations); + domainNamespaceAccessChecks.put(Resource.EVENTS, crudOperations); + domainNamespaceAccessChecks.put(Resource.JOBS, crudOperations); + domainNamespaceAccessChecks.put(Resource.SECRETS, glwOperations); - namespaceAccessChecks.put(Resource.LOGS, glOperations); - namespaceAccessChecks.put(Resource.EXEC, cOperations); + domainNamespaceAccessChecks.put(Resource.LOGS, glOperations); + domainNamespaceAccessChecks.put(Resource.EXEC, cOperations); - namespaceAccessChecks.put(Resource.JOBS, crudOperations); + operatorNamespaceAccessChecks.put(Resource.EVENTS, crudOperations); + operatorNamespaceAccessChecks.put(Resource.CONFIGMAPS, glwOperations); + operatorNamespaceAccessChecks.put(Resource.SECRETS, glwOperations); } private HealthCheckHelper() { } /** - * Verify Access. + * Access the self-subject rules review for the namespace. The namespace may be the operator's + * namespace, a domain namespace, or both. * - * @param namespace domain namespace - * @return self subject rules review for the domain namespace + * @param namespace namespace + * @return self-subject rules review for the namespace */ - public static V1SubjectRulesReviewStatus getAccessAuthorizations(@Nonnull String namespace) { - // Validate namespace - if (DEFAULT_NAMESPACE.equals(getOperatorNamespace())) { - LOGGER.fine(MessageKeys.NAMESPACE_IS_DEFAULT); - } + public static V1SubjectRulesReviewStatus getSelfSubjectRulesReviewStatus(@Nonnull String namespace) { + AuthorizationProxy ap = new AuthorizationProxy(); + return Optional.ofNullable(ap.review(namespace)).map(V1SelfSubjectRulesReview::getStatus).orElse(null); + } + /** + * Verify Access. + * + * @param status Self-subject rules review status + * @param namespace Namespace + * @param isDomainNamespace if true, verify domain namespace access; otherwise, verify operator-only namespaces access + */ + public static void verifyAccess(@Nonnull V1SubjectRulesReviewStatus status, @Nonnull String namespace, + boolean isDomainNamespace) { // Validate policies allow service account to perform required operations AuthorizationProxy ap = new AuthorizationProxy(); LOGGER.fine(MessageKeys.VERIFY_ACCESS_START, namespace); - V1SelfSubjectRulesReview review = ap.review(namespace); - if (review != null) { - V1SubjectRulesReviewStatus status = review.getStatus(); + if (status != null) { + List rules = status.getResourceRules(); - if (status != null) { - List rules = status.getResourceRules(); - - for (Resource r : namespaceAccessChecks.keySet()) { - for (Operation op : namespaceAccessChecks.get(r)) { + if (isDomainNamespace) { + for (Resource r : domainNamespaceAccessChecks.keySet()) { + for (Operation op : domainNamespaceAccessChecks.get(r)) { + check(rules, r, op, namespace); + } + } + } else { + for (Resource r : operatorNamespaceAccessChecks.keySet()) { + for (Operation op : operatorNamespaceAccessChecks.get(r)) { check(rules, r, op, namespace); } } - if (!Main.isDedicated() && getOperatorNamespace().equals(namespace)) { + if (!Main.isDedicated()) { for (Resource r : clusterAccessChecks.keySet()) { for (Operation op : clusterAccessChecks.get(r)) { check(rules, r, op, namespace); @@ -143,11 +157,7 @@ public static V1SubjectRulesReviewStatus getAccessAuthorizations(@Nonnull String } } } - - return status; } - - return null; } /** diff --git a/operator/src/test/java/oracle/kubernetes/operator/helpers/HealthCheckHelperTest.java b/operator/src/test/java/oracle/kubernetes/operator/helpers/HealthCheckHelperTest.java index f58b081aecf..d1d565538d6 100644 --- a/operator/src/test/java/oracle/kubernetes/operator/helpers/HealthCheckHelperTest.java +++ b/operator/src/test/java/oracle/kubernetes/operator/helpers/HealthCheckHelperTest.java @@ -50,6 +50,7 @@ public class HealthCheckHelperTest { private static final String NS1 = "ns1"; private static final String NS2 = "ns2"; + private static final String OPERATOR_NAMESPACE = "op1"; private static final List TARGET_NAMESPACES = Arrays.asList(NS1, NS2); private static final List CRUD_RESOURCES = Arrays.asList( @@ -116,22 +117,37 @@ public void whenRulesReviewSupported_accessGrantedForEverything() { expectSelfSubjectRulesReview(); for (String ns : TARGET_NAMESPACES) { - HealthCheckHelper.getAccessAuthorizations(ns); + V1SubjectRulesReviewStatus status = HealthCheckHelper.getSelfSubjectRulesReviewStatus(ns); + HealthCheckHelper.verifyAccess(status, ns, true); } } @Test - public void whenRulesReviewSupportedAndNoNamespaceAccess_logWarning() { + public void whenRulesReviewSupportedAndNoDomainNamespaceAccess_logWarning() { accessChecks.setMayAccessNamespace(false); expectSelfSubjectRulesReview(); for (String ns : TARGET_NAMESPACES) { - HealthCheckHelper.getAccessAuthorizations(ns); + V1SubjectRulesReviewStatus status = HealthCheckHelper.getSelfSubjectRulesReviewStatus(ns); + HealthCheckHelper.verifyAccess(status, ns, true); } assertThat(logRecords, containsWarning(VERIFY_ACCESS_DENIED_WITH_NS)); } + // HERE + + @Test + public void whenRulesReviewSupportedAndNoOperatorNamespaceAccess_logWarning() { + accessChecks.setMayAccessNamespace(false); + expectSelfSubjectRulesReview(); + + V1SubjectRulesReviewStatus status = HealthCheckHelper.getSelfSubjectRulesReviewStatus(OPERATOR_NAMESPACE); + HealthCheckHelper.verifyAccess(status, OPERATOR_NAMESPACE, false); + + assertThat(logRecords, containsWarning(VERIFY_ACCESS_DENIED_WITH_NS)); + } + private void expectSelfSubjectRulesReview() { testSupport .createCannedResponse("createSelfSubjectRulesReview")