From 70d58d7d74cbf2383e72d2363f5dfe283940dde3 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Tue, 7 Jun 2022 16:43:17 +0900 Subject: [PATCH 01/14] Add certificate reconciler for internal certs --- cmd/activator/main.go | 5 +- cmd/controller/main.go | 2 + cmd/queue/main.go | 5 +- config/core/300-secret.yaml | 27 ++ go.mod | 1 + go.sum | 6 + test/config/tls/config-network.yaml | 8 +- test/config/tls/secret.yaml | 29 ++ test/e2e-common.sh | 6 +- test/generate-cert.sh | 47 --- test/ha/ha.go | 2 +- .../control-protocol/pkg/certificates/LICENSE | 201 ++++++++++ third_party/kourier-latest/kourier.yaml | 2 +- vendor/knative.dev/control-protocol/LICENSE | 201 ++++++++++ .../pkg/certificates/certs.go | 221 ++++++++++ .../pkg/certificates/constants.go | 26 ++ .../pkg/certificates/key_pair.go | 60 +++ .../certificates/reconciler/certificates.go | 184 +++++++++ .../pkg/certificates/reconciler/controller.go | 86 ++++ .../kube/informers/core/v1/secret/secret.go | 116 ++++++ .../reconciler/core/v1/secret/controller.go | 157 ++++++++ .../reconciler/core/v1/secret/reconciler.go | 377 ++++++++++++++++++ .../kube/reconciler/core/v1/secret/state.go | 97 +++++ vendor/modules.txt | 6 + 24 files changed, 1813 insertions(+), 59 deletions(-) create mode 100644 config/core/300-secret.yaml create mode 100644 test/config/tls/secret.yaml delete mode 100755 test/generate-cert.sh create mode 100644 third_party/VENDOR-LICENSE/knative.dev/control-protocol/pkg/certificates/LICENSE create mode 100644 vendor/knative.dev/control-protocol/LICENSE create mode 100644 vendor/knative.dev/control-protocol/pkg/certificates/certs.go create mode 100644 vendor/knative.dev/control-protocol/pkg/certificates/constants.go create mode 100644 vendor/knative.dev/control-protocol/pkg/certificates/key_pair.go create mode 100644 vendor/knative.dev/control-protocol/pkg/certificates/reconciler/certificates.go create mode 100644 vendor/knative.dev/control-protocol/pkg/certificates/reconciler/controller.go create mode 100644 vendor/knative.dev/pkg/client/injection/kube/informers/core/v1/secret/secret.go create mode 100644 vendor/knative.dev/pkg/client/injection/kube/reconciler/core/v1/secret/controller.go create mode 100644 vendor/knative.dev/pkg/client/injection/kube/reconciler/core/v1/secret/reconciler.go create mode 100644 vendor/knative.dev/pkg/client/injection/kube/reconciler/core/v1/secret/state.go diff --git a/cmd/activator/main.go b/cmd/activator/main.go index 403ef7a22fdb..09ce6587da40 100644 --- a/cmd/activator/main.go +++ b/cmd/activator/main.go @@ -40,6 +40,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" + "knative.dev/control-protocol/pkg/certificates" network "knative.dev/networking/pkg" netcfg "knative.dev/networking/pkg/config" netprobe "knative.dev/networking/pkg/http/probe" @@ -173,7 +174,7 @@ func main() { pool = x509.NewCertPool() } - if ok := pool.AppendCertsFromPEM(caSecret.Data["ca.crt"]); !ok { + if ok := pool.AppendCertsFromPEM(caSecret.Data[certificates.SecretCaCertKey]); !ok { logger.Fatalw("Failed to append ca cert to the RootCAs") } @@ -283,7 +284,7 @@ func main() { if err != nil { logger.Fatalw("failed to get secret", zap.Error(err)) } - cert, err := tls.X509KeyPair(secret.Data["tls.crt"], secret.Data["tls.key"]) + cert, err := tls.X509KeyPair(secret.Data[certificates.SecretCertKey], secret.Data[certificates.SecretPKKey]) if err != nil { logger.Fatalw("failed to load certs", zap.Error(err)) } diff --git a/cmd/controller/main.go b/cmd/controller/main.go index e08aee7c4ec6..25a321cd617c 100644 --- a/cmd/controller/main.go +++ b/cmd/controller/main.go @@ -18,6 +18,7 @@ package main import ( // The set of controllers this controller process runs. + certificate "knative.dev/control-protocol/pkg/certificates/reconciler" "knative.dev/serving/pkg/reconciler/configuration" "knative.dev/serving/pkg/reconciler/gc" "knative.dev/serving/pkg/reconciler/labeler" @@ -41,6 +42,7 @@ var ctors = []injection.ControllerConstructor{ service.NewController, gc.NewController, nscert.NewController, + certificate.NewControllerFactory("serving"), } func main() { diff --git a/cmd/queue/main.go b/cmd/queue/main.go index 345ffc0878ca..4804e37f19b0 100644 --- a/cmd/queue/main.go +++ b/cmd/queue/main.go @@ -33,6 +33,7 @@ import ( "k8s.io/apimachinery/pkg/types" + "knative.dev/control-protocol/pkg/certificates" netheader "knative.dev/networking/pkg/http/header" netproxy "knative.dev/networking/pkg/http/proxy" netstats "knative.dev/networking/pkg/http/stats" @@ -66,10 +67,10 @@ const ( drainSleepDuration = 30 * time.Second // certPath is the path for the server certificate mounted by queue-proxy. - certPath = queue.CertDirectory + "/tls.crt" + certPath = queue.CertDirectory + certificates.SecretCertKey // keyPath is the path for the server certificate key mounted by queue-proxy. - keyPath = queue.CertDirectory + "/tls.key" + keyPath = queue.CertDirectory + certificates.SecretPKKey ) type config struct { diff --git a/config/core/300-secret.yaml b/config/core/300-secret.yaml new file mode 100644 index 000000000000..27fe2ddd004e --- /dev/null +++ b/config/core/300-secret.yaml @@ -0,0 +1,27 @@ +# Copyright 2022 The Knative Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: Secret +metadata: + name: serving-ctrl-ca + namespace: knative-serving +--- +apiVersion: v1 +kind: Secret +metadata: + name: server-certs + namespace: knative-serving + labels: + serving-ctrl: "data-plane" diff --git a/go.mod b/go.mod index 8fdc39056af9..acb09fe65e2c 100644 --- a/go.mod +++ b/go.mod @@ -34,6 +34,7 @@ require ( k8s.io/code-generator v0.23.5 k8s.io/kube-openapi v0.0.0-20220124234850-424119656bbf knative.dev/caching v0.0.0-20220610113725-9c092893371a + knative.dev/control-protocol v0.0.0-20220610133426-4a1c8e84039f knative.dev/hack v0.0.0-20220610014127-dc6c287516dc knative.dev/networking v0.0.0-20220610013825-3103f3a72792 knative.dev/pkg v0.0.0-20220610014025-7d607d643ee2 diff --git a/go.sum b/go.sum index d53ed9cc8dbf..8e5cb219e86c 100644 --- a/go.sum +++ b/go.sum @@ -296,6 +296,8 @@ github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2u github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudevents/conformance v0.2.0/go.mod h1:rHKDwylBH89Rns6U3wL9ww8bg9/4GbwRCDNuyoC6bcc= +github.com/cloudevents/sdk-go/v2 v2.4.1/go.mod h1:MZiMwmAh5tGj+fPFvtHv9hKurKqXtdB9haJYMJ/7GJY= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -856,6 +858,7 @@ github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1: github.com/imdario/mergo v0.3.4/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= @@ -2244,6 +2247,8 @@ k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 h1:HNSDgDCrr/6Ly3WEGKZftiE7IY19V k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= knative.dev/caching v0.0.0-20220610113725-9c092893371a h1:HMiI0L60m16KhkBLDyb8XV3GSaBM6ZPqRSluAwJ4XKs= knative.dev/caching v0.0.0-20220610113725-9c092893371a/go.mod h1:IcfEPqEP6ma4EcRUcPkwVNx5FWHHWu8w4/eqRQguDwc= +knative.dev/control-protocol v0.0.0-20220610133426-4a1c8e84039f h1:vdhs0WWGojtUldsM/ijbOfYY2LTO3GlulilCgeZX4Js= +knative.dev/control-protocol v0.0.0-20220610133426-4a1c8e84039f/go.mod h1:MjnhSes1u2GIoqwQia5bSe3Ny8r+d5//UB+Y/en2ZL8= knative.dev/hack v0.0.0-20220524153203-12d3e2a7addc/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI= knative.dev/hack v0.0.0-20220609132040-fd240e2cef5c/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI= knative.dev/hack v0.0.0-20220610014127-dc6c287516dc h1:LyqyT+rtgZYfOb3ChGE5jTFApCOcUmAcSV+TzgLxnys= @@ -2254,6 +2259,7 @@ knative.dev/pkg v0.0.0-20220524202603-19adf798efb8/go.mod h1:pApypeWDkGrsMkUDkV6 knative.dev/pkg v0.0.0-20220609131940-865e331abfa5/go.mod h1:pApypeWDkGrsMkUDkV6StWXS4CXhwGWuJEID9GGZY0Y= knative.dev/pkg v0.0.0-20220610014025-7d607d643ee2 h1:MMClRZRz6rzhrpySJ21XCJqVDd4K3rurUEJ1Yrh8DmA= knative.dev/pkg v0.0.0-20220610014025-7d607d643ee2/go.mod h1:pApypeWDkGrsMkUDkV6StWXS4CXhwGWuJEID9GGZY0Y= +knative.dev/reconciler-test v0.0.0-20220610014025-b62b10257cbf/go.mod h1:/ps2aEdmtjId+pUGJuuADQN4IucIp4rI7KnrYEahOgE= mvdan.cc/gofumpt v0.1.1/go.mod h1:yXG1r1WqZVKWbVRtBWKWX9+CxGYfA51nSomhM0woR48= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= diff --git a/test/config/tls/config-network.yaml b/test/config/tls/config-network.yaml index ae048d23acbc..6cb6b70a43e4 100644 --- a/test/config/tls/config-network.yaml +++ b/test/config/tls/config-network.yaml @@ -21,9 +21,9 @@ metadata: app.kubernetes.io/version: devel serving.knative.dev/release: devel data: - activator-ca: "serving-ca" - activator-san: "knative" + activator-ca: "server-certs" + activator-san: "data-plane.knative.dev" activator-cert-secret: "server-certs" - queue-proxy-ca: "serving-ca" - queue-proxy-san: "knative" + queue-proxy-ca: "server-certs" + queue-proxy-san: "data-plane.knative.dev" queue-proxy-cert-secret: "server-certs" diff --git a/test/config/tls/secret.yaml b/test/config/tls/secret.yaml new file mode 100644 index 000000000000..c6677894ef30 --- /dev/null +++ b/test/config/tls/secret.yaml @@ -0,0 +1,29 @@ +# Copyright 2020 The Knative Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: Secret +metadata: + name: server-certs + namespace: serving-tests-alt + labels: + serving-ctrl: "data-plane" +--- +apiVersion: v1 +kind: Secret +metadata: + name: server-certs + namespace: serving-tests + labels: + serving-ctrl: "data-plane" diff --git a/test/e2e-common.sh b/test/e2e-common.sh index a261e9c65a01..af0da4e4902f 100644 --- a/test/e2e-common.sh +++ b/test/e2e-common.sh @@ -359,12 +359,14 @@ function install() { fi if (( ENABLE_TLS )); then - echo "Generate certificates" - bash ${REPO_ROOT_DIR}/test/generate-cert.sh + echo "Deploy server certificates into user(test) namespaces" + kubectl apply -f ${REPO_ROOT_DIR}/test/config/tls/secret.yaml echo "Patch to activator to serve TLS" kubectl apply -n ${SYSTEM_NAMESPACE} -f ${REPO_ROOT_DIR}/test/config/tls/config-network.yaml kubectl delete pod -n ${SYSTEM_NAMESPACE} -l app=activator + + kubectl wait --timeout=60s --for=condition=Available deployment -n ${SYSTEM_NAMESPACE} activator fi } diff --git a/test/generate-cert.sh b/test/generate-cert.sh deleted file mode 100755 index 5569f166ad32..000000000000 --- a/test/generate-cert.sh +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env bash - -# Copyright 2022 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -SYSTEM_NAMESPACE="${SYSTEM_NAMESPACE:-knative-serving}" -TEST_NAMESPACE=serving-tests -TEST_NAMESPACE_ALT=serving-tests-alt -out_dir="$(mktemp -d /tmp/certs-XXX)" -san="knative" - -# Generate Root key and cert. -openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=Example/CN=Example' -keyout "${out_dir}"/root.key -out "${out_dir}"/root.crt - -# Create server key -openssl req -out "${out_dir}"/tls.csr -newkey rsa:2048 -nodes -keyout "${out_dir}"/tls.key -subj "/CN=Example/O=Example" -addext "subjectAltName = DNS:$san" - -# Create server certs -openssl x509 -req -extfile <(printf "subjectAltName=DNS:$san") -days 365 -in "${out_dir}"/tls.csr -CA "${out_dir}"/root.crt -CAkey "${out_dir}"/root.key -CAcreateserial -out "${out_dir}"/tls.crt - -# Create secret -kubectl create -n ${SYSTEM_NAMESPACE} secret generic serving-ca \ - --from-file=ca.crt="${out_dir}"/root.crt --dry-run=client -o yaml | kubectl apply -f - - -kubectl create -n ${SYSTEM_NAMESPACE} secret tls server-certs \ - --key="${out_dir}"/tls.key \ - --cert="${out_dir}"/tls.crt --dry-run=client -o yaml | kubectl apply -f - - -# Create secrets for test namespaces -kubectl create -n ${TEST_NAMESPACE} secret tls server-certs \ - --key="${out_dir}"/tls.key \ - --cert="${out_dir}"/tls.crt --dry-run=client -o yaml | kubectl apply -f - - -kubectl create -n ${TEST_NAMESPACE_ALT} secret tls server-certs \ - --key="${out_dir}"/tls.key \ - --cert="${out_dir}"/tls.crt --dry-run=client -o yaml | kubectl apply -f - diff --git a/test/ha/ha.go b/test/ha/ha.go index 4d0706815325..c519d5b0abaf 100644 --- a/test/ha/ha.go +++ b/test/ha/ha.go @@ -37,7 +37,7 @@ import ( const ( // NumControllerReconcilers is the number of controllers run by ./cmd/controller/main.go. // It is exported so the tests from cmd/controller/main.go can ensure we keep it in sync. - NumControllerReconcilers = 8 + NumControllerReconcilers = 9 ) func createPizzaPlanetService(t *testing.T, fopt ...rtesting.ServiceOption) (test.ResourceNames, *v1test.ResourceObjects) { diff --git a/third_party/VENDOR-LICENSE/knative.dev/control-protocol/pkg/certificates/LICENSE b/third_party/VENDOR-LICENSE/knative.dev/control-protocol/pkg/certificates/LICENSE new file mode 100644 index 000000000000..261eeb9e9f8b --- /dev/null +++ b/third_party/VENDOR-LICENSE/knative.dev/control-protocol/pkg/certificates/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/third_party/kourier-latest/kourier.yaml b/third_party/kourier-latest/kourier.yaml index 939df5c04925..a6f9879e879b 100644 --- a/third_party/kourier-latest/kourier.yaml +++ b/third_party/kourier-latest/kourier.yaml @@ -299,7 +299,7 @@ spec: app: net-kourier-controller spec: containers: - - image: gcr.io/knative-nightly/knative.dev/net-kourier/cmd/kourier@sha256:5216c4465db7932d77754059d0016e6b6f8a39b4189cd9234c821c1dfe8342cc + - image: gcr.io/gcp-compute-engine-223401/kourier-b74c3918b7eee585f87df62ccd297dc8@sha256:5bd5fb08ebf83c27f4f0a05ba893f0bd0bc29d9327c996e7de6c79ce378142a3 name: controller env: - name: CERTS_SECRET_NAMESPACE diff --git a/vendor/knative.dev/control-protocol/LICENSE b/vendor/knative.dev/control-protocol/LICENSE new file mode 100644 index 000000000000..261eeb9e9f8b --- /dev/null +++ b/vendor/knative.dev/control-protocol/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/knative.dev/control-protocol/pkg/certificates/certs.go b/vendor/knative.dev/control-protocol/pkg/certificates/certs.go new file mode 100644 index 000000000000..9f79c827f294 --- /dev/null +++ b/vendor/knative.dev/control-protocol/pkg/certificates/certs.go @@ -0,0 +1,221 @@ +/* +Copyright 2021 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package certificates + +import ( + "context" + "crypto/rand" + "crypto/rsa" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "errors" + "fmt" + "math/big" + "time" + + "go.uber.org/zap" + "knative.dev/pkg/logging" +) + +var randReader = rand.Reader +var serialNumberLimit = new(big.Int).Lsh(big.NewInt(1), 128) + +// Copy-pasted from https://github.com/knative/pkg/blob/975a1cf9e4470b26ce54d9cc628dbd50716b6b95/webhook/certificates/resources/certs.go +func createCertTemplate(expirationInterval time.Duration) (*x509.Certificate, error) { + serialNumber, err := rand.Int(randReader, serialNumberLimit) + if err != nil { + return nil, errors.New("failed to generate serial number: " + err.Error()) + } + + tmpl := x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{ + Organization: []string{Organization}, + CommonName: "control-plane", + }, + SignatureAlgorithm: x509.SHA256WithRSA, + NotBefore: time.Now(), + NotAfter: time.Now().Add(expirationInterval), + BasicConstraintsValid: true, + DNSNames: []string{FakeDnsName}, + } + return &tmpl, nil +} + +// Create cert template suitable for CA and hence signing +func createCACertTemplate(expirationInterval time.Duration) (*x509.Certificate, error) { + rootCert, err := createCertTemplate(expirationInterval) + if err != nil { + return nil, err + } + // Make it into a CA cert and change it so we can use it to sign certs + rootCert.IsCA = true + rootCert.KeyUsage = x509.KeyUsageCertSign | x509.KeyUsageDigitalSignature + rootCert.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth} + return rootCert, nil +} + +// Create cert template that we can use on the server for TLS +func createServerCertTemplate(expirationInterval time.Duration) (*x509.Certificate, error) { + serverCert, err := createCertTemplate(expirationInterval) + if err != nil { + return nil, err + } + serverCert.KeyUsage = x509.KeyUsageDigitalSignature + serverCert.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth} + return serverCert, err +} + +// Create cert template that we can use on the server for TLS +func createClientCertTemplate(expirationInterval time.Duration) (*x509.Certificate, error) { + serverCert, err := createCertTemplate(expirationInterval) + if err != nil { + return nil, err + } + serverCert.KeyUsage = x509.KeyUsageDigitalSignature + serverCert.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth} + return serverCert, err +} + +func createCert(template, parent *x509.Certificate, pub, parentPriv interface{}) (cert *x509.Certificate, certPEM *pem.Block, err error) { + certDER, err := x509.CreateCertificate(rand.Reader, template, parent, pub, parentPriv) + if err != nil { + return + } + cert, err = x509.ParseCertificate(certDER) + if err != nil { + return + } + certPEM = &pem.Block{Type: "CERTIFICATE", Bytes: certDER} + return +} + +// CreateCACerts generates the root CA cert +func CreateCACerts(ctx context.Context, expirationInterval time.Duration) (*KeyPair, error) { + logger := logging.FromContext(ctx) + caKeyPair, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + logger.Errorw("error generating random key", zap.Error(err)) + return nil, err + } + + rootCertTmpl, err := createCACertTemplate(expirationInterval) + if err != nil { + logger.Errorw("error generating CA cert", zap.Error(err)) + return nil, err + } + + _, caCertPem, err := createCert(rootCertTmpl, rootCertTmpl, &caKeyPair.PublicKey, caKeyPair) + if err != nil { + logger.Errorw("error signing the CA cert", zap.Error(err)) + return nil, err + } + caPrivateKeyPem := &pem.Block{ + Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(caKeyPair), + } + return NewKeyPair(caPrivateKeyPem, caCertPem), nil +} + +// CreateControlPlaneCert generates the certificate for the client +func CreateControlPlaneCert(ctx context.Context, caKey *rsa.PrivateKey, caCertificate *x509.Certificate, expirationInterval time.Duration) (*KeyPair, error) { + logger := logging.FromContext(ctx) + + // Then create the private key for the serving cert + clientKey, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + logger.Errorw("error generating random key", zap.Error(err)) + return nil, err + } + clientCertTemplate, err := createClientCertTemplate(expirationInterval) + if err != nil { + logger.Errorw("failed to create the server certificate template", zap.Error(err)) + return nil, err + } + + // create a certificate which wraps the server's public key, sign it with the CA private key + _, clientCertPEM, err := createCert(clientCertTemplate, caCertificate, &clientKey.PublicKey, caKey) + if err != nil { + logger.Errorw("error signing client certificate template", zap.Error(err)) + return nil, err + } + privateClientKeyPEM := &pem.Block{ + Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(clientKey), + } + return NewKeyPair(privateClientKeyPEM, clientCertPEM), nil +} + +// CreateDataPlaneCert generates the certificate for the server +func CreateDataPlaneCert(ctx context.Context, caKey *rsa.PrivateKey, caCertificate *x509.Certificate, expirationInterval time.Duration) (*KeyPair, error) { + logger := logging.FromContext(ctx) + + // Then create the private key for the serving cert + serverKey, err := rsa.GenerateKey(rand.Reader, 2048) + if err != nil { + logger.Errorw("error generating random key", zap.Error(err)) + return nil, err + } + serverCertTemplate, err := createServerCertTemplate(expirationInterval) + if err != nil { + logger.Errorw("failed to create the server certificate template", zap.Error(err)) + return nil, err + } + + // create a certificate which wraps the server's public key, sign it with the CA private key + _, serverCertPEM, err := createCert(serverCertTemplate, caCertificate, &serverKey.PublicKey, caKey) + if err != nil { + logger.Errorw("error signing server certificate template", zap.Error(err)) + return nil, err + } + privateServerKeyPEM := &pem.Block{ + Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(serverKey), + } + return NewKeyPair(privateServerKeyPEM, serverCertPEM), nil +} + +// ParseCert parses a certificate/private key pair from serialized pem blocks +func ParseCert(certPemBytes []byte, privateKeyPemBytes []byte) (*x509.Certificate, *rsa.PrivateKey, error) { + certBlock, _ := pem.Decode(certPemBytes) + if certBlock == nil { + return nil, nil, fmt.Errorf("decoding the cert block returned nil") + } + if certBlock.Type != "CERTIFICATE" { + return nil, nil, fmt.Errorf("bad pem block, expecting type 'CERTIFICATE', found %q", certBlock.Type) + } + cert, err := x509.ParseCertificate(certBlock.Bytes) + if err != nil { + return nil, nil, err + } + + pkBlock, _ := pem.Decode(privateKeyPemBytes) + if pkBlock == nil { + return nil, nil, fmt.Errorf("decoding the pk block returned nil") + } + if pkBlock.Type != "RSA PRIVATE KEY" { + return nil, nil, fmt.Errorf("bad pem block, expecting type 'RSA PRIVATE KEY', found %q", pkBlock.Type) + } + pk, err := x509.ParsePKCS1PrivateKey(pkBlock.Bytes) + return cert, pk, err +} + +// ValidateCert checks the expiration of the certificate +func ValidateCert(cert *x509.Certificate, rotationThreshold time.Duration) error { + if !cert.NotAfter.After(time.Now().Add(rotationThreshold)) { + return fmt.Errorf("certificate is going to expire %v", cert.NotAfter) + } + return nil +} diff --git a/vendor/knative.dev/control-protocol/pkg/certificates/constants.go b/vendor/knative.dev/control-protocol/pkg/certificates/constants.go new file mode 100644 index 000000000000..77f18c8dfb55 --- /dev/null +++ b/vendor/knative.dev/control-protocol/pkg/certificates/constants.go @@ -0,0 +1,26 @@ +/* +Copyright 2021 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package certificates + +const ( + Organization = "knative.dev" + FakeDnsName = "data-plane." + Organization + + SecretCaCertKey = "ca-cert.pem" + SecretCertKey = "public-cert.pem" + SecretPKKey = "private-key.pem" +) diff --git a/vendor/knative.dev/control-protocol/pkg/certificates/key_pair.go b/vendor/knative.dev/control-protocol/pkg/certificates/key_pair.go new file mode 100644 index 000000000000..67abc42dd42a --- /dev/null +++ b/vendor/knative.dev/control-protocol/pkg/certificates/key_pair.go @@ -0,0 +1,60 @@ +/* +Copyright 2021 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package certificates + +import ( + "crypto/rsa" + "crypto/x509" + "encoding/pem" +) + +type KeyPair struct { + privateKeyBlock *pem.Block + privateKeyPemBytes []byte + + certBlock *pem.Block + certPemBytes []byte +} + +func NewKeyPair(privateKey *pem.Block, cert *pem.Block) *KeyPair { + return &KeyPair{ + privateKeyBlock: privateKey, + privateKeyPemBytes: pem.EncodeToMemory(privateKey), + certBlock: cert, + certPemBytes: pem.EncodeToMemory(cert), + } +} + +func (kh *KeyPair) PrivateKey() *pem.Block { + return kh.privateKeyBlock +} + +func (kh *KeyPair) PrivateKeyBytes() []byte { + return kh.privateKeyPemBytes +} + +func (kh *KeyPair) Cert() *pem.Block { + return kh.certBlock +} + +func (kh *KeyPair) CertBytes() []byte { + return kh.certPemBytes +} + +func (kh *KeyPair) Parse() (*x509.Certificate, *rsa.PrivateKey, error) { + return ParseCert(kh.certPemBytes, kh.privateKeyPemBytes) +} diff --git a/vendor/knative.dev/control-protocol/pkg/certificates/reconciler/certificates.go b/vendor/knative.dev/control-protocol/pkg/certificates/reconciler/certificates.go new file mode 100644 index 000000000000..a4f1329b659d --- /dev/null +++ b/vendor/knative.dev/control-protocol/pkg/certificates/reconciler/certificates.go @@ -0,0 +1,184 @@ +/* +Copyright 2021 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package sample + +import ( + "context" + "crypto/rsa" + "crypto/x509" + "fmt" + "time" + + "go.uber.org/zap" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/kubernetes" + listerv1 "k8s.io/client-go/listers/core/v1" + pkgreconciler "knative.dev/pkg/reconciler" + "knative.dev/pkg/system" + + reconcilersecret "knative.dev/pkg/client/injection/kube/reconciler/core/v1/secret" + + "knative.dev/control-protocol/pkg/certificates" +) + +const ( + caExpirationInterval = time.Hour * 24 * 365 * 10 // 10 years + expirationInterval = time.Hour * 24 * 30 // 30 days + rotationThreshold = 10 * time.Minute + + controlPlaneSecretType = "control-plane" + dataPlaneSecretType = "data-plane" +) + +// Reconciler reconciles a SampleSource object +type reconciler struct { + client kubernetes.Interface + secretLister listerv1.SecretLister + caSecretName string + secretTypeLabelName string + enqueueAfter func(key types.NamespacedName, delay time.Duration) + + logger *zap.SugaredLogger +} + +// Check that our Reconciler implements Interface +var _ reconcilersecret.Interface = (*reconciler)(nil) + +// ReconcileKind implements Interface.ReconcileKind. +func (r *reconciler) ReconcileKind(ctx context.Context, secret *corev1.Secret) pkgreconciler.Event { + // This should not happen, but it happens :) https://github.com/knative/pkg/issues/1891 + if !r.shouldReconcile(secret) { + r.logger.Infof("Skipping reconciling secret %q:%q", secret.Namespace, secret.Name) + return nil + } + r.logger.Infof("Updating secret %q:%q", secret.Namespace, secret.Name) + + // Reconcile CA secret first + caSecret, err := r.secretLister.Secrets(system.Namespace()).Get(r.caSecretName) + if apierrors.IsNotFound(err) { + // The secret should be created explicitly by a higher-level system + // that's responsible for install/updates. We simply populate the + // secret information. + return nil + } else if err != nil { + r.logger.Errorf("Error accessing CA certificate secret %q %q: %v", system.Namespace(), r.caSecretName, err) + return err + } + caCert, caPk, err := parseAndValidateSecret(caSecret, false) + if err != nil { + r.logger.Infof("CA cert invalid: %v", err) + + // We need to generate a new CA cert, then shortcircuit the reconciler + keyPair, err := certificates.CreateCACerts(ctx, caExpirationInterval) + if err != nil { + return fmt.Errorf("cannot generate the CA cert: %v", err) + } + return r.commitUpdatedSecret(ctx, caSecret, keyPair, nil) + } + + // Reconcile the provided secret + cert, _, err := parseAndValidateSecret(secret, true) + if err != nil { + r.logger.Infof("Secret invalid: %v", err) + + // Check the secret to reconcile type + var keyPair *certificates.KeyPair + if secret.Labels[r.secretTypeLabelName] == dataPlaneSecretType { + keyPair, err = certificates.CreateDataPlaneCert(ctx, caPk, caCert, expirationInterval) + } else if secret.Labels[r.secretTypeLabelName] == controlPlaneSecretType { + keyPair, err = certificates.CreateControlPlaneCert(ctx, caPk, caCert, expirationInterval) + } else { + return fmt.Errorf("unknown cert type: %v", r.secretTypeLabelName) + } + if err != nil { + return fmt.Errorf("cannot generate the cert: %v", err) + } + err = r.commitUpdatedSecret(ctx, secret, keyPair, caSecret.Data[certificates.SecretCertKey]) + if err != nil { + return err + } + cert, _, err = certificates.ParseCert(keyPair.CertBytes(), keyPair.PrivateKeyBytes()) + if err != nil { + return err + } + } + + r.enqueueBeforeExpiration(secret, cert) + + return nil +} + +func parseAndValidateSecret(secret *corev1.Secret, shouldContainCaCert bool) (*x509.Certificate, *rsa.PrivateKey, error) { + certBytes, ok := secret.Data[certificates.SecretCertKey] + if !ok { + return nil, nil, fmt.Errorf("missing cert bytes") + } + pkBytes, ok := secret.Data[certificates.SecretPKKey] + if !ok { + return nil, nil, fmt.Errorf("missing pk bytes") + } + if shouldContainCaCert { + if _, ok := secret.Data[certificates.SecretCaCertKey]; !ok { + return nil, nil, fmt.Errorf("missing ca cert bytes") + } + } + + caCert, caPk, err := certificates.ParseCert(certBytes, pkBytes) + if err != nil { + return nil, nil, err + } + if err := certificates.ValidateCert(caCert, rotationThreshold); err != nil { + return nil, nil, err + } + return caCert, caPk, nil +} + +func (r *reconciler) enqueueBeforeExpiration(secret *corev1.Secret, cert *x509.Certificate) { + when := cert.NotAfter.Add(-rotationThreshold).Add(1 * time.Second) // Make sure to enqueue it after the rotation threshold + r.enqueueAfter(types.NamespacedName{ + Namespace: secret.Namespace, + Name: secret.Name, + }, when.Sub(time.Now())) +} + +func (r *reconciler) commitUpdatedSecret(ctx context.Context, secret *corev1.Secret, keyPair *certificates.KeyPair, caCert []byte) error { + // Don't modify the informer copy. + secret = secret.DeepCopy() + + secret.Data = make(map[string][]byte, 3) + secret.Data[certificates.SecretCertKey] = keyPair.CertBytes() + secret.Data[certificates.SecretPKKey] = keyPair.PrivateKeyBytes() + if caCert != nil { + secret.Data[certificates.SecretCaCertKey] = caCert + } + + _, err := r.client.CoreV1().Secrets(secret.Namespace).Update(ctx, secret, metav1.UpdateOptions{}) + return err +} + +func (r *reconciler) shouldReconcile(secret *corev1.Secret) bool { + // Is CA secret? + if secret.Name == r.caSecretName && secret.Namespace == system.Namespace() { + return false + } + + _, hasLabel := secret.Labels[r.secretTypeLabelName] + return hasLabel +} diff --git a/vendor/knative.dev/control-protocol/pkg/certificates/reconciler/controller.go b/vendor/knative.dev/control-protocol/pkg/certificates/reconciler/controller.go new file mode 100644 index 000000000000..66e666aa5209 --- /dev/null +++ b/vendor/knative.dev/control-protocol/pkg/certificates/reconciler/controller.go @@ -0,0 +1,86 @@ +/* +Copyright 2021 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package sample + +import ( + "context" + + "k8s.io/client-go/tools/cache" + kubeclient "knative.dev/pkg/client/injection/kube/client" + "knative.dev/pkg/client/injection/kube/reconciler/core/v1/secret" + "knative.dev/pkg/injection" + "knative.dev/pkg/system" + + "knative.dev/pkg/configmap" + "knative.dev/pkg/controller" + "knative.dev/pkg/logging" + + pkgreconciler "knative.dev/pkg/reconciler" + + secretinformer "knative.dev/pkg/client/injection/kube/informers/core/v1/secret" +) + +const ( + caSecretNamePostfix = "-ctrl-ca" + secretLabelNamePostfix = "-ctrl" +) + +// NewControllerFactory generates a ControllerConstructor for the control certificates reconciler. +func NewControllerFactory(componentName string) injection.ControllerConstructor { + return func( + ctx context.Context, + cmw configmap.Watcher, + ) *controller.Impl { + ctx = logging.WithLogger(ctx, logging.FromContext(ctx).Named("ctrl-secrets-controller")) + + secretInformer := secretinformer.Get(ctx) + + caSecretName := componentName + caSecretNamePostfix + labelName := componentName + secretLabelNamePostfix + + r := &reconciler{ + client: kubeclient.Get(ctx), + + secretLister: secretInformer.Lister(), + caSecretName: caSecretName, + secretTypeLabelName: labelName, + + logger: logging.FromContext(ctx), + } + + impl := secret.NewImpl(ctx, r) + r.enqueueAfter = impl.EnqueueKeyAfter + + logging.FromContext(ctx).Info("Setting up event handlers") + + // If the ca secret changes, global resync + secretInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{ + FilterFunc: controller.FilterWithNameAndNamespace(system.Namespace(), caSecretName), + Handler: controller.HandleAll(func(i interface{}) { + impl.FilteredGlobalResync(pkgreconciler.LabelExistsFilterFunc(labelName), secretInformer.Informer()) + }), + }) + + // Enqueue only secrets with expected label + secretInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{ + FilterFunc: pkgreconciler.LabelExistsFilterFunc(labelName), + Handler: controller.HandleAll(impl.Enqueue), + }) + + return impl + } +} diff --git a/vendor/knative.dev/pkg/client/injection/kube/informers/core/v1/secret/secret.go b/vendor/knative.dev/pkg/client/injection/kube/informers/core/v1/secret/secret.go new file mode 100644 index 000000000000..715fbac5fa7b --- /dev/null +++ b/vendor/knative.dev/pkg/client/injection/kube/informers/core/v1/secret/secret.go @@ -0,0 +1,116 @@ +/* +Copyright 2021 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package secret + +import ( + context "context" + + apicorev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + v1 "k8s.io/client-go/informers/core/v1" + kubernetes "k8s.io/client-go/kubernetes" + corev1 "k8s.io/client-go/listers/core/v1" + cache "k8s.io/client-go/tools/cache" + client "knative.dev/pkg/client/injection/kube/client" + factory "knative.dev/pkg/client/injection/kube/informers/factory" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + logging "knative.dev/pkg/logging" +) + +func init() { + injection.Default.RegisterInformer(withInformer) + injection.Dynamic.RegisterDynamicInformer(withDynamicInformer) +} + +// Key is used for associating the Informer inside the context.Context. +type Key struct{} + +func withInformer(ctx context.Context) (context.Context, controller.Informer) { + f := factory.Get(ctx) + inf := f.Core().V1().Secrets() + return context.WithValue(ctx, Key{}, inf), inf.Informer() +} + +func withDynamicInformer(ctx context.Context) context.Context { + inf := &wrapper{client: client.Get(ctx), resourceVersion: injection.GetResourceVersion(ctx)} + return context.WithValue(ctx, Key{}, inf) +} + +// Get extracts the typed informer from the context. +func Get(ctx context.Context) v1.SecretInformer { + untyped := ctx.Value(Key{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch k8s.io/client-go/informers/core/v1.SecretInformer from context.") + } + return untyped.(v1.SecretInformer) +} + +type wrapper struct { + client kubernetes.Interface + + namespace string + + resourceVersion string +} + +var _ v1.SecretInformer = (*wrapper)(nil) +var _ corev1.SecretLister = (*wrapper)(nil) + +func (w *wrapper) Informer() cache.SharedIndexInformer { + return cache.NewSharedIndexInformer(nil, &apicorev1.Secret{}, 0, nil) +} + +func (w *wrapper) Lister() corev1.SecretLister { + return w +} + +func (w *wrapper) Secrets(namespace string) corev1.SecretNamespaceLister { + return &wrapper{client: w.client, namespace: namespace, resourceVersion: w.resourceVersion} +} + +// SetResourceVersion allows consumers to adjust the minimum resourceVersion +// used by the underlying client. It is not accessible via the standard +// lister interface, but can be accessed through a user-defined interface and +// an implementation check e.g. rvs, ok := foo.(ResourceVersionSetter) +func (w *wrapper) SetResourceVersion(resourceVersion string) { + w.resourceVersion = resourceVersion +} + +func (w *wrapper) List(selector labels.Selector) (ret []*apicorev1.Secret, err error) { + lo, err := w.client.CoreV1().Secrets(w.namespace).List(context.TODO(), metav1.ListOptions{ + LabelSelector: selector.String(), + ResourceVersion: w.resourceVersion, + }) + if err != nil { + return nil, err + } + for idx := range lo.Items { + ret = append(ret, &lo.Items[idx]) + } + return ret, nil +} + +func (w *wrapper) Get(name string) (*apicorev1.Secret, error) { + return w.client.CoreV1().Secrets(w.namespace).Get(context.TODO(), name, metav1.GetOptions{ + ResourceVersion: w.resourceVersion, + }) +} diff --git a/vendor/knative.dev/pkg/client/injection/kube/reconciler/core/v1/secret/controller.go b/vendor/knative.dev/pkg/client/injection/kube/reconciler/core/v1/secret/controller.go new file mode 100644 index 000000000000..0df152ebaf30 --- /dev/null +++ b/vendor/knative.dev/pkg/client/injection/kube/reconciler/core/v1/secret/controller.go @@ -0,0 +1,157 @@ +/* +Copyright 2021 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package secret + +import ( + context "context" + fmt "fmt" + reflect "reflect" + strings "strings" + + zap "go.uber.org/zap" + corev1 "k8s.io/api/core/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + scheme "k8s.io/client-go/kubernetes/scheme" + v1 "k8s.io/client-go/kubernetes/typed/core/v1" + record "k8s.io/client-go/tools/record" + client "knative.dev/pkg/client/injection/kube/client" + secret "knative.dev/pkg/client/injection/kube/informers/core/v1/secret" + controller "knative.dev/pkg/controller" + logging "knative.dev/pkg/logging" + logkey "knative.dev/pkg/logging/logkey" + reconciler "knative.dev/pkg/reconciler" +) + +const ( + defaultControllerAgentName = "secret-controller" + defaultFinalizerName = "secrets.core" +) + +// NewImpl returns a controller.Impl that handles queuing and feeding work from +// the queue through an implementation of controller.Reconciler, delegating to +// the provided Interface and optional Finalizer methods. OptionsFn is used to return +// controller.ControllerOptions to be used by the internal reconciler. +func NewImpl(ctx context.Context, r Interface, optionsFns ...controller.OptionsFn) *controller.Impl { + logger := logging.FromContext(ctx) + + // Check the options function input. It should be 0 or 1. + if len(optionsFns) > 1 { + logger.Fatal("Up to one options function is supported, found: ", len(optionsFns)) + } + + secretInformer := secret.Get(ctx) + + lister := secretInformer.Lister() + + var promoteFilterFunc func(obj interface{}) bool + + rec := &reconcilerImpl{ + LeaderAwareFuncs: reconciler.LeaderAwareFuncs{ + PromoteFunc: func(bkt reconciler.Bucket, enq func(reconciler.Bucket, types.NamespacedName)) error { + all, err := lister.List(labels.Everything()) + if err != nil { + return err + } + for _, elt := range all { + if promoteFilterFunc != nil { + if ok := promoteFilterFunc(elt); !ok { + continue + } + } + enq(bkt, types.NamespacedName{ + Namespace: elt.GetNamespace(), + Name: elt.GetName(), + }) + } + return nil + }, + }, + Client: client.Get(ctx), + Lister: lister, + reconciler: r, + finalizerName: defaultFinalizerName, + } + + ctrType := reflect.TypeOf(r).Elem() + ctrTypeName := fmt.Sprintf("%s.%s", ctrType.PkgPath(), ctrType.Name()) + ctrTypeName = strings.ReplaceAll(ctrTypeName, "/", ".") + + logger = logger.With( + zap.String(logkey.ControllerType, ctrTypeName), + zap.String(logkey.Kind, "core.Secret"), + ) + + impl := controller.NewContext(ctx, rec, controller.ControllerOptions{WorkQueueName: ctrTypeName, Logger: logger}) + agentName := defaultControllerAgentName + + // Pass impl to the options. Save any optional results. + for _, fn := range optionsFns { + opts := fn(impl) + if opts.ConfigStore != nil { + rec.configStore = opts.ConfigStore + } + if opts.FinalizerName != "" { + rec.finalizerName = opts.FinalizerName + } + if opts.AgentName != "" { + agentName = opts.AgentName + } + if opts.DemoteFunc != nil { + rec.DemoteFunc = opts.DemoteFunc + } + if opts.PromoteFilterFunc != nil { + promoteFilterFunc = opts.PromoteFilterFunc + } + } + + rec.Recorder = createRecorder(ctx, agentName) + + return impl +} + +func createRecorder(ctx context.Context, agentName string) record.EventRecorder { + logger := logging.FromContext(ctx) + + recorder := controller.GetEventRecorder(ctx) + if recorder == nil { + // Create event broadcaster + logger.Debug("Creating event broadcaster") + eventBroadcaster := record.NewBroadcaster() + watches := []watch.Interface{ + eventBroadcaster.StartLogging(logger.Named("event-broadcaster").Infof), + eventBroadcaster.StartRecordingToSink( + &v1.EventSinkImpl{Interface: client.Get(ctx).CoreV1().Events("")}), + } + recorder = eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: agentName}) + go func() { + <-ctx.Done() + for _, w := range watches { + w.Stop() + } + }() + } + + return recorder +} + +func init() { + scheme.AddToScheme(scheme.Scheme) +} diff --git a/vendor/knative.dev/pkg/client/injection/kube/reconciler/core/v1/secret/reconciler.go b/vendor/knative.dev/pkg/client/injection/kube/reconciler/core/v1/secret/reconciler.go new file mode 100644 index 000000000000..a8f2806f4818 --- /dev/null +++ b/vendor/knative.dev/pkg/client/injection/kube/reconciler/core/v1/secret/reconciler.go @@ -0,0 +1,377 @@ +/* +Copyright 2021 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package secret + +import ( + context "context" + json "encoding/json" + fmt "fmt" + + zap "go.uber.org/zap" + v1 "k8s.io/api/core/v1" + errors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + sets "k8s.io/apimachinery/pkg/util/sets" + kubernetes "k8s.io/client-go/kubernetes" + corev1 "k8s.io/client-go/listers/core/v1" + record "k8s.io/client-go/tools/record" + controller "knative.dev/pkg/controller" + logging "knative.dev/pkg/logging" + reconciler "knative.dev/pkg/reconciler" +) + +// Interface defines the strongly typed interfaces to be implemented by a +// controller reconciling v1.Secret. +type Interface interface { + // ReconcileKind implements custom logic to reconcile v1.Secret. Any changes + // to the objects .Status or .Finalizers will be propagated to the stored + // object. It is recommended that implementors do not call any update calls + // for the Kind inside of ReconcileKind, it is the responsibility of the calling + // controller to propagate those properties. The resource passed to ReconcileKind + // will always have an empty deletion timestamp. + ReconcileKind(ctx context.Context, o *v1.Secret) reconciler.Event +} + +// Finalizer defines the strongly typed interfaces to be implemented by a +// controller finalizing v1.Secret. +type Finalizer interface { + // FinalizeKind implements custom logic to finalize v1.Secret. Any changes + // to the objects .Status or .Finalizers will be ignored. Returning a nil or + // Normal type reconciler.Event will allow the finalizer to be deleted on + // the resource. The resource passed to FinalizeKind will always have a set + // deletion timestamp. + FinalizeKind(ctx context.Context, o *v1.Secret) reconciler.Event +} + +// ReadOnlyInterface defines the strongly typed interfaces to be implemented by a +// controller reconciling v1.Secret if they want to process resources for which +// they are not the leader. +type ReadOnlyInterface interface { + // ObserveKind implements logic to observe v1.Secret. + // This method should not write to the API. + ObserveKind(ctx context.Context, o *v1.Secret) reconciler.Event +} + +type doReconcile func(ctx context.Context, o *v1.Secret) reconciler.Event + +// reconcilerImpl implements controller.Reconciler for v1.Secret resources. +type reconcilerImpl struct { + // LeaderAwareFuncs is inlined to help us implement reconciler.LeaderAware. + reconciler.LeaderAwareFuncs + + // Client is used to write back status updates. + Client kubernetes.Interface + + // Listers index properties about resources. + Lister corev1.SecretLister + + // Recorder is an event recorder for recording Event resources to the + // Kubernetes API. + Recorder record.EventRecorder + + // configStore allows for decorating a context with config maps. + // +optional + configStore reconciler.ConfigStore + + // reconciler is the implementation of the business logic of the resource. + reconciler Interface + + // finalizerName is the name of the finalizer to reconcile. + finalizerName string +} + +// Check that our Reconciler implements controller.Reconciler. +var _ controller.Reconciler = (*reconcilerImpl)(nil) + +// Check that our generated Reconciler is always LeaderAware. +var _ reconciler.LeaderAware = (*reconcilerImpl)(nil) + +func NewReconciler(ctx context.Context, logger *zap.SugaredLogger, client kubernetes.Interface, lister corev1.SecretLister, recorder record.EventRecorder, r Interface, options ...controller.Options) controller.Reconciler { + // Check the options function input. It should be 0 or 1. + if len(options) > 1 { + logger.Fatal("Up to one options struct is supported, found: ", len(options)) + } + + // Fail fast when users inadvertently implement the other LeaderAware interface. + // For the typed reconcilers, Promote shouldn't take any arguments. + if _, ok := r.(reconciler.LeaderAware); ok { + logger.Fatalf("%T implements the incorrect LeaderAware interface. Promote() should not take an argument as genreconciler handles the enqueuing automatically.", r) + } + + rec := &reconcilerImpl{ + LeaderAwareFuncs: reconciler.LeaderAwareFuncs{ + PromoteFunc: func(bkt reconciler.Bucket, enq func(reconciler.Bucket, types.NamespacedName)) error { + all, err := lister.List(labels.Everything()) + if err != nil { + return err + } + for _, elt := range all { + // TODO: Consider letting users specify a filter in options. + enq(bkt, types.NamespacedName{ + Namespace: elt.GetNamespace(), + Name: elt.GetName(), + }) + } + return nil + }, + }, + Client: client, + Lister: lister, + Recorder: recorder, + reconciler: r, + finalizerName: defaultFinalizerName, + } + + for _, opts := range options { + if opts.ConfigStore != nil { + rec.configStore = opts.ConfigStore + } + if opts.FinalizerName != "" { + rec.finalizerName = opts.FinalizerName + } + if opts.DemoteFunc != nil { + rec.DemoteFunc = opts.DemoteFunc + } + } + + return rec +} + +// Reconcile implements controller.Reconciler +func (r *reconcilerImpl) Reconcile(ctx context.Context, key string) error { + logger := logging.FromContext(ctx) + + // Initialize the reconciler state. This will convert the namespace/name + // string into a distinct namespace and name, determine if this instance of + // the reconciler is the leader, and any additional interfaces implemented + // by the reconciler. Returns an error is the resource key is invalid. + s, err := newState(key, r) + if err != nil { + logger.Error("Invalid resource key: ", key) + return nil + } + + // If we are not the leader, and we don't implement either ReadOnly + // observer interfaces, then take a fast-path out. + if s.isNotLeaderNorObserver() { + return controller.NewSkipKey(key) + } + + // If configStore is set, attach the frozen configuration to the context. + if r.configStore != nil { + ctx = r.configStore.ToContext(ctx) + } + + // Add the recorder to context. + ctx = controller.WithEventRecorder(ctx, r.Recorder) + + // Get the resource with this namespace/name. + + getter := r.Lister.Secrets(s.namespace) + + original, err := getter.Get(s.name) + + if errors.IsNotFound(err) { + // The resource may no longer exist, in which case we stop processing and call + // the ObserveDeletion handler if appropriate. + logger.Debugf("Resource %q no longer exists", key) + if del, ok := r.reconciler.(reconciler.OnDeletionInterface); ok { + return del.ObserveDeletion(ctx, types.NamespacedName{ + Namespace: s.namespace, + Name: s.name, + }) + } + return nil + } else if err != nil { + return err + } + + // Don't modify the informers copy. + resource := original.DeepCopy() + + var reconcileEvent reconciler.Event + + name, do := s.reconcileMethodFor(resource) + // Append the target method to the logger. + logger = logger.With(zap.String("targetMethod", name)) + switch name { + case reconciler.DoReconcileKind: + // Set and update the finalizer on resource if r.reconciler + // implements Finalizer. + if resource, err = r.setFinalizerIfFinalizer(ctx, resource); err != nil { + return fmt.Errorf("failed to set finalizers: %w", err) + } + + // Reconcile this copy of the resource and then write back any status + // updates regardless of whether the reconciliation errored out. + reconcileEvent = do(ctx, resource) + + case reconciler.DoFinalizeKind: + // For finalizing reconcilers, if this resource being marked for deletion + // and reconciled cleanly (nil or normal event), remove the finalizer. + reconcileEvent = do(ctx, resource) + + if resource, err = r.clearFinalizer(ctx, resource, reconcileEvent); err != nil { + return fmt.Errorf("failed to clear finalizers: %w", err) + } + + case reconciler.DoObserveKind: + // Observe any changes to this resource, since we are not the leader. + reconcileEvent = do(ctx, resource) + + } + + // Report the reconciler event, if any. + if reconcileEvent != nil { + var event *reconciler.ReconcilerEvent + if reconciler.EventAs(reconcileEvent, &event) { + logger.Infow("Returned an event", zap.Any("event", reconcileEvent)) + r.Recorder.Event(resource, event.EventType, event.Reason, event.Error()) + + // the event was wrapped inside an error, consider the reconciliation as failed + if _, isEvent := reconcileEvent.(*reconciler.ReconcilerEvent); !isEvent { + return reconcileEvent + } + return nil + } + + if controller.IsSkipKey(reconcileEvent) { + // This is a wrapped error, don't emit an event. + } else if ok, _ := controller.IsRequeueKey(reconcileEvent); ok { + // This is a wrapped error, don't emit an event. + } else { + logger.Errorw("Returned an error", zap.Error(reconcileEvent)) + r.Recorder.Event(resource, v1.EventTypeWarning, "InternalError", reconcileEvent.Error()) + } + return reconcileEvent + } + + return nil +} + +// updateFinalizersFiltered will update the Finalizers of the resource. +// TODO: this method could be generic and sync all finalizers. For now it only +// updates defaultFinalizerName or its override. +func (r *reconcilerImpl) updateFinalizersFiltered(ctx context.Context, resource *v1.Secret) (*v1.Secret, error) { + + getter := r.Lister.Secrets(resource.Namespace) + + actual, err := getter.Get(resource.Name) + if err != nil { + return resource, err + } + + // Don't modify the informers copy. + existing := actual.DeepCopy() + + var finalizers []string + + // If there's nothing to update, just return. + existingFinalizers := sets.NewString(existing.Finalizers...) + desiredFinalizers := sets.NewString(resource.Finalizers...) + + if desiredFinalizers.Has(r.finalizerName) { + if existingFinalizers.Has(r.finalizerName) { + // Nothing to do. + return resource, nil + } + // Add the finalizer. + finalizers = append(existing.Finalizers, r.finalizerName) + } else { + if !existingFinalizers.Has(r.finalizerName) { + // Nothing to do. + return resource, nil + } + // Remove the finalizer. + existingFinalizers.Delete(r.finalizerName) + finalizers = existingFinalizers.List() + } + + mergePatch := map[string]interface{}{ + "metadata": map[string]interface{}{ + "finalizers": finalizers, + "resourceVersion": existing.ResourceVersion, + }, + } + + patch, err := json.Marshal(mergePatch) + if err != nil { + return resource, err + } + + patcher := r.Client.CoreV1().Secrets(resource.Namespace) + + resourceName := resource.Name + updated, err := patcher.Patch(ctx, resourceName, types.MergePatchType, patch, metav1.PatchOptions{}) + if err != nil { + r.Recorder.Eventf(existing, v1.EventTypeWarning, "FinalizerUpdateFailed", + "Failed to update finalizers for %q: %v", resourceName, err) + } else { + r.Recorder.Eventf(updated, v1.EventTypeNormal, "FinalizerUpdate", + "Updated %q finalizers", resource.GetName()) + } + return updated, err +} + +func (r *reconcilerImpl) setFinalizerIfFinalizer(ctx context.Context, resource *v1.Secret) (*v1.Secret, error) { + if _, ok := r.reconciler.(Finalizer); !ok { + return resource, nil + } + + finalizers := sets.NewString(resource.Finalizers...) + + // If this resource is not being deleted, mark the finalizer. + if resource.GetDeletionTimestamp().IsZero() { + finalizers.Insert(r.finalizerName) + } + + resource.Finalizers = finalizers.List() + + // Synchronize the finalizers filtered by r.finalizerName. + return r.updateFinalizersFiltered(ctx, resource) +} + +func (r *reconcilerImpl) clearFinalizer(ctx context.Context, resource *v1.Secret, reconcileEvent reconciler.Event) (*v1.Secret, error) { + if _, ok := r.reconciler.(Finalizer); !ok { + return resource, nil + } + if resource.GetDeletionTimestamp().IsZero() { + return resource, nil + } + + finalizers := sets.NewString(resource.Finalizers...) + + if reconcileEvent != nil { + var event *reconciler.ReconcilerEvent + if reconciler.EventAs(reconcileEvent, &event) { + if event.EventType == v1.EventTypeNormal { + finalizers.Delete(r.finalizerName) + } + } + } else { + finalizers.Delete(r.finalizerName) + } + + resource.Finalizers = finalizers.List() + + // Synchronize the finalizers filtered by r.finalizerName. + return r.updateFinalizersFiltered(ctx, resource) +} diff --git a/vendor/knative.dev/pkg/client/injection/kube/reconciler/core/v1/secret/state.go b/vendor/knative.dev/pkg/client/injection/kube/reconciler/core/v1/secret/state.go new file mode 100644 index 000000000000..5bf83703726c --- /dev/null +++ b/vendor/knative.dev/pkg/client/injection/kube/reconciler/core/v1/secret/state.go @@ -0,0 +1,97 @@ +/* +Copyright 2021 The Knative Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package secret + +import ( + fmt "fmt" + + v1 "k8s.io/api/core/v1" + types "k8s.io/apimachinery/pkg/types" + cache "k8s.io/client-go/tools/cache" + reconciler "knative.dev/pkg/reconciler" +) + +// state is used to track the state of a reconciler in a single run. +type state struct { + // key is the original reconciliation key from the queue. + key string + // namespace is the namespace split from the reconciliation key. + namespace string + // name is the name split from the reconciliation key. + name string + // reconciler is the reconciler. + reconciler Interface + // roi is the read only interface cast of the reconciler. + roi ReadOnlyInterface + // isROI (Read Only Interface) the reconciler only observes reconciliation. + isROI bool + // isLeader the instance of the reconciler is the elected leader. + isLeader bool +} + +func newState(key string, r *reconcilerImpl) (*state, error) { + // Convert the namespace/name string into a distinct namespace and name. + namespace, name, err := cache.SplitMetaNamespaceKey(key) + if err != nil { + return nil, fmt.Errorf("invalid resource key: %s", key) + } + + roi, isROI := r.reconciler.(ReadOnlyInterface) + + isLeader := r.IsLeaderFor(types.NamespacedName{ + Namespace: namespace, + Name: name, + }) + + return &state{ + key: key, + namespace: namespace, + name: name, + reconciler: r.reconciler, + roi: roi, + isROI: isROI, + isLeader: isLeader, + }, nil +} + +// isNotLeaderNorObserver checks to see if this reconciler with the current +// state is enabled to do any work or not. +// isNotLeaderNorObserver returns true when there is no work possible for the +// reconciler. +func (s *state) isNotLeaderNorObserver() bool { + if !s.isLeader && !s.isROI { + // If we are not the leader, and we don't implement the ReadOnly + // interface, then take a fast-path out. + return true + } + return false +} + +func (s *state) reconcileMethodFor(o *v1.Secret) (string, doReconcile) { + if o.GetDeletionTimestamp().IsZero() { + if s.isLeader { + return reconciler.DoReconcileKind, s.reconciler.ReconcileKind + } else if s.isROI { + return reconciler.DoObserveKind, s.roi.ObserveKind + } + } else if fin, ok := s.reconciler.(Finalizer); s.isLeader && ok { + return reconciler.DoFinalizeKind, fin.FinalizeKind + } + return "unknown", nil +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 920ba68c97c4..45d6b7d7c767 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1192,6 +1192,10 @@ knative.dev/caching/pkg/client/injection/informers/caching/v1alpha1/image/fake knative.dev/caching/pkg/client/injection/informers/factory knative.dev/caching/pkg/client/injection/informers/factory/fake knative.dev/caching/pkg/client/listers/caching/v1alpha1 +# knative.dev/control-protocol v0.0.0-20220610133426-4a1c8e84039f +## explicit; go 1.17 +knative.dev/control-protocol/pkg/certificates +knative.dev/control-protocol/pkg/certificates/reconciler # knative.dev/hack v0.0.0-20220610014127-dc6c287516dc ## explicit; go 1.14 knative.dev/hack @@ -1267,6 +1271,7 @@ knative.dev/pkg/client/injection/kube/informers/core/v1/pod knative.dev/pkg/client/injection/kube/informers/core/v1/pod/fake knative.dev/pkg/client/injection/kube/informers/core/v1/pod/filtered knative.dev/pkg/client/injection/kube/informers/core/v1/pod/filtered/fake +knative.dev/pkg/client/injection/kube/informers/core/v1/secret knative.dev/pkg/client/injection/kube/informers/core/v1/service knative.dev/pkg/client/injection/kube/informers/core/v1/service/fake knative.dev/pkg/client/injection/kube/informers/factory @@ -1274,6 +1279,7 @@ knative.dev/pkg/client/injection/kube/informers/factory/fake knative.dev/pkg/client/injection/kube/informers/factory/filtered knative.dev/pkg/client/injection/kube/informers/factory/filtered/fake knative.dev/pkg/client/injection/kube/reconciler/core/v1/namespace +knative.dev/pkg/client/injection/kube/reconciler/core/v1/secret knative.dev/pkg/codegen/cmd/injection-gen knative.dev/pkg/codegen/cmd/injection-gen/args knative.dev/pkg/codegen/cmd/injection-gen/generators From 3af4f435f0ef7102a587a71986cda9bbc3c57851 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Wed, 8 Jun 2022 09:36:03 +0900 Subject: [PATCH 02/14] Fix cert path --- cmd/queue/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/queue/main.go b/cmd/queue/main.go index 4804e37f19b0..23c6d29bd45c 100644 --- a/cmd/queue/main.go +++ b/cmd/queue/main.go @@ -67,10 +67,10 @@ const ( drainSleepDuration = 30 * time.Second // certPath is the path for the server certificate mounted by queue-proxy. - certPath = queue.CertDirectory + certificates.SecretCertKey + certPath = queue.CertDirectory + "/" + certificates.SecretCertKey // keyPath is the path for the server certificate key mounted by queue-proxy. - keyPath = queue.CertDirectory + certificates.SecretPKKey + keyPath = queue.CertDirectory + "/" + certificates.SecretPKKey ) type config struct { From fb30cfc515934b2b63c42718b44e6294a41e1286 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Wed, 8 Jun 2022 15:49:10 +0900 Subject: [PATCH 03/14] Temporary use local networking repo --- go.mod | 2 +- go.sum | 4 +- .../networking/config/config-network.yaml | 52 ++---------- .../networking/pkg/config/config.go | 81 +++---------------- .../networking/pkg/deprecated_config.go | 34 -------- vendor/modules.txt | 2 +- 6 files changed, 22 insertions(+), 153 deletions(-) diff --git a/go.mod b/go.mod index acb09fe65e2c..0096ffa4e6a8 100644 --- a/go.mod +++ b/go.mod @@ -36,7 +36,7 @@ require ( knative.dev/caching v0.0.0-20220610113725-9c092893371a knative.dev/control-protocol v0.0.0-20220610133426-4a1c8e84039f knative.dev/hack v0.0.0-20220610014127-dc6c287516dc - knative.dev/networking v0.0.0-20220610013825-3103f3a72792 + knative.dev/networking v0.0.0-20220614203516-07c9d7614c61 knative.dev/pkg v0.0.0-20220610014025-7d607d643ee2 sigs.k8s.io/yaml v1.3.0 ) diff --git a/go.sum b/go.sum index 8e5cb219e86c..6289723f3b6d 100644 --- a/go.sum +++ b/go.sum @@ -2253,8 +2253,8 @@ knative.dev/hack v0.0.0-20220524153203-12d3e2a7addc/go.mod h1:PHt8x8yX5Z9pPquBEf knative.dev/hack v0.0.0-20220609132040-fd240e2cef5c/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI= knative.dev/hack v0.0.0-20220610014127-dc6c287516dc h1:LyqyT+rtgZYfOb3ChGE5jTFApCOcUmAcSV+TzgLxnys= knative.dev/hack v0.0.0-20220610014127-dc6c287516dc/go.mod h1:PHt8x8yX5Z9pPquBEfIj0X66f8iWkWfR0S/sarACJrI= -knative.dev/networking v0.0.0-20220610013825-3103f3a72792 h1:GDLLrx8w9oEXoE/am8AdWSTtSsLoZevmEMaeAdetM1Q= -knative.dev/networking v0.0.0-20220610013825-3103f3a72792/go.mod h1:oIETD09Q4GSOXjdBdiPc0eEQxMwmjH7/gdhfg+sgdW8= +knative.dev/networking v0.0.0-20220614203516-07c9d7614c61 h1:IsEfLWjHFt10XEUnAE/W4XcEU2uA+PMd1aZFkz5vrzA= +knative.dev/networking v0.0.0-20220614203516-07c9d7614c61/go.mod h1:oIETD09Q4GSOXjdBdiPc0eEQxMwmjH7/gdhfg+sgdW8= knative.dev/pkg v0.0.0-20220524202603-19adf798efb8/go.mod h1:pApypeWDkGrsMkUDkV6StWXS4CXhwGWuJEID9GGZY0Y= knative.dev/pkg v0.0.0-20220609131940-865e331abfa5/go.mod h1:pApypeWDkGrsMkUDkV6StWXS4CXhwGWuJEID9GGZY0Y= knative.dev/pkg v0.0.0-20220610014025-7d607d643ee2 h1:MMClRZRz6rzhrpySJ21XCJqVDd4K3rurUEJ1Yrh8DmA= diff --git a/vendor/knative.dev/networking/config/config-network.yaml b/vendor/knative.dev/networking/config/config-network.yaml index aed72bba5cdc..39cbc4a1b58a 100644 --- a/vendor/knative.dev/networking/config/config-network.yaml +++ b/vendor/knative.dev/networking/config/config-network.yaml @@ -22,7 +22,7 @@ metadata: app.kubernetes.io/component: networking app.kubernetes.io/version: devel annotations: - knative.dev/example-checksum: "d0b91f80" + knative.dev/example-checksum: "73d96d1b" data: _example: | ################################ @@ -173,50 +173,12 @@ data: # Knative doesn't know about that otherwise. default-external-scheme: "http" - # The CA public certificate used to sign the activator TLS certificate. - # It is specified by the secret name, which has the "ca.crt" data field. - # Use an empty value to disable the feature (default). + # internal-encryption indicates whether internal traffic is encrypted or not. + # If this is "true", the following traffic are encrypted: + # - ingress to activator + # - ingress to queue-proxy + # - activator to queue-proxy # # NOTE: This flag is in an alpha state and is mostly here to enable internal testing # for now. Use with caution. - activator-ca: "" - - # The SAN (Subject Alt Name) used to validate the activator TLS certificate. - # It must be set when "activator-ca" is specified. - # Use an empty value to disable the feature (default). - # - # NOTE: This flag is in an alpha state and is mostly here to enable internal testing - # for now. Use with caution. - activator-san: "" - - # The server certificates to serve the TLS traffic from ingress to activator. - # It is specified by the secret name, which has the "tls.crt" and "tls.key" data field. - # Use an empty value to disable the feature (default). - # - # NOTE: This flag is in an alpha state and is mostly here to enable internal testing - # for now. Use with caution. - activator-cert-secret: "" - - # The CA public certificate used to sign the queue-proxy TLS certificate. - # It is specified by the secret name, which has the "ca.crt" data field. - # Use an empty value to disable the feature (default). - # - # NOTE: This flag is in an alpha state and is mostly here to enable internal testing - # for now. Use with caution. - queue-proxy-ca: "" - - # The SAN (Subject Alt Name) used to validate the activator TLS certificate. - # It must be set when "queue-proxy-ca" is specified. - # Use an empty value to disable the feature (default). - # - # NOTE: This flag is in an alpha state and is mostly here to enable internal testing - # for now. Use with caution. - queue-proxy-san: "" - - # The server certificates to serve the TLS traffic from activator to queue-proxy. - # It is specified by the secret name, which has the "tls.crt" and "tls.key" data field. - # Use an empty value to disable the feature (default). - # - # NOTE: This flag is in an alpha state and is mostly here to enable internal testing - # for now. Use with caution. - queue-proxy-cert-secret: "" + internal-encryption: "false" diff --git a/vendor/knative.dev/networking/pkg/config/config.go b/vendor/knative.dev/networking/pkg/config/config.go index 1a7a59428bef..30580161a87c 100644 --- a/vendor/knative.dev/networking/pkg/config/config.go +++ b/vendor/knative.dev/networking/pkg/config/config.go @@ -65,6 +65,10 @@ const ( // CertManagerCertificateClassName value for specifying Knative's Cert-Manager // Certificate reconciler. CertManagerCertificateClassName = "cert-manager.certificate.networking.knative.dev" + + // ServingInternalCertName is the name of secret contains certificates in serving + // system namespace. + ServingInternalCertName = "knative-serving-certs" ) // Config Keys @@ -118,27 +122,9 @@ const ( // hostname for a Route's tag. TagTemplateKey = "tag-template" - // ActivatorCAKey is the config for the secret name, which stores CA public certificate used - // to sign the activator TLS certificate. - ActivatorCAKey = "activator-ca" - - // ActivatorSANKey is the config for the SAN used to validate the activator TLS certificate. - ActivatorSANKey = "activator-san" - - // ActivatorCertKey is the config for the secret name, which stores certificates - // to serve the TLS traffic from ingress to activator. - ActivatorCertKey = "activator-cert-secret" - - // QueueProxyCAKey is the config for the secret name, which stores CA public certificate used - // to sign the queue-proxy TLS certificate. - QueueProxyCAKey = "queue-proxy-ca" - - // QueueProxySANKey is the config for the SAN used to validate the queue-proxy TLS certificate. - QueueProxySANKey = "queue-proxy-san" - - // QueueProxyCertKey is the config for the secret name, which stores certificates - // to serve the TLS traffic from activator to queue-proxy. - QueueProxyCertKey = "queue-proxy-cert-secret" + // InternalEncryptionKey is the name of the configuration whether + // internal traffic is encrypted or not. + InternalEncryptionKey = "internal-encryption" ) // HTTPProtocol indicates a type of HTTP endpoint behavior @@ -265,27 +251,8 @@ type Config struct { // not enabled. Defaults to "http". DefaultExternalScheme string - // ActivatorCA defines the secret name of the CA public certificate used to sign the activator TLS certificate. - // The traffic is not encrypted if ActivatorCA is empty. - ActivatorCA string - - // ActivatorSAN defines the SAN (Subject Alt Name) used to validate the activator TLS certificate. - // It is used only when ActivatorCA is specified. - ActivatorSAN string - - // ActivatorCertSecret defines the secret name of the server certificates to serve the TLS traffic from ingress to activator. - ActivatorCertSecret string - - // QueueProxyCA defines the secret name of the CA public certificate used to sign the queue-proxy TLS certificate. - // The traffic to queue-proxy is not encrypted if QueueProxyCA is empty. - QueueProxyCA string - - // QueueProxySAN defines the SAN (Subject Alt Name) used to validate the queue-proxy TLS certificate. - // It is used only when QueueProxyCA is specified. - QueueProxySAN string - - // QueueProxyCertSecret defines the secret name of the server certificates to serve the TLS traffic from activator to queue-proxy. - QueueProxyCertSecret string + // DefaultExternal specifies whether internal traffic is encrypted or not. + InternalEncryption bool } func defaultConfig() *Config { @@ -300,12 +267,7 @@ func defaultConfig() *Config { AutocreateClusterDomainClaims: false, DefaultExternalScheme: "http", MeshCompatibilityMode: MeshCompatibilityModeAuto, - ActivatorCA: "", - ActivatorSAN: "", - ActivatorCertSecret: "", - QueueProxyCA: "", - QueueProxySAN: "", - QueueProxyCertSecret: "", + InternalEncryption: false, } } @@ -332,12 +294,7 @@ func NewConfigFromMap(data map[string]string) (*Config, error) { cm.AsBool(AutocreateClusterDomainClaimsKey, &nc.AutocreateClusterDomainClaims), cm.AsBool(EnableMeshPodAddressabilityKey, &nc.EnableMeshPodAddressability), cm.AsString(DefaultExternalSchemeKey, &nc.DefaultExternalScheme), - cm.AsString(ActivatorCAKey, &nc.ActivatorCA), - cm.AsString(ActivatorSANKey, &nc.ActivatorSAN), - cm.AsString(ActivatorCertKey, &nc.ActivatorCertSecret), - cm.AsString(QueueProxyCAKey, &nc.QueueProxyCA), - cm.AsString(QueueProxySANKey, &nc.QueueProxySAN), - cm.AsString(QueueProxyCertKey, &nc.QueueProxyCertSecret), + cm.AsBool(InternalEncryptionKey, &nc.InternalEncryption), asMode(MeshCompatibilityModeKey, &nc.MeshCompatibilityMode), asLabelSelector(NamespaceWildcardCertSelectorKey, &nc.NamespaceWildcardCertSelector), ); err != nil { @@ -394,22 +351,6 @@ func NewConfigFromMap(data map[string]string) (*Config, error) { return nil, fmt.Errorf("httpProtocol %s in config-network ConfigMap is not supported", data[HTTPProtocolKey]) } - if nc.ActivatorCA != "" && nc.ActivatorSAN == "" { - return nil, fmt.Errorf("%q must be set when %q was set", ActivatorSANKey, ActivatorCAKey) - } - - if nc.ActivatorCA == "" && nc.ActivatorSAN != "" { - return nil, fmt.Errorf("%q must be set when %q was set", ActivatorCAKey, ActivatorSANKey) - } - - if nc.QueueProxyCA != "" && nc.QueueProxySAN == "" { - return nil, fmt.Errorf("%q must be set when %q was set", QueueProxySANKey, QueueProxyCAKey) - } - - if nc.QueueProxyCA == "" && nc.QueueProxySAN != "" { - return nil, fmt.Errorf("%q must be set when %q was set", QueueProxyCAKey, QueueProxySANKey) - } - return nc, nil } diff --git a/vendor/knative.dev/networking/pkg/deprecated_config.go b/vendor/knative.dev/networking/pkg/deprecated_config.go index f099c68f40f5..50c322d457af 100644 --- a/vendor/knative.dev/networking/pkg/deprecated_config.go +++ b/vendor/knative.dev/networking/pkg/deprecated_config.go @@ -123,40 +123,6 @@ const ( // // Deprecated: use knative.dev/networking/pkg/config.DefaultExternalSchemeKey DefaultExternalSchemeKey = config.DefaultExternalSchemeKey - - // ActivatorCAKey is the config for the secret name, which stores CA public certificate used - // to sign the activator TLS certificate. - // - // Deprecated: use knative.dev/networking/pkg/config.ActivatorCAKey - ActivatorCAKey = config.ActivatorCAKey - - // ActivatorSANKey is the config for the SAN used to validate the activator TLS certificate. - // - // Deprecated: use knative.dev/networking/pkg/config.ActivatorSANKey - ActivatorSANKey = config.ActivatorSANKey - - // ActivatorCertKey is the config for the secret name, which stores certificates - // to serve the TLS traffic from ingress to activator. - // - // Deprecated: use knative.dev/networking/pkg/config.ActivatorCertKey - ActivatorCertKey = config.ActivatorCertKey - - // QueueProxyCAKey is the config for the secret name, which stores CA public certificate used - // to sign the queue-proxy TLS certificate. - // - // Deprecated: use knative.dev/networking/pkg/config.QueueProxyCAKey - QueueProxyCAKey = config.QueueProxyCAKey - - // QueueProxySANKey is the config for the SAN used to validate the queue-proxy TLS certificate. - // - // Deprecated: use knative.dev/networking/pkg/config.QueueProxySANKey - QueueProxySANKey = config.QueueProxySANKey - - // QueueProxyCertKey is the config for the secret name, which stores certificates - // to serve the TLS traffic from activator to queue-proxy. - // - // Deprecated: use knative.dev/networking/pkg/config.QueueProxyCertKey - QueueProxyCertKey = config.QueueProxyCertKey ) // DomainTemplateValues are the available properties people can choose from diff --git a/vendor/modules.txt b/vendor/modules.txt index 45d6b7d7c767..8c51d1480ce2 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1200,7 +1200,7 @@ knative.dev/control-protocol/pkg/certificates/reconciler ## explicit; go 1.14 knative.dev/hack knative.dev/hack/shell -# knative.dev/networking v0.0.0-20220610013825-3103f3a72792 +# knative.dev/networking v0.0.0-20220614203516-07c9d7614c61 ## explicit; go 1.17 knative.dev/networking/config knative.dev/networking/pkg From 4d19c6a98d72fb940092c403169f25ac42000796 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Wed, 8 Jun 2022 12:01:20 +0900 Subject: [PATCH 04/14] Support internal-encryption configuration --- cmd/activator/main.go | 14 +++--- config/core/300-secret.yaml | 2 +- .../autoscaling/config/store_test.go | 6 +-- pkg/reconciler/autoscaling/kpa/kpa.go | 6 --- pkg/reconciler/autoscaling/kpa/kpa_test.go | 43 +------------------ pkg/reconciler/revision/cruds.go | 15 +++++++ .../revision/reconcile_resources.go | 32 ++++++++++++++ pkg/reconciler/revision/resources/deploy.go | 4 +- pkg/reconciler/revision/revision.go | 7 +++ pkg/reconciler/route/resources/ingress.go | 16 +++---- .../route/resources/ingress_test.go | 9 ++-- test/config/tls/config-network.yaml | 29 ------------- test/config/tls/secret.yaml | 29 ------------- test/e2e-common.sh | 11 ++--- test/e2e/autoscale_test.go | 11 ----- third_party/kourier-latest/kourier.yaml | 2 +- 16 files changed, 87 insertions(+), 149 deletions(-) delete mode 100644 test/config/tls/config-network.yaml delete mode 100644 test/config/tls/secret.yaml diff --git a/cmd/activator/main.go b/cmd/activator/main.go index 09ce6587da40..4c831d2cc42b 100644 --- a/cmd/activator/main.go +++ b/cmd/activator/main.go @@ -157,14 +157,14 @@ func main() { logger.Fatalw("Failed to construct network config", zap.Error(err)) } - // Enable TLS against queue-proxy when the CA and SA are specified. - tlsEnabled := networkConfig.QueueProxyCA != "" && networkConfig.QueueProxySAN != "" + // Enable TLS against queue-proxy when internal-encryption is enabled. + tlsEnabled := networkConfig.InternalEncryption // Enable TLS client when queue-proxy-ca is specified. // At this moment activator with TLS does not disable HTTP. // See also https://github.com/knative/serving/issues/12808. if tlsEnabled { - caSecret, err := kubeClient.CoreV1().Secrets(system.Namespace()).Get(ctx, networkConfig.QueueProxyCA, metav1.GetOptions{}) + caSecret, err := kubeClient.CoreV1().Secrets(system.Namespace()).Get(ctx, netcfg.ServingInternalCertName, metav1.GetOptions{}) if err != nil { logger.Fatalw("Failed to get secret", zap.Error(err)) } @@ -181,7 +181,7 @@ func main() { tlsConf := &tls.Config{ RootCAs: pool, InsecureSkipVerify: false, - ServerName: networkConfig.QueueProxySAN, + ServerName: certificates.FakeDnsName, MinVersion: tls.VersionTLS12, } transport = pkgnet.NewProxyAutoTLSTransport(env.MaxIdleProxyConns, env.MaxIdleProxyConnsPerHost, tlsConf) @@ -276,11 +276,11 @@ func main() { }(name, server) } - // Enable TLS server when activator-server-cert is specified. + // Enable TLS server when internal-encryption is specified. // At this moment activator with TLS does not disable HTTP. // See also https://github.com/knative/serving/issues/12808. - if networkConfig.ActivatorCertSecret != "" { - secret, err := kubeClient.CoreV1().Secrets(system.Namespace()).Get(ctx, networkConfig.ActivatorCertSecret, metav1.GetOptions{}) + if networkConfig.InternalEncryption { + secret, err := kubeClient.CoreV1().Secrets(system.Namespace()).Get(ctx, netcfg.ServingInternalCertName, metav1.GetOptions{}) if err != nil { logger.Fatalw("failed to get secret", zap.Error(err)) } diff --git a/config/core/300-secret.yaml b/config/core/300-secret.yaml index 27fe2ddd004e..6a8fc21db4c2 100644 --- a/config/core/300-secret.yaml +++ b/config/core/300-secret.yaml @@ -21,7 +21,7 @@ metadata: apiVersion: v1 kind: Secret metadata: - name: server-certs + name: knative-serving-certs namespace: knative-serving labels: serving-ctrl: "data-plane" diff --git a/pkg/reconciler/autoscaling/config/store_test.go b/pkg/reconciler/autoscaling/config/store_test.go index e2687ac68db5..df370af4717c 100644 --- a/pkg/reconciler/autoscaling/config/store_test.go +++ b/pkg/reconciler/autoscaling/config/store_test.go @@ -67,8 +67,7 @@ func TestStoreImmutableConfig(t *testing.T) { config := store.Load() config.Autoscaler.MaxScaleUpRate = 100.0 config.Deployment.ProgressDeadline = 3 * time.Minute - config.Network.ActivatorCA = "activator-ca" - config.Network.ActivatorSAN = "activator-san" + config.Network.InternalEncryption = true newConfig := store.Load() if newConfig.Autoscaler.MaxScaleUpRate == 100.0 { @@ -77,7 +76,8 @@ func TestStoreImmutableConfig(t *testing.T) { if newConfig.Deployment.ProgressDeadline == 3*time.Minute { t.Error("Deployment config is not immuable") } - if newConfig.Network.ActivatorCA == "activator-ca" || newConfig.Network.ActivatorSAN == "activator-san" { + + if newConfig.Network.InternalEncryption { t.Error("Network config is not immuable") } } diff --git a/pkg/reconciler/autoscaling/kpa/kpa.go b/pkg/reconciler/autoscaling/kpa/kpa.go index 5f38600e585e..8258bce9bd15 100644 --- a/pkg/reconciler/autoscaling/kpa/kpa.go +++ b/pkg/reconciler/autoscaling/kpa/kpa.go @@ -126,12 +126,6 @@ func (c *Reconciler) ReconcileKind(ctx context.Context, pa *autoscalingv1alpha1. mode := nv1alpha1.SKSOperationModeProxy switch { - // When activator CA is enabled, force activator always in path. - // TODO: This is a temporary state and to be fixed. - // See also issues/11906 and issues/12797. - case len(config.FromContext(ctx).Network.ActivatorCA) > 0: - mode = nv1alpha1.SKSOperationModeProxy - // If the want == -1 and PA is inactive that implies the autoscaler // has no knowledge of the revision (due to restart) but it was previously // scaled down (inactive). In this instance we want to remain in Proxy Mode diff --git a/pkg/reconciler/autoscaling/kpa/kpa_test.go b/pkg/reconciler/autoscaling/kpa/kpa_test.go index 3d876cc106aa..1052bc2b9ce1 100644 --- a/pkg/reconciler/autoscaling/kpa/kpa_test.go +++ b/pkg/reconciler/autoscaling/kpa/kpa_test.go @@ -126,14 +126,6 @@ func initialScaleZeroASConfig() *autoscalerconfig.Config { return ac } -func activatorCertsNetConfig() *netcfg.Config { - nc, _ := netcfg.NewConfigFromMap(map[string]string{ - netcfg.ActivatorCAKey: "knative-ca", - netcfg.ActivatorSANKey: "knative-san", - }) - return nc -} - func defaultConfig() *config.Config { ac, _ := asconfig.NewConfigFromMap(defaultConfigMapData()) deploymentConfig, _ := deployment.NewConfigFromMap(map[string]string{ @@ -141,8 +133,7 @@ func defaultConfig() *config.Config { deployment.ProgressDeadlineKey: progressDeadline.String(), }) networkConfig, _ := netcfg.NewConfigFromMap(map[string]string{ - netcfg.ActivatorCAKey: "", - netcfg.ActivatorSANKey: "", + netcfg.InternalEncryptionKey: "false", }) return &config.Config{ @@ -1141,38 +1132,6 @@ func TestReconcile(t *testing.T) { WithPAMetricsService(privateSvc), WithObservedGeneration(1), ), }}, - }, { - Name: "we have enough burst capacity, but keep proxy mode as activator CA is enabled", - Key: key, - Ctx: context.WithValue(context.WithValue(context.Background(), netConfigKey{}, activatorCertsNetConfig()), deciderKey{}, - decider(testNamespace, testRevision, defaultScale, /* desiredScale */ - 1 /* ebc */)), - Objects: []runtime.Object{ - kpa(testNamespace, testRevision, WithPASKSReady, WithTraffic, markScaleTargetInitialized, - WithPAMetricsService(privateSvc), withScales(1, defaultScale), - WithPAStatusService(testRevision), WithObservedGeneration(1)), - defaultProxySKS, - metric(testNamespace, testRevision), - defaultDeployment, - defaultReady}, - // No update from ProxySKS. - }, { - Name: "we have enough burst capacity, but switch to keep proxy mode as activator CA is turned on", - Key: key, - Ctx: context.WithValue(context.WithValue(context.Background(), netConfigKey{}, activatorCertsNetConfig()), deciderKey{}, - decider(testNamespace, testRevision, defaultScale, /* desiredScale */ - 1 /* ebc */)), - Objects: []runtime.Object{ - kpa(testNamespace, testRevision, WithPASKSReady, WithTraffic, markScaleTargetInitialized, - WithPAMetricsService(privateSvc), withScales(1, defaultScale), - WithPAStatusService(testRevision), WithObservedGeneration(1)), - defaultSKS, - metric(testNamespace, testRevision), - defaultDeployment, - defaultReady}, - WantUpdates: []clientgotesting.UpdateActionImpl{{ - Object: defaultProxySKS, - }}, }} table.Test(t, MakeFactory(func(ctx context.Context, listers *Listers, cmw configmap.Watcher) controller.Reconciler { diff --git a/pkg/reconciler/revision/cruds.go b/pkg/reconciler/revision/cruds.go index 2fe0a0a9f161..03fa1d34947e 100644 --- a/pkg/reconciler/revision/cruds.go +++ b/pkg/reconciler/revision/cruds.go @@ -21,6 +21,7 @@ import ( "fmt" appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/equality" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -46,6 +47,20 @@ func (c *Reconciler) createDeployment(ctx context.Context, rev *v1.Revision) (*a return c.kubeclient.AppsV1().Deployments(deployment.Namespace).Create(ctx, deployment, metav1.CreateOptions{}) } +func (c *Reconciler) createSecret(ctx context.Context, ns *corev1.Namespace) (*corev1.Secret, error) { + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: ns.Name + "-serving", + Namespace: ns.Name, + OwnerReferences: []metav1.OwnerReference{*metav1.NewControllerRef(ns, corev1.SchemeGroupVersion.WithKind("Namespace"))}, + Labels: map[string]string{ + "serving-ctrl": "data-plane", + }, + }, + } + return c.kubeclient.CoreV1().Secrets(secret.Namespace).Create(ctx, secret, metav1.CreateOptions{}) +} + func (c *Reconciler) checkAndUpdateDeployment(ctx context.Context, rev *v1.Revision, have *appsv1.Deployment) (*appsv1.Deployment, error) { logger := logging.FromContext(ctx) cfgs := config.FromContext(ctx) diff --git a/pkg/reconciler/revision/reconcile_resources.go b/pkg/reconciler/revision/reconcile_resources.go index e77d9e65cc91..07cccc2dfd37 100644 --- a/pkg/reconciler/revision/reconcile_resources.go +++ b/pkg/reconciler/revision/reconcile_resources.go @@ -28,6 +28,7 @@ import ( apierrs "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/control-protocol/pkg/certificates" "knative.dev/pkg/kmeta" "knative.dev/pkg/kmp" "knative.dev/pkg/logging" @@ -197,3 +198,34 @@ func hasDeploymentTimedOut(deployment *appsv1.Deployment) bool { } return false } + +func (c *Reconciler) reconcileSecret(ctx context.Context, rev *v1.Revision) error { + ns := rev.Namespace + // TODO: const + secretName := ns + "-serving" + logger := logging.FromContext(ctx) + logger.Info("Reconciling Secret: ", secretName) + + secret, err := c.kubeclient.CoreV1().Secrets(ns).Get(ctx, secretName, metav1.GetOptions{}) + if apierrs.IsNotFound(err) { + namespace, err := c.kubeclient.CoreV1().Namespaces().Get(ctx, ns, metav1.GetOptions{}) + if err != nil { + return fmt.Errorf("failed to get Namespace %q: %w", secretName, err) + } + logger.Info("Created Secret: ", secretName) + secret, err = c.createSecret(ctx, namespace) + if err != nil { + return fmt.Errorf("failed to create Secret %q: %w", secretName, err) + } + } else if err != nil { + return fmt.Errorf("failed to get secret %q: %w", secretName, err) + } + + // Verify if secret has been added the data. + _, ok := secret.Data[certificates.SecretCertKey] + if !ok { + return fmt.Errorf("secret is not ready yet.") + } + + return nil +} diff --git a/pkg/reconciler/revision/resources/deploy.go b/pkg/reconciler/revision/resources/deploy.go index a4ecb5ac17ce..f3554fb3698a 100644 --- a/pkg/reconciler/revision/resources/deploy.go +++ b/pkg/reconciler/revision/resources/deploy.go @@ -139,9 +139,9 @@ func makePodSpec(rev *v1.Revision, cfg *config.Config) (*corev1.PodSpec, error) extraVolumes = append(extraVolumes, varTokenVolume) } - if cfg.Network.QueueProxyCertSecret != "" { + if cfg.Network.InternalEncryption { queueContainer.VolumeMounts = append(queueContainer.VolumeMounts, certVolumeMount) - extraVolumes = append(extraVolumes, certVolume(cfg.Network.QueueProxyCertSecret)) + extraVolumes = append(extraVolumes, certVolume(rev.Namespace+"-serving")) } podSpec := BuildPodSpec(rev, append(BuildUserContainers(rev), *queueContainer), cfg) diff --git a/pkg/reconciler/revision/revision.go b/pkg/reconciler/revision/revision.go index 6a5556bae96a..8922d04b13ca 100644 --- a/pkg/reconciler/revision/revision.go +++ b/pkg/reconciler/revision/revision.go @@ -138,6 +138,13 @@ func (c *Reconciler) ReconcileKind(ctx context.Context, rev *v1.Revision) pkgrec logger.Debug("Revision meta: " + spew.Sdump(rev.ObjectMeta)) } + // Deploy certificate when internal-encryption is enabled. + if config.FromContext(ctx).Network.InternalEncryption { + if err := c.reconcileSecret(ctx, rev); err != nil { + return err + } + } + for _, phase := range []func(context.Context, *v1.Revision) error{ c.reconcileDeployment, c.reconcileImageCache, diff --git a/pkg/reconciler/route/resources/ingress.go b/pkg/reconciler/route/resources/ingress.go index 2b5c2fd6391e..f6cf82618d17 100644 --- a/pkg/reconciler/route/resources/ingress.go +++ b/pkg/reconciler/route/resources/ingress.go @@ -149,7 +149,7 @@ func makeIngressSpec( return netv1alpha1.IngressSpec{}, err } rule := makeIngressRule(domains, r.Namespace, - visibility, tc.Targets[name], ro.RolloutsByTag(name), networkConfig.ActivatorCA) + visibility, tc.Targets[name], ro.RolloutsByTag(name), networkConfig.InternalEncryption) if featuresConfig.TagHeaderBasedRouting == apicfg.Enabled { if rule.HTTP.Paths[0].AppendHeaders == nil { rule.HTTP.Paths[0].AppendHeaders = make(map[string]string, 1) @@ -171,7 +171,7 @@ func makeIngressSpec( // Since names are sorted `DefaultTarget == ""` is the first one, // so just pass the subslice. rule.HTTP.Paths = append( - makeTagBasedRoutingIngressPaths(r.Namespace, tc, ro, networkConfig.ActivatorCA, names[1:]), rule.HTTP.Paths...) + makeTagBasedRoutingIngressPaths(r.Namespace, tc, ro, networkConfig.InternalEncryption, names[1:]), rule.HTTP.Paths...) } else { // If a request is routed by a tag-attached hostname instead of the tag header, // the request may not have the tag header "Knative-Serving-Tag", @@ -265,24 +265,24 @@ func makeIngressRule(domains []string, ns string, visibility netv1alpha1.IngressVisibility, targets traffic.RevisionTargets, roCfgs []*traffic.ConfigurationRollout, - activatorCA string) netv1alpha1.IngressRule { + encryption bool) netv1alpha1.IngressRule { return netv1alpha1.IngressRule{ Hosts: domains, Visibility: visibility, HTTP: &netv1alpha1.HTTPIngressRuleValue{ Paths: []netv1alpha1.HTTPIngressPath{ - *makeBaseIngressPath(ns, targets, roCfgs, activatorCA), + *makeBaseIngressPath(ns, targets, roCfgs, encryption), }, }, } } // `names` must not include `""` — the DefaultTarget. -func makeTagBasedRoutingIngressPaths(ns string, tc *traffic.Config, ro *traffic.Rollout, activatorCA string, names []string) []netv1alpha1.HTTPIngressPath { +func makeTagBasedRoutingIngressPaths(ns string, tc *traffic.Config, ro *traffic.Rollout, encryption bool, names []string) []netv1alpha1.HTTPIngressPath { paths := make([]netv1alpha1.HTTPIngressPath, 0, len(names)) for _, name := range names { - path := makeBaseIngressPath(ns, tc.Targets[name], ro.RolloutsByTag(name), activatorCA) + path := makeBaseIngressPath(ns, tc.Targets[name], ro.RolloutsByTag(name), encryption) path.Headers = map[string]netv1alpha1.HeaderMatch{netheader.RouteTagKey: {Exact: name}} paths = append(paths, *path) } @@ -302,7 +302,7 @@ func rolloutConfig(cfgName string, ros []*traffic.ConfigurationRollout) *traffic } func makeBaseIngressPath(ns string, targets traffic.RevisionTargets, - roCfgs []*traffic.ConfigurationRollout, activatorCA string) *netv1alpha1.HTTPIngressPath { + roCfgs []*traffic.ConfigurationRollout, encryption bool) *netv1alpha1.HTTPIngressPath { // Optimistically allocate |targets| elements. splits := make([]netv1alpha1.IngressBackendSplit, 0, len(targets)) for _, t := range targets { @@ -315,7 +315,7 @@ func makeBaseIngressPath(ns string, targets traffic.RevisionTargets, cfg = rolloutConfig(t.ConfigurationName, roCfgs) } var servicePort intstr.IntOrString - if len(activatorCA) != 0 { + if encryption { servicePort = intstr.FromInt(networking.ServiceHTTPSPort) } else { servicePort = intstr.FromInt(networking.ServicePort(t.Protocol)) diff --git a/pkg/reconciler/route/resources/ingress_test.go b/pkg/reconciler/route/resources/ingress_test.go index 03ed1c53a7b6..cc6516a3ea8c 100644 --- a/pkg/reconciler/route/resources/ingress_test.go +++ b/pkg/reconciler/route/resources/ingress_test.go @@ -868,7 +868,7 @@ func TestMakeIngressRuleVanilla(t *testing.T) { } ro := tc.BuildRollout() rule := makeIngressRule(domains, ns, - netv1alpha1.IngressVisibilityExternalIP, targets, ro.RolloutsByTag(traffic.DefaultTarget), "" /* activatorCA */) + netv1alpha1.IngressVisibilityExternalIP, targets, ro.RolloutsByTag(traffic.DefaultTarget), false /* internal encryption */) expected := netv1alpha1.IngressRule{ Hosts: []string{ "a.com", @@ -921,7 +921,7 @@ func TestMakeIngressRuleZeroPercentTarget(t *testing.T) { } ro := tc.BuildRollout() rule := makeIngressRule(domains, ns, - netv1alpha1.IngressVisibilityExternalIP, targets, ro.RolloutsByTag(traffic.DefaultTarget), "" /* activatorCA */) + netv1alpha1.IngressVisibilityExternalIP, targets, ro.RolloutsByTag(traffic.DefaultTarget), false /* internal encryption */) expected := netv1alpha1.IngressRule{ Hosts: []string{"test.org"}, HTTP: &netv1alpha1.HTTPIngressRuleValue{ @@ -971,7 +971,7 @@ func TestMakeIngressRuleTwoTargets(t *testing.T) { ro := tc.BuildRollout() domains := []string{"test.org"} rule := makeIngressRule(domains, ns, netv1alpha1.IngressVisibilityExternalIP, - targets, ro.RolloutsByTag("a-tag"), "" /* activatorCA */) + targets, ro.RolloutsByTag("a-tag"), false /* internal encryption */) expected := netv1alpha1.IngressRule{ Hosts: []string{"test.org"}, HTTP: &netv1alpha1.HTTPIngressRuleValue{ @@ -1426,7 +1426,6 @@ func testContextWithHTTPOption() context.Context { func testContextWithActivatorCA() context.Context { cfg := testConfig() - cfg.Network.ActivatorCA = "ca-ame" - cfg.Network.ActivatorSAN = "san-name" + cfg.Network.InternalEncryption = true return config.ToContext(context.Background(), cfg) } diff --git a/test/config/tls/config-network.yaml b/test/config/tls/config-network.yaml deleted file mode 100644 index 6cb6b70a43e4..000000000000 --- a/test/config/tls/config-network.yaml +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright 2022 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -apiVersion: v1 -kind: ConfigMap -metadata: - name: config-network - labels: - app.kubernetes.io/name: knative-serving - app.kubernetes.io/version: devel - serving.knative.dev/release: devel -data: - activator-ca: "server-certs" - activator-san: "data-plane.knative.dev" - activator-cert-secret: "server-certs" - queue-proxy-ca: "server-certs" - queue-proxy-san: "data-plane.knative.dev" - queue-proxy-cert-secret: "server-certs" diff --git a/test/config/tls/secret.yaml b/test/config/tls/secret.yaml deleted file mode 100644 index c6677894ef30..000000000000 --- a/test/config/tls/secret.yaml +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright 2020 The Knative Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -apiVersion: v1 -kind: Secret -metadata: - name: server-certs - namespace: serving-tests-alt - labels: - serving-ctrl: "data-plane" ---- -apiVersion: v1 -kind: Secret -metadata: - name: server-certs - namespace: serving-tests - labels: - serving-ctrl: "data-plane" diff --git a/test/e2e-common.sh b/test/e2e-common.sh index af0da4e4902f..d0c6927c33a6 100644 --- a/test/e2e-common.sh +++ b/test/e2e-common.sh @@ -359,13 +359,14 @@ function install() { fi if (( ENABLE_TLS )); then - echo "Deploy server certificates into user(test) namespaces" - kubectl apply -f ${REPO_ROOT_DIR}/test/config/tls/secret.yaml + echo "Patch to config-network to enable internal encryption" + kubectl patch configmap/config-network \ + -n ${SYSTEM_NAMESPACE} \ + --type merge \ + -p '{"data":{"internal-encryption":"true"}}' - echo "Patch to activator to serve TLS" - kubectl apply -n ${SYSTEM_NAMESPACE} -f ${REPO_ROOT_DIR}/test/config/tls/config-network.yaml + echo "Restart activator to mount the certificates" kubectl delete pod -n ${SYSTEM_NAMESPACE} -l app=activator - kubectl wait --timeout=60s --for=condition=Available deployment -n ${SYSTEM_NAMESPACE} activator fi } diff --git a/test/e2e/autoscale_test.go b/test/e2e/autoscale_test.go index d3d83c30dc55..fa4725061ecd 100644 --- a/test/e2e/autoscale_test.go +++ b/test/e2e/autoscale_test.go @@ -28,7 +28,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" - netcfg "knative.dev/networking/pkg/config" "knative.dev/pkg/system" "knative.dev/serving/pkg/apis/autoscaling" "knative.dev/serving/pkg/networking" @@ -138,16 +137,6 @@ func TestTargetBurstCapacity(t *testing.T) { })) test.EnsureTearDown(t, ctx.Clients(), ctx.Names()) - cm, err := ctx.clients.KubeClient.CoreV1().ConfigMaps(system.Namespace()). - Get(context.Background(), netcfg.ConfigMapName, metav1.GetOptions{}) - if err != nil { - t.Fatal("Fail to get ConfigMap config-network:", err) - } - if cm.Data[netcfg.ActivatorCAKey] != "" { - // TODO: Remove this when https://github.com/knative/serving/issues/12797 was done. - t.Skip("Skipping TestTargetBurstCapacity as activator-ca is specified. See issue/12797.") - } - cfg, err := autoscalerCM(ctx.clients) if err != nil { t.Fatal("Error retrieving autoscaler configmap:", err) diff --git a/third_party/kourier-latest/kourier.yaml b/third_party/kourier-latest/kourier.yaml index a6f9879e879b..2048abda61f2 100644 --- a/third_party/kourier-latest/kourier.yaml +++ b/third_party/kourier-latest/kourier.yaml @@ -299,7 +299,7 @@ spec: app: net-kourier-controller spec: containers: - - image: gcr.io/gcp-compute-engine-223401/kourier-b74c3918b7eee585f87df62ccd297dc8@sha256:5bd5fb08ebf83c27f4f0a05ba893f0bd0bc29d9327c996e7de6c79ce378142a3 + - image: gcr.io/gcp-compute-engine-223401/kourier-b74c3918b7eee585f87df62ccd297dc8@sha256:bf80c24b17f79f306a39853a7e9a96b532fec7e752346edcb4e45bdda71d6c4e name: controller env: - name: CERTS_SECRET_NAMESPACE From 8140587830e1df11e5617b04e48d6c33265532a8 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Wed, 8 Jun 2022 19:49:32 +0900 Subject: [PATCH 05/14] Use const for cert name --- cmd/controller/main.go | 4 +++- config/core/300-secret.yaml | 6 ++++-- pkg/networking/constants.go | 4 ++++ pkg/reconciler/revision/cruds.go | 5 +++-- pkg/reconciler/revision/reconcile_resources.go | 6 +++--- pkg/reconciler/revision/resources/deploy.go | 2 +- 6 files changed, 18 insertions(+), 9 deletions(-) diff --git a/cmd/controller/main.go b/cmd/controller/main.go index 25a321cd617c..08408f4a9ceb 100644 --- a/cmd/controller/main.go +++ b/cmd/controller/main.go @@ -31,6 +31,8 @@ import ( // This defines the shared main for injected controllers. "knative.dev/pkg/injection" "knative.dev/pkg/injection/sharedmain" + + "knative.dev/serving/pkg/networking" ) var ctors = []injection.ControllerConstructor{ @@ -42,7 +44,7 @@ var ctors = []injection.ControllerConstructor{ service.NewController, gc.NewController, nscert.NewController, - certificate.NewControllerFactory("serving"), + certificate.NewControllerFactory(networking.ServingCertName), } func main() { diff --git a/config/core/300-secret.yaml b/config/core/300-secret.yaml index 6a8fc21db4c2..ae936886d31c 100644 --- a/config/core/300-secret.yaml +++ b/config/core/300-secret.yaml @@ -15,8 +15,9 @@ apiVersion: v1 kind: Secret metadata: - name: serving-ctrl-ca + name: serving-certs-ctrl-ca namespace: knative-serving +# The data is populated when internal-encryption is enabled. --- apiVersion: v1 kind: Secret @@ -24,4 +25,5 @@ metadata: name: knative-serving-certs namespace: knative-serving labels: - serving-ctrl: "data-plane" + serving-certs-ctrl: "data-plane" +# The data is populated when internal-encryption is enabled. diff --git a/pkg/networking/constants.go b/pkg/networking/constants.go index 0fe1e5ea1048..a832d46540ca 100644 --- a/pkg/networking/constants.go +++ b/pkg/networking/constants.go @@ -51,6 +51,10 @@ const ( // ServiceTypeKey is the label key attached to a service specifying the type of service. // e.g. Public, Private. ServiceTypeKey = networking.GroupName + "/serviceType" + + // ServingCertName is used by the secret name for internal TLS as "namespace-${ServingCertName}". + // Also the secret name has the label with "${ServingCertName}: data-plane" + ServingCertName = "serving-certs" ) // ServiceType is the enumeration type for the Kubernetes services diff --git a/pkg/reconciler/revision/cruds.go b/pkg/reconciler/revision/cruds.go index 03fa1d34947e..f3d0c9c55035 100644 --- a/pkg/reconciler/revision/cruds.go +++ b/pkg/reconciler/revision/cruds.go @@ -31,6 +31,7 @@ import ( "knative.dev/pkg/logging" autoscalingv1alpha1 "knative.dev/serving/pkg/apis/autoscaling/v1alpha1" v1 "knative.dev/serving/pkg/apis/serving/v1" + "knative.dev/serving/pkg/networking" "knative.dev/serving/pkg/reconciler/revision/config" "knative.dev/serving/pkg/reconciler/revision/resources" ) @@ -50,11 +51,11 @@ func (c *Reconciler) createDeployment(ctx context.Context, rev *v1.Revision) (*a func (c *Reconciler) createSecret(ctx context.Context, ns *corev1.Namespace) (*corev1.Secret, error) { secret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ - Name: ns.Name + "-serving", + Name: ns.Name + "-" + networking.ServingCertName, Namespace: ns.Name, OwnerReferences: []metav1.OwnerReference{*metav1.NewControllerRef(ns, corev1.SchemeGroupVersion.WithKind("Namespace"))}, Labels: map[string]string{ - "serving-ctrl": "data-plane", + networking.ServingCertName + "-ctrl": "data-plane", }, }, } diff --git a/pkg/reconciler/revision/reconcile_resources.go b/pkg/reconciler/revision/reconcile_resources.go index 07cccc2dfd37..622beba1a36d 100644 --- a/pkg/reconciler/revision/reconcile_resources.go +++ b/pkg/reconciler/revision/reconcile_resources.go @@ -34,6 +34,7 @@ import ( "knative.dev/pkg/logging" "knative.dev/pkg/logging/logkey" v1 "knative.dev/serving/pkg/apis/serving/v1" + "knative.dev/serving/pkg/networking" "knative.dev/serving/pkg/reconciler/revision/resources" resourcenames "knative.dev/serving/pkg/reconciler/revision/resources/names" ) @@ -201,8 +202,7 @@ func hasDeploymentTimedOut(deployment *appsv1.Deployment) bool { func (c *Reconciler) reconcileSecret(ctx context.Context, rev *v1.Revision) error { ns := rev.Namespace - // TODO: const - secretName := ns + "-serving" + secretName := ns + "-" + networking.ServingCertName logger := logging.FromContext(ctx) logger.Info("Reconciling Secret: ", secretName) @@ -212,11 +212,11 @@ func (c *Reconciler) reconcileSecret(ctx context.Context, rev *v1.Revision) erro if err != nil { return fmt.Errorf("failed to get Namespace %q: %w", secretName, err) } - logger.Info("Created Secret: ", secretName) secret, err = c.createSecret(ctx, namespace) if err != nil { return fmt.Errorf("failed to create Secret %q: %w", secretName, err) } + logger.Info("Created Secret: ", secretName) } else if err != nil { return fmt.Errorf("failed to get secret %q: %w", secretName, err) } diff --git a/pkg/reconciler/revision/resources/deploy.go b/pkg/reconciler/revision/resources/deploy.go index f3554fb3698a..c0e2bd4648c9 100644 --- a/pkg/reconciler/revision/resources/deploy.go +++ b/pkg/reconciler/revision/resources/deploy.go @@ -141,7 +141,7 @@ func makePodSpec(rev *v1.Revision, cfg *config.Config) (*corev1.PodSpec, error) if cfg.Network.InternalEncryption { queueContainer.VolumeMounts = append(queueContainer.VolumeMounts, certVolumeMount) - extraVolumes = append(extraVolumes, certVolume(rev.Namespace+"-serving")) + extraVolumes = append(extraVolumes, certVolume(rev.Namespace+"-"+networking.ServingCertName)) } podSpec := BuildPodSpec(rev, append(BuildUserContainers(rev), *queueContainer), cfg) From d313bd5e35834d3d9f6208021631fa161c50d97c Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Wed, 8 Jun 2022 20:02:49 +0900 Subject: [PATCH 06/14] Fix lint --- pkg/reconciler/revision/reconcile_resources.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/reconciler/revision/reconcile_resources.go b/pkg/reconciler/revision/reconcile_resources.go index 622beba1a36d..61b36ef73d65 100644 --- a/pkg/reconciler/revision/reconcile_resources.go +++ b/pkg/reconciler/revision/reconcile_resources.go @@ -224,7 +224,7 @@ func (c *Reconciler) reconcileSecret(ctx context.Context, rev *v1.Revision) erro // Verify if secret has been added the data. _, ok := secret.Data[certificates.SecretCertKey] if !ok { - return fmt.Errorf("secret is not ready yet.") + return fmt.Errorf("secret is not ready yet") } return nil From 56d00632ee65825e7fd06370a4580ab4f8556088 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Wed, 15 Jun 2022 10:53:57 +0900 Subject: [PATCH 07/14] rm blank line --- cmd/controller/main.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cmd/controller/main.go b/cmd/controller/main.go index 08408f4a9ceb..0c14df0b3b26 100644 --- a/cmd/controller/main.go +++ b/cmd/controller/main.go @@ -31,7 +31,6 @@ import ( // This defines the shared main for injected controllers. "knative.dev/pkg/injection" "knative.dev/pkg/injection/sharedmain" - "knative.dev/serving/pkg/networking" ) From 6e5ba2ad6a2b6caac8a282c50310fc219c0d7715 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Thu, 16 Jun 2022 19:01:33 +0900 Subject: [PATCH 08/14] Drop unused variable --- pkg/reconciler/autoscaling/kpa/kpa_test.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pkg/reconciler/autoscaling/kpa/kpa_test.go b/pkg/reconciler/autoscaling/kpa/kpa_test.go index 1052bc2b9ce1..56a1688240f6 100644 --- a/pkg/reconciler/autoscaling/kpa/kpa_test.go +++ b/pkg/reconciler/autoscaling/kpa/kpa_test.go @@ -132,14 +132,10 @@ func defaultConfig() *config.Config { deployment.QueueSidecarImageKey: "bob", deployment.ProgressDeadlineKey: progressDeadline.String(), }) - networkConfig, _ := netcfg.NewConfigFromMap(map[string]string{ - netcfg.InternalEncryptionKey: "false", - }) return &config.Config{ Autoscaler: ac, Deployment: deploymentConfig, - Network: networkConfig, } } From 0389beed2cd2d46df20a803ccec4874b057aa4f5 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Thu, 16 Jun 2022 19:23:07 +0900 Subject: [PATCH 09/14] Use one line style --- pkg/reconciler/revision/reconcile_resources.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/reconciler/revision/reconcile_resources.go b/pkg/reconciler/revision/reconcile_resources.go index 61b36ef73d65..0b7f7cf04000 100644 --- a/pkg/reconciler/revision/reconcile_resources.go +++ b/pkg/reconciler/revision/reconcile_resources.go @@ -222,8 +222,7 @@ func (c *Reconciler) reconcileSecret(ctx context.Context, rev *v1.Revision) erro } // Verify if secret has been added the data. - _, ok := secret.Data[certificates.SecretCertKey] - if !ok { + if _, ok := secret.Data[certificates.SecretCertKey]; !ok { return fmt.Errorf("secret is not ready yet") } From dba0c95d373f1b0ee633849af5f5ef726447a216 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Thu, 16 Jun 2022 20:29:37 +0900 Subject: [PATCH 10/14] Use one line code --- pkg/reconciler/revision/reconcile_resources.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pkg/reconciler/revision/reconcile_resources.go b/pkg/reconciler/revision/reconcile_resources.go index 0b7f7cf04000..54d0a68fc757 100644 --- a/pkg/reconciler/revision/reconcile_resources.go +++ b/pkg/reconciler/revision/reconcile_resources.go @@ -212,8 +212,7 @@ func (c *Reconciler) reconcileSecret(ctx context.Context, rev *v1.Revision) erro if err != nil { return fmt.Errorf("failed to get Namespace %q: %w", secretName, err) } - secret, err = c.createSecret(ctx, namespace) - if err != nil { + if secret, err = c.createSecret(ctx, namespace); err != nil { return fmt.Errorf("failed to create Secret %q: %w", secretName, err) } logger.Info("Created Secret: ", secretName) From 200a1f3349aa8b1d0519951e662d8810771b775c Mon Sep 17 00:00:00 2001 From: Knative Automation Date: Thu, 16 Jun 2022 11:05:14 +0000 Subject: [PATCH 11/14] Update net-kourier nightly bumping knative.dev/net-kourier d758682...b9b1e8b: > b9b1e8b Use `internal-encryption` to deploy internal certificates automatically (# 855) > 427434c bump kind and k8s versions in kind-e2e tests (# 859) Signed-off-by: Knative Automation --- third_party/kourier-latest/kourier.yaml | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/third_party/kourier-latest/kourier.yaml b/third_party/kourier-latest/kourier.yaml index 2048abda61f2..22a0454b5f01 100644 --- a/third_party/kourier-latest/kourier.yaml +++ b/third_party/kourier-latest/kourier.yaml @@ -20,7 +20,7 @@ metadata: networking.knative.dev/ingress-provider: kourier app.kubernetes.io/name: knative-serving app.kubernetes.io/component: net-kourier - app.kubernetes.io/version: "20220610-d758682a" + app.kubernetes.io/version: "20220616-b9b1e8b9" --- # Copyright 2020 The Knative Authors @@ -45,7 +45,7 @@ metadata: labels: networking.knative.dev/ingress-provider: kourier app.kubernetes.io/component: net-kourier - app.kubernetes.io/version: "20220610-d758682a" + app.kubernetes.io/version: "20220616-b9b1e8b9" app.kubernetes.io/name: knative-serving data: envoy-bootstrap.yaml: | @@ -150,7 +150,7 @@ metadata: labels: networking.knative.dev/ingress-provider: kourier app.kubernetes.io/component: net-kourier - app.kubernetes.io/version: "20220610-d758682a" + app.kubernetes.io/version: "20220616-b9b1e8b9" app.kubernetes.io/name: knative-serving data: _example: | @@ -212,7 +212,7 @@ metadata: labels: networking.knative.dev/ingress-provider: kourier app.kubernetes.io/component: net-kourier - app.kubernetes.io/version: "20220610-d758682a" + app.kubernetes.io/version: "20220616-b9b1e8b9" app.kubernetes.io/name: knative-serving --- apiVersion: rbac.authorization.k8s.io/v1 @@ -223,7 +223,7 @@ metadata: labels: networking.knative.dev/ingress-provider: kourier app.kubernetes.io/component: net-kourier - app.kubernetes.io/version: "20220610-d758682a" + app.kubernetes.io/version: "20220616-b9b1e8b9" app.kubernetes.io/name: knative-serving rules: - apiGroups: [""] @@ -252,7 +252,7 @@ metadata: labels: networking.knative.dev/ingress-provider: kourier app.kubernetes.io/component: net-kourier - app.kubernetes.io/version: "20220610-d758682a" + app.kubernetes.io/version: "20220616-b9b1e8b9" app.kubernetes.io/name: knative-serving roleRef: apiGroup: rbac.authorization.k8s.io @@ -286,7 +286,7 @@ metadata: labels: networking.knative.dev/ingress-provider: kourier app.kubernetes.io/component: net-kourier - app.kubernetes.io/version: "20220610-d758682a" + app.kubernetes.io/version: "20220616-b9b1e8b9" app.kubernetes.io/name: knative-serving spec: replicas: 1 @@ -299,7 +299,7 @@ spec: app: net-kourier-controller spec: containers: - - image: gcr.io/gcp-compute-engine-223401/kourier-b74c3918b7eee585f87df62ccd297dc8@sha256:bf80c24b17f79f306a39853a7e9a96b532fec7e752346edcb4e45bdda71d6c4e + - image: gcr.io/knative-nightly/knative.dev/net-kourier/cmd/kourier@sha256:e7f939aeb09f97bbef7d9b745b6ba203500ea8d9a6f8f63d3949686ff1cad627 name: controller env: - name: CERTS_SECRET_NAMESPACE @@ -339,7 +339,7 @@ metadata: labels: networking.knative.dev/ingress-provider: kourier app.kubernetes.io/component: net-kourier - app.kubernetes.io/version: "20220610-d758682a" + app.kubernetes.io/version: "20220616-b9b1e8b9" app.kubernetes.io/name: knative-serving spec: ports: @@ -374,7 +374,7 @@ metadata: labels: networking.knative.dev/ingress-provider: kourier app.kubernetes.io/component: net-kourier - app.kubernetes.io/version: "20220610-d758682a" + app.kubernetes.io/version: "20220616-b9b1e8b9" app.kubernetes.io/name: knative-serving spec: strategy: @@ -457,7 +457,7 @@ metadata: labels: networking.knative.dev/ingress-provider: kourier app.kubernetes.io/component: net-kourier - app.kubernetes.io/version: "20220610-d758682a" + app.kubernetes.io/version: "20220616-b9b1e8b9" app.kubernetes.io/name: knative-serving spec: ports: @@ -481,7 +481,7 @@ metadata: labels: networking.knative.dev/ingress-provider: kourier app.kubernetes.io/component: net-kourier - app.kubernetes.io/version: "20220610-d758682a" + app.kubernetes.io/version: "20220616-b9b1e8b9" app.kubernetes.io/name: knative-serving spec: ports: From b829926016d150c3c77cac3746b155a4c63e1d76 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Mon, 27 Jun 2022 18:51:23 +0900 Subject: [PATCH 12/14] Verify SecretPKKey as well --- pkg/reconciler/revision/reconcile_resources.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pkg/reconciler/revision/reconcile_resources.go b/pkg/reconciler/revision/reconcile_resources.go index 54d0a68fc757..0cb9c68e44fa 100644 --- a/pkg/reconciler/revision/reconcile_resources.go +++ b/pkg/reconciler/revision/reconcile_resources.go @@ -222,7 +222,10 @@ func (c *Reconciler) reconcileSecret(ctx context.Context, rev *v1.Revision) erro // Verify if secret has been added the data. if _, ok := secret.Data[certificates.SecretCertKey]; !ok { - return fmt.Errorf("secret is not ready yet") + return fmt.Errorf("public cert in the secret is not ready yet") + } + if _, ok := secret.Data[certificates.SecretPKKey]; !ok { + return fmt.Errorf("private key in the secret is not ready yet") } return nil From bd56955f9a9207a0e1d7862f55a23385eb450cd2 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Mon, 27 Jun 2022 18:49:10 +0900 Subject: [PATCH 13/14] Do not drop activator always in the path --- pkg/reconciler/autoscaling/kpa/kpa.go | 6 +++ pkg/reconciler/autoscaling/kpa/kpa_test.go | 43 ++++++++++++++++++++++ test/e2e/autoscale_test.go | 12 ++++++ 3 files changed, 61 insertions(+) diff --git a/pkg/reconciler/autoscaling/kpa/kpa.go b/pkg/reconciler/autoscaling/kpa/kpa.go index 8258bce9bd15..8025575fc35e 100644 --- a/pkg/reconciler/autoscaling/kpa/kpa.go +++ b/pkg/reconciler/autoscaling/kpa/kpa.go @@ -126,6 +126,12 @@ func (c *Reconciler) ReconcileKind(ctx context.Context, pa *autoscalingv1alpha1. mode := nv1alpha1.SKSOperationModeProxy switch { + // When activator CA is enabled, force activator always in path. + // TODO: This is a temporary state and to be fixed. + // See also issues/11906 and issues/12797. + case config.FromContext(ctx).Network.InternalEncryption: + mode = nv1alpha1.SKSOperationModeProxy + // If the want == -1 and PA is inactive that implies the autoscaler // has no knowledge of the revision (due to restart) but it was previously // scaled down (inactive). In this instance we want to remain in Proxy Mode diff --git a/pkg/reconciler/autoscaling/kpa/kpa_test.go b/pkg/reconciler/autoscaling/kpa/kpa_test.go index 56a1688240f6..59541f50ff7f 100644 --- a/pkg/reconciler/autoscaling/kpa/kpa_test.go +++ b/pkg/reconciler/autoscaling/kpa/kpa_test.go @@ -126,16 +126,27 @@ func initialScaleZeroASConfig() *autoscalerconfig.Config { return ac } +func activatorCertsNetConfig() *netcfg.Config { + nc, _ := netcfg.NewConfigFromMap(map[string]string{ + netcfg.InternalEncryptionKey: "true", + }) + return nc +} + func defaultConfig() *config.Config { ac, _ := asconfig.NewConfigFromMap(defaultConfigMapData()) deploymentConfig, _ := deployment.NewConfigFromMap(map[string]string{ deployment.QueueSidecarImageKey: "bob", deployment.ProgressDeadlineKey: progressDeadline.String(), }) + networkConfig, _ := netcfg.NewConfigFromMap(map[string]string{ + netcfg.InternalEncryptionKey: "false", + }) return &config.Config{ Autoscaler: ac, Deployment: deploymentConfig, + Network: networkConfig, } } @@ -1128,6 +1139,38 @@ func TestReconcile(t *testing.T) { WithPAMetricsService(privateSvc), WithObservedGeneration(1), ), }}, + }, { + Name: "we have enough burst capacity, but keep proxy mode as activator CA is enabled", + Key: key, + Ctx: context.WithValue(context.WithValue(context.Background(), netConfigKey{}, activatorCertsNetConfig()), deciderKey{}, + decider(testNamespace, testRevision, defaultScale, /* desiredScale */ + 1 /* ebc */)), + Objects: []runtime.Object{ + kpa(testNamespace, testRevision, WithPASKSReady, WithTraffic, markScaleTargetInitialized, + WithPAMetricsService(privateSvc), withScales(1, defaultScale), + WithPAStatusService(testRevision), WithObservedGeneration(1)), + defaultProxySKS, + metric(testNamespace, testRevision), + defaultDeployment, + defaultReady}, + // No update from ProxySKS. + }, { + Name: "we have enough burst capacity, but switch to keep proxy mode as activator CA is turned on", + Key: key, + Ctx: context.WithValue(context.WithValue(context.Background(), netConfigKey{}, activatorCertsNetConfig()), deciderKey{}, + decider(testNamespace, testRevision, defaultScale, /* desiredScale */ + 1 /* ebc */)), + Objects: []runtime.Object{ + kpa(testNamespace, testRevision, WithPASKSReady, WithTraffic, markScaleTargetInitialized, + WithPAMetricsService(privateSvc), withScales(1, defaultScale), + WithPAStatusService(testRevision), WithObservedGeneration(1)), + defaultSKS, + metric(testNamespace, testRevision), + defaultDeployment, + defaultReady}, + WantUpdates: []clientgotesting.UpdateActionImpl{{ + Object: defaultProxySKS, + }}, }} table.Test(t, MakeFactory(func(ctx context.Context, listers *Listers, cmw configmap.Watcher) controller.Reconciler { diff --git a/test/e2e/autoscale_test.go b/test/e2e/autoscale_test.go index fa4725061ecd..1184ea390430 100644 --- a/test/e2e/autoscale_test.go +++ b/test/e2e/autoscale_test.go @@ -21,6 +21,7 @@ package e2e import ( "context" + "strings" "testing" "time" @@ -28,6 +29,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" + netcfg "knative.dev/networking/pkg/config" "knative.dev/pkg/system" "knative.dev/serving/pkg/apis/autoscaling" "knative.dev/serving/pkg/networking" @@ -137,6 +139,16 @@ func TestTargetBurstCapacity(t *testing.T) { })) test.EnsureTearDown(t, ctx.Clients(), ctx.Names()) + cm, err := ctx.clients.KubeClient.CoreV1().ConfigMaps(system.Namespace()). + Get(context.Background(), netcfg.ConfigMapName, metav1.GetOptions{}) + if err != nil { + t.Fatal("Fail to get ConfigMap config-network:", err) + } + if strings.EqualFold(cm.Data[netcfg.InternalEncryptionKey], "true") { + // TODO: Remove this when https://github.com/knative/serving/issues/12797 was done. + t.Skip("Skipping TestTargetBurstCapacity as activator-ca is specified. See issue/12797.") + } + cfg, err := autoscalerCM(ctx.clients) if err != nil { t.Fatal("Error retrieving autoscaler configmap:", err) From 7a929b04ce65d08c10d99e1359b54fa90aadeb14 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Wed, 29 Jun 2022 17:43:40 +0900 Subject: [PATCH 14/14] Comment about ctrl-ca suffix --- config/core/300-secret.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/core/300-secret.yaml b/config/core/300-secret.yaml index ae936886d31c..06956c829281 100644 --- a/config/core/300-secret.yaml +++ b/config/core/300-secret.yaml @@ -15,6 +15,8 @@ apiVersion: v1 kind: Secret metadata: + # Do not drop -ctrl-ca suffix as control-protocol requires it. + # https://github.com/knative-sandbox/control-protocol/blob/main/pkg/certificates/reconciler/controller.go name: serving-certs-ctrl-ca namespace: knative-serving # The data is populated when internal-encryption is enabled.