├── pkg ├── apiserver │ ├── testdata │ │ ├── generate.client.json │ │ ├── README.md │ │ ├── generate.client-ca.json │ │ ├── generate.server-ca.json │ │ ├── generate.server.json │ │ ├── client-ca-key.pem │ │ ├── client-key.pem │ │ ├── server-ca-key.pem │ │ ├── server-key.pem │ │ ├── client-ca.pem │ │ ├── server-ca.pem │ │ ├── generate.profiles.json │ │ ├── client.pem │ │ ├── server.pem │ │ └── generate.sh │ ├── scheme │ │ └── scheme.go │ ├── metrics.go │ └── resolvers.go ├── registry │ └── apiservice │ │ ├── etcd │ │ └── OWNERS │ │ └── rest │ │ └── storage_apiservice.go ├── apis │ ├── OWNERS │ ├── apiregistration │ │ ├── doc.go │ │ ├── v1 │ │ │ ├── defaults.go │ │ │ ├── generated.protomessage.pb.go │ │ │ ├── zz_generated.prerelease-lifecycle.go │ │ │ ├── zz_generated.defaults.go │ │ │ ├── doc.go │ │ │ ├── zz_generated.model_name.go │ │ │ ├── register.go │ │ │ ├── zz_generated.deepcopy.go │ │ │ └── helper │ │ │ │ └── helpers.go │ │ ├── v1beta1 │ │ │ ├── defaults.go │ │ │ ├── generated.protomessage.pb.go │ │ │ ├── zz_generated.defaults.go │ │ │ ├── doc.go │ │ │ ├── zz_generated.model_name.go │ │ │ ├── register.go │ │ │ ├── zz_generated.prerelease-lifecycle.go │ │ │ └── zz_generated.deepcopy.go │ │ ├── install │ │ │ └── install.go │ │ ├── register.go │ │ └── helpers.go │ ├── roundtrip_test.go │ └── openapi_models_test.go ├── client │ ├── clientset_generated │ │ └── clientset │ │ │ ├── fake │ │ │ ├── doc.go │ │ │ ├── register.go │ │ │ └── clientset_generated.go │ │ │ ├── typed │ │ │ └── apiregistration │ │ │ │ ├── v1 │ │ │ │ ├── generated_expansion.go │ │ │ │ ├── doc.go │ │ │ │ ├── fake │ │ │ │ │ ├── doc.go │ │ │ │ │ ├── fake_apiregistration_client.go │ │ │ │ │ └── fake_apiservice.go │ │ │ │ ├── apiservice.go │ │ │ │ └── apiregistration_client.go │ │ │ │ └── v1beta1 │ │ │ │ ├── fake │ │ │ │ ├── doc.go │ │ │ │ ├── fake_apiregistration_client.go │ │ │ │ └── fake_apiservice.go │ │ │ │ ├── generated_expansion.go │ │ │ │ ├── doc.go │ │ │ │ ├── apiservice.go │ │ │ │ └── apiregistration_client.go │ │ │ ├── scheme │ │ │ ├── doc.go │ │ │ └── register.go │ │ │ └── clientset.go │ ├── listers │ │ └── apiregistration │ │ │ ├── v1 │ │ │ ├── expansion_generated.go │ │ │ └── apiservice.go │ │ │ └── v1beta1 │ │ │ ├── expansion_generated.go │ │ │ └── apiservice.go │ └── informers │ │ └── externalversions │ │ ├── internalinterfaces │ │ └── factory_interfaces.go │ │ ├── apiregistration │ │ ├── v1 │ │ │ ├── interface.go │ │ │ └── apiservice.go │ │ ├── v1beta1 │ │ │ ├── interface.go │ │ │ └── apiservice.go │ │ └── interface.go │ │ └── generic.go └── controllers │ ├── cache.go │ ├── openapi │ ├── aggregator │ │ ├── metrics.go │ │ ├── priority_test.go │ │ ├── priority.go │ │ ├── downloader_test.go │ │ └── downloader.go │ └── controller.go │ ├── status │ └── metrics │ │ └── metrics_test.go │ └── openapiv3 │ └── aggregator │ ├── downloader_test.go │ └── downloader.go ├── artifacts ├── self-contained │ ├── kubernetes-discovery-sa.yaml │ ├── etcd-svc.yaml │ ├── kubernetes-discovery-svc.yaml │ ├── etcd-pod.yaml │ └── kubernetes-discover-pod.yaml ├── simple-image │ └── Dockerfile └── hostpath-pods │ └── insecure-etcd-pod.yaml ├── code-of-conduct.md ├── .github └── PULL_REQUEST_TEMPLATE.md ├── hack ├── apiservice-template.yaml ├── boilerplate.go.txt ├── tools.go ├── build-image.sh ├── verify-codegen.sh ├── update-codegen.sh ├── godep-deps.sh ├── sync-from-kubernetes.sh ├── register-all-apis-from.sh └── local-up-kube-aggregator.sh ├── OWNERS ├── SECURITY_CONTACTS ├── CONTRIBUTING.md ├── main.go ├── README.md └── go.mod /pkg/apiserver/testdata/generate.client.json: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "My Client" 3 | } -------------------------------------------------------------------------------- /pkg/apiserver/testdata/README.md: -------------------------------------------------------------------------------- 1 | Keys in this directory are generated for testing purposes only. 2 | -------------------------------------------------------------------------------- /pkg/registry/apiservice/etcd/OWNERS: -------------------------------------------------------------------------------- 1 | # See the OWNERS docs at https://go.k8s.io/owners 2 | 3 | labels: 4 | - sig/etcd 5 | -------------------------------------------------------------------------------- /artifacts/self-contained/kubernetes-discovery-sa.yaml: -------------------------------------------------------------------------------- 1 | kind: ServiceAccount 2 | apiVersion: v1 3 | metadata: 4 | name: kube-aggregator -------------------------------------------------------------------------------- /pkg/apiserver/testdata/generate.client-ca.json: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "Client-CA", 3 | "ca": { 4 | "expiry": "876000h" 5 | } 6 | } -------------------------------------------------------------------------------- /pkg/apiserver/testdata/generate.server-ca.json: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "Server-CA", 3 | "ca": { 4 | "expiry": "876000h" 5 | } 6 | } -------------------------------------------------------------------------------- /pkg/apiserver/testdata/generate.server.json: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "test-service2.test-ns.svc", 3 | "hosts": ["test-service2.test-ns.svc"] 4 | } -------------------------------------------------------------------------------- /code-of-conduct.md: -------------------------------------------------------------------------------- 1 | # Kubernetes Community Code of Conduct 2 | 3 | Please refer to our [Kubernetes Community Code of Conduct](https://git.k8s.io/community/code-of-conduct.md) 4 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Sorry, we do not accept changes directly against this repository. Please see 2 | CONTRIBUTING.md for information on where and how to contribute instead. 3 | -------------------------------------------------------------------------------- /artifacts/self-contained/etcd-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: etcd 5 | spec: 6 | ports: 7 | - port: 4001 8 | protocol: TCP 9 | targetPort: 4001 10 | selector: 11 | etcd: "true" 12 | -------------------------------------------------------------------------------- /pkg/apiserver/testdata/client-ca-key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEIHM3EPGDat3kZv4DmyI6X0k6gHGP9JSS3R9t0sCvcj1coAoGCCqGSM49 3 | AwEHoUQDQgAEA4QqivypLZVLaoFYAS0UWyfyNRSXRtgMWEabvsoHO31CRa2ZS3m8 4 | glOQ21aLysVdF6vAP31O9fqysuGMm0UI7w== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /pkg/apiserver/testdata/client-key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEIJVbghSTWVClgCMEMWHf4Z5QRHplGl3OZzNvvYVc1hVLoAoGCCqGSM49 3 | AwEHoUQDQgAEI7HyyXMDVAU8o3kQpInG+Ec1mCELWJrKz2owv0jONgc7dkDjKHuP 4 | 7UkDuKGrUpS2MW0UkqajJAODEUwSF1wH5A== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /pkg/apiserver/testdata/server-ca-key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEIBoMWQC4K4Vp/wKA7yHBVWgjV69lpGhAZZAAcsf8osUVoAoGCCqGSM49 3 | AwEHoUQDQgAEPwxv8IjkfU5AivcK0IiurHL9H6EiGh+zZ0S8r+PBW0DXFPXcAjQc 4 | tE8gVHu3fp90y1JVTriaxriU/x8Lbrp8ZA== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /pkg/apiserver/testdata/server-key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEIFizWdUWI/ggduZByisCOjPljfUq/f++RwQl0scxeOU/oAoGCCqGSM49 3 | AwEHoUQDQgAEvw23SM/msE+rsXx919gkNM+A7HBJ99YXqvsV0zRd6ykiQV5rszGw 4 | DHF/3sKTbb38eLcF/sORWVEFc4+QqnZLkw== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /pkg/apis/OWNERS: -------------------------------------------------------------------------------- 1 | # See the OWNERS docs at https://go.k8s.io/owners 2 | 3 | # Disable inheritance as this is an api owners file 4 | options: 5 | no_parent_owners: true 6 | approvers: 7 | - api-approvers 8 | reviewers: 9 | - api-reviewers 10 | labels: 11 | - kind/api-change 12 | -------------------------------------------------------------------------------- /hack/apiservice-template.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiregistration.k8s.io/v1 2 | kind: APIService 3 | metadata: 4 | name: RESOURCE_NAME 5 | spec: 6 | group: API_GROUP 7 | version: API_VERSION 8 | service: 9 | namespace: SERVICE_NAMESPACE 10 | name: SERVICE_NAME 11 | caBundle: CA_BUNDLE 12 | priority: 100 13 | -------------------------------------------------------------------------------- /artifacts/self-contained/kubernetes-discovery-svc.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | kube-aggregator: "true" 6 | name: kube-aggregator 7 | spec: 8 | ports: 9 | - port: 443 10 | protocol: TCP 11 | nodePort: 31090 12 | targetPort: 443 13 | selector: 14 | kube-aggregator: "true" 15 | type: NodePort 16 | -------------------------------------------------------------------------------- /OWNERS: -------------------------------------------------------------------------------- 1 | # See the OWNERS docs at https://go.k8s.io/owners 2 | 3 | approvers: 4 | - deads2k 5 | - smarterclayton 6 | - sttts 7 | - jpbetz 8 | reviewers: 9 | - caesarxuchao 10 | - deads2k 11 | - smarterclayton 12 | - liggitt 13 | - sttts 14 | - cheftako 15 | - logicalhan 16 | - alexzielenski 17 | - jefftree 18 | - jpbetz 19 | labels: 20 | - sig/api-machinery 21 | emeritus_approvers: 22 | - lavalamp 23 | -------------------------------------------------------------------------------- /pkg/apiserver/testdata/client-ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBbTCCARSgAwIBAgIUDMmq4/Gw2N1o5TWBLWsm65RiVkIwCgYIKoZIzj0EAwIw 3 | FDESMBAGA1UEAxMJQ2xpZW50LUNBMCAXDTIxMDUyMjIzNTIwMFoYDzIxMjEwNDI4 4 | MjM1MjAwWjAUMRIwEAYDVQQDEwlDbGllbnQtQ0EwWTATBgcqhkjOPQIBBggqhkjO 5 | PQMBBwNCAAQDhCqK/KktlUtqgVgBLRRbJ/I1FJdG2AxYRpu+ygc7fUJFrZlLebyC 6 | U5DbVovKxV0Xq8A/fU71+rKy4YybRQjvo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD 7 | VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUaDl2pG6N7NoORQjpHprKDSOL8+0wCgYI 8 | KoZIzj0EAwIDRwAwRAIgbS1tdj6El37kUwF9yZDXKfjLUlRBBLmIYhP0mdui6/AC 9 | IB4F/weuM/6IjCdcPJRxvdC7qjCdV0xnFqvQ+BhuUGSF 10 | -----END CERTIFICATE----- 11 | -------------------------------------------------------------------------------- /SECURITY_CONTACTS: -------------------------------------------------------------------------------- 1 | # Defined below are the security contacts for this repo. 2 | # 3 | # They are the contact point for the Product Security Committee to reach out 4 | # to for triaging and handling of incoming issues. 5 | # 6 | # The below names agree to abide by the 7 | # [Embargo Policy](https://git.k8s.io/security/private-distributors-list.md#embargo-policy) 8 | # and will be removed and replaced if they violate that agreement. 9 | # 10 | # DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE 11 | # INSTRUCTIONS AT https://kubernetes.io/security/ 12 | 13 | cheftako 14 | deads2k 15 | lavalamp 16 | sttts 17 | -------------------------------------------------------------------------------- /pkg/apiserver/testdata/server-ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBbzCCARSgAwIBAgIUf0aG2C1P7KaDGobg9oeN3uhQlu4wCgYIKoZIzj0EAwIw 3 | FDESMBAGA1UEAxMJU2VydmVyLUNBMCAXDTIxMDUyMjIzNTIwMFoYDzIxMjEwNDI4 4 | MjM1MjAwWjAUMRIwEAYDVQQDEwlTZXJ2ZXItQ0EwWTATBgcqhkjOPQIBBggqhkjO 5 | PQMBBwNCAAQ/DG/wiOR9TkCK9wrQiK6scv0foSIaH7NnRLyv48FbQNcU9dwCNBy0 6 | TyBUe7d+n3TLUlVOuJrGuJT/Hwtuunxko0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYD 7 | VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUjcdIlU1vGLSUWBcSqCEJTgqlSacwCgYI 8 | KoZIzj0EAwIDSQAwRgIhAIujFeJKprddp+9aCZZUv05jCS5JiopW2bn/FJJRQ6OK 9 | AiEA1NS6trAbfgk6vYS2D2vamuF4XC9LggyxbcoaMf+GAn4= 10 | -----END CERTIFICATE----- 11 | -------------------------------------------------------------------------------- /pkg/apiserver/testdata/generate.profiles.json: -------------------------------------------------------------------------------- 1 | { 2 | "signing": { 3 | "profiles": { 4 | "client": { 5 | "expiry": "876000h", 6 | "usages": [ 7 | "signing", 8 | "key encipherment", 9 | "client auth" 10 | ] 11 | }, 12 | "server": { 13 | "expiry": "876000h", 14 | "usages": [ 15 | "signing", 16 | "key encipherment", 17 | "server auth" 18 | ] 19 | } 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /hack/boilerplate.go.txt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | -------------------------------------------------------------------------------- /pkg/apiserver/testdata/client.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIBoTCCAUegAwIBAgIUci8u0GG5LGSaykYqdgYL9ZIO/v4wCgYIKoZIzj0EAwIw 3 | FDESMBAGA1UEAxMJQ2xpZW50LUNBMCAXDTIxMDUyMjIzNTIwMFoYDzIxMjEwNDI4 4 | MjM1MjAwWjAUMRIwEAYDVQQDEwlNeSBDbGllbnQwWTATBgcqhkjOPQIBBggqhkjO 5 | PQMBBwNCAAQjsfLJcwNUBTyjeRCkicb4RzWYIQtYmsrPajC/SM42Bzt2QOMoe4/t 6 | SQO4oatSlLYxbRSSpqMkA4MRTBIXXAfko3UwczAOBgNVHQ8BAf8EBAMCBaAwEwYD 7 | VR0lBAwwCgYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUaS3acr6g 8 | cfHE/zty3M0nd9aDo30wHwYDVR0jBBgwFoAUaDl2pG6N7NoORQjpHprKDSOL8+0w 9 | CgYIKoZIzj0EAwIDSAAwRQIhAPjuVM2rWOhyzfRqAAdn8a/LJxjLf1+bjrb/cyT4 10 | h0LbAiBE8MY0gARwVYoRgYmVMXyewwjW+SVu+y8+kQv7uCFJzg== 11 | -----END CERTIFICATE----- 12 | -------------------------------------------------------------------------------- /artifacts/simple-image/Dockerfile: -------------------------------------------------------------------------------- 1 | # Copyright 2016 The Kubernetes Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | FROM fedora 16 | ADD kube-aggregator / 17 | ENTRYPOINT ["/kube-aggregator"] 18 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing guidelines 2 | 3 | Do not open pull requests directly against this repository, they will be ignored. Instead, please open pull requests against [kubernetes/kubernetes](https://git.k8s.io/kubernetes/). Please follow the same [contributing guide](https://git.k8s.io/kubernetes/CONTRIBUTING.md) you would follow for any other pull request made to kubernetes/kubernetes. 4 | 5 | This repository is published from [kubernetes/kubernetes/staging/src/k8s.io/kube-aggregator](https://git.k8s.io/kubernetes/staging/src/k8s.io/kube-aggregator) by the [kubernetes publishing-bot](https://git.k8s.io/publishing-bot). 6 | 7 | Please see [Staging Directory and Publishing](https://git.k8s.io/community/contributors/devel/sig-architecture/staging.md) for more information 8 | -------------------------------------------------------------------------------- /pkg/apiserver/testdata/server.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIB2jCCAX+gAwIBAgIUKcO5RlFpX+/7Ed5WR/kqFtuOjJswCgYIKoZIzj0EAwIw 3 | FDESMBAGA1UEAxMJU2VydmVyLUNBMCAXDTIxMDUyMjIzNTIwMFoYDzIxMjEwNDI4 4 | MjM1MjAwWjAkMSIwIAYDVQQDExl0ZXN0LXNlcnZpY2UyLnRlc3QtbnMuc3ZjMFkw 5 | EwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEvw23SM/msE+rsXx919gkNM+A7HBJ99YX 6 | qvsV0zRd6ykiQV5rszGwDHF/3sKTbb38eLcF/sORWVEFc4+QqnZLk6OBnDCBmTAO 7 | BgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDAYDVR0TAQH/BAIw 8 | ADAdBgNVHQ4EFgQUkDkrXrpDB9jRA2CnWRAbb4GZWdgwHwYDVR0jBBgwFoAUjcdI 9 | lU1vGLSUWBcSqCEJTgqlSacwJAYDVR0RBB0wG4IZdGVzdC1zZXJ2aWNlMi50ZXN0 10 | LW5zLnN2YzAKBggqhkjOPQQDAgNJADBGAiEAt/gcJpu0+whAUjTvkcS1zwnaLjuY 11 | nij9Q+UNkxle7UICIQDmyixha4e/2gufANiSeYKu9IzSJ6vyRgvbAlZ0ihAsOA== 12 | -----END CERTIFICATE----- 13 | -------------------------------------------------------------------------------- /pkg/client/clientset_generated/clientset/fake/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | // This package has the automatically generated fake clientset. 20 | package fake 21 | -------------------------------------------------------------------------------- /pkg/client/clientset_generated/clientset/typed/apiregistration/v1/generated_expansion.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package v1 20 | 21 | type APIServiceExpansion interface{} 22 | -------------------------------------------------------------------------------- /pkg/apis/apiregistration/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // +k8s:deepcopy-gen=package 18 | // +groupName=apiregistration.k8s.io 19 | 20 | // Package apiregistration is the internal version of the API. 21 | package apiregistration 22 | -------------------------------------------------------------------------------- /pkg/client/clientset_generated/clientset/scheme/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | // This package contains the scheme of the automatically generated clientset. 20 | package scheme 21 | -------------------------------------------------------------------------------- /pkg/client/clientset_generated/clientset/typed/apiregistration/v1/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | // This package has the automatically generated typed clients. 20 | package v1 21 | -------------------------------------------------------------------------------- /pkg/client/clientset_generated/clientset/typed/apiregistration/v1/fake/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | // Package fake has the automatically generated clients. 20 | package fake 21 | -------------------------------------------------------------------------------- /pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/fake/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | // Package fake has the automatically generated clients. 20 | package fake 21 | -------------------------------------------------------------------------------- /pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/generated_expansion.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package v1beta1 20 | 21 | type APIServiceExpansion interface{} 22 | -------------------------------------------------------------------------------- /pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | // This package has the automatically generated typed clients. 20 | package v1beta1 21 | -------------------------------------------------------------------------------- /hack/tools.go: -------------------------------------------------------------------------------- 1 | //go:build tools 2 | // +build tools 3 | 4 | /* 5 | Copyright 2019 The Kubernetes Authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | // This package imports things required by build scripts, to force `go mod` to see them as dependencies 21 | package tools 22 | 23 | import _ "k8s.io/code-generator" 24 | -------------------------------------------------------------------------------- /pkg/client/listers/apiregistration/v1/expansion_generated.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by lister-gen. DO NOT EDIT. 18 | 19 | package v1 20 | 21 | // APIServiceListerExpansion allows custom methods to be added to 22 | // APIServiceLister. 23 | type APIServiceListerExpansion interface{} 24 | -------------------------------------------------------------------------------- /pkg/client/listers/apiregistration/v1beta1/expansion_generated.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by lister-gen. DO NOT EDIT. 18 | 19 | package v1beta1 20 | 21 | // APIServiceListerExpansion allows custom methods to be added to 22 | // APIServiceLister. 23 | type APIServiceListerExpansion interface{} 24 | -------------------------------------------------------------------------------- /pkg/apis/apiregistration/v1/defaults.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1 18 | 19 | import ( 20 | "k8s.io/apimachinery/pkg/runtime" 21 | "k8s.io/utils/ptr" 22 | ) 23 | 24 | func addDefaultingFuncs(scheme *runtime.Scheme) error { 25 | return RegisterDefaults(scheme) 26 | } 27 | 28 | // SetDefaults_ServiceReference sets defaults for AuditSync Webhook's ServiceReference 29 | func SetDefaults_ServiceReference(obj *ServiceReference) { 30 | if obj.Port == nil { 31 | obj.Port = ptr.To[int32](443) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /pkg/apis/apiregistration/v1beta1/defaults.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1beta1 18 | 19 | import ( 20 | "k8s.io/apimachinery/pkg/runtime" 21 | "k8s.io/utils/ptr" 22 | ) 23 | 24 | func addDefaultingFuncs(scheme *runtime.Scheme) error { 25 | return RegisterDefaults(scheme) 26 | } 27 | 28 | // SetDefaults_ServiceReference sets defaults for AuditSync Webhook's ServiceReference 29 | func SetDefaults_ServiceReference(obj *ServiceReference) { 30 | if obj.Port == nil { 31 | obj.Port = ptr.To[int32](443) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /pkg/apis/apiregistration/v1/generated.protomessage.pb.go: -------------------------------------------------------------------------------- 1 | //go:build kubernetes_protomessage_one_more_release 2 | // +build kubernetes_protomessage_one_more_release 3 | 4 | /* 5 | Copyright The Kubernetes Authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | // Code generated by go-to-protobuf. DO NOT EDIT. 21 | 22 | package v1 23 | 24 | func (*APIService) ProtoMessage() {} 25 | 26 | func (*APIServiceCondition) ProtoMessage() {} 27 | 28 | func (*APIServiceList) ProtoMessage() {} 29 | 30 | func (*APIServiceSpec) ProtoMessage() {} 31 | 32 | func (*APIServiceStatus) ProtoMessage() {} 33 | 34 | func (*ServiceReference) ProtoMessage() {} 35 | -------------------------------------------------------------------------------- /pkg/apis/apiregistration/v1beta1/generated.protomessage.pb.go: -------------------------------------------------------------------------------- 1 | //go:build kubernetes_protomessage_one_more_release 2 | // +build kubernetes_protomessage_one_more_release 3 | 4 | /* 5 | Copyright The Kubernetes Authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | // Code generated by go-to-protobuf. DO NOT EDIT. 21 | 22 | package v1beta1 23 | 24 | func (*APIService) ProtoMessage() {} 25 | 26 | func (*APIServiceCondition) ProtoMessage() {} 27 | 28 | func (*APIServiceList) ProtoMessage() {} 29 | 30 | func (*APIServiceSpec) ProtoMessage() {} 31 | 32 | func (*APIServiceStatus) ProtoMessage() {} 33 | 34 | func (*ServiceReference) ProtoMessage() {} 35 | -------------------------------------------------------------------------------- /pkg/apiserver/testdata/generate.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright 2021 The Kubernetes Authors. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | cfssl gencert -initca generate.client-ca.json | cfssljson -bare client-ca 18 | cfssl gencert -initca generate.server-ca.json | cfssljson -bare server-ca 19 | 20 | cfssl gencert -ca client-ca.pem -ca-key client-ca-key.pem -config generate.profiles.json --profile=client generate.client.json | cfssljson -bare client 21 | cfssl gencert -ca server-ca.pem -ca-key server-ca-key.pem -config generate.profiles.json --profile=server generate.server.json | cfssljson -bare server 22 | 23 | rm ./*.csr 24 | -------------------------------------------------------------------------------- /pkg/apiserver/scheme/scheme.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package scheme 18 | 19 | import ( 20 | "k8s.io/apimachinery/pkg/runtime" 21 | "k8s.io/apimachinery/pkg/runtime/serializer" 22 | 23 | "k8s.io/kube-aggregator/pkg/apis/apiregistration/install" 24 | ) 25 | 26 | var ( 27 | // Scheme defines methods for serializing and deserializing API objects. 28 | Scheme = runtime.NewScheme() 29 | // Codecs provides methods for retrieving codecs and serializers for specific 30 | // versions and content types. 31 | Codecs = serializer.NewCodecFactory(Scheme) 32 | ) 33 | 34 | func init() { 35 | install.Install(Scheme) 36 | } 37 | -------------------------------------------------------------------------------- /hack/build-image.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright 2014 The Kubernetes Authors. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -o errexit 18 | set -o nounset 19 | set -o pipefail 20 | 21 | KUBE_ROOT=$(dirname "${BASH_SOURCE[0]}")/../../../../.. 22 | source "${KUBE_ROOT}/hack/lib/util.sh" 23 | 24 | # Register function to be called on EXIT to remove generated binary. 25 | function cleanup { 26 | rm "${KUBE_ROOT}/staging/src/k8s.io/kube-aggregator/artifacts/simple-image/kube-aggregator" 27 | } 28 | trap cleanup EXIT 29 | 30 | pushd "${KUBE_ROOT}/staging/src/k8s.io/kube-aggregator" 31 | cp -v ../../../../_output/local/bin/linux/amd64/kube-aggregator ./artifacts/simple-image/kube-aggregator 32 | docker build -t kube-aggregator:latest ./artifacts/simple-image 33 | popd 34 | -------------------------------------------------------------------------------- /pkg/apis/apiregistration/install/install.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package install 18 | 19 | import ( 20 | "k8s.io/apimachinery/pkg/runtime" 21 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 22 | "k8s.io/kube-aggregator/pkg/apis/apiregistration" 23 | "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" 24 | "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1" 25 | ) 26 | 27 | // Install registers the API group and adds types to a scheme 28 | func Install(scheme *runtime.Scheme) { 29 | utilruntime.Must(apiregistration.AddToScheme(scheme)) 30 | utilruntime.Must(v1.AddToScheme(scheme)) 31 | utilruntime.Must(v1beta1.AddToScheme(scheme)) 32 | utilruntime.Must(scheme.SetVersionPriority(v1.SchemeGroupVersion, v1beta1.SchemeGroupVersion)) 33 | } 34 | -------------------------------------------------------------------------------- /pkg/client/clientset_generated/clientset/typed/apiregistration/v1/fake/fake_apiregistration_client.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package fake 20 | 21 | import ( 22 | rest "k8s.io/client-go/rest" 23 | testing "k8s.io/client-go/testing" 24 | v1 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1" 25 | ) 26 | 27 | type FakeApiregistrationV1 struct { 28 | *testing.Fake 29 | } 30 | 31 | func (c *FakeApiregistrationV1) APIServices() v1.APIServiceInterface { 32 | return newFakeAPIServices(c) 33 | } 34 | 35 | // RESTClient returns a RESTClient that is used to communicate 36 | // with API server by this client implementation. 37 | func (c *FakeApiregistrationV1) RESTClient() rest.Interface { 38 | var ret *rest.RESTClient 39 | return ret 40 | } 41 | -------------------------------------------------------------------------------- /hack/verify-codegen.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright 2016 The Kubernetes Authors. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -o errexit 18 | set -o nounset 19 | set -o pipefail 20 | 21 | SCRIPT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)" 22 | DIFFROOT="${SCRIPT_ROOT}/pkg" 23 | TMP_DIFFROOT="$(mktemp -d -t "$(basename "$0").XXXXXX")/pkg" 24 | 25 | cleanup() { 26 | rm -rf "${TMP_DIFFROOT}" 27 | } 28 | trap "cleanup" EXIT SIGINT 29 | 30 | cleanup 31 | 32 | mkdir -p "${TMP_DIFFROOT}" 33 | cp -a "${DIFFROOT}"/* "${TMP_DIFFROOT}" 34 | 35 | "${SCRIPT_ROOT}/hack/update-codegen.sh" 36 | echo "diffing ${DIFFROOT} against freshly generated codegen" 37 | ret=0 38 | diff -Naupr "${DIFFROOT}" "${TMP_DIFFROOT}" || ret=$? 39 | if [[ $ret -eq 0 ]]; then 40 | echo "${DIFFROOT} up to date." 41 | else 42 | echo "${DIFFROOT} is out of date. Please run hack/update-codegen.sh" 43 | fi 44 | exit $ret 45 | -------------------------------------------------------------------------------- /pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/fake/fake_apiregistration_client.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package fake 20 | 21 | import ( 22 | rest "k8s.io/client-go/rest" 23 | testing "k8s.io/client-go/testing" 24 | v1beta1 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1" 25 | ) 26 | 27 | type FakeApiregistrationV1beta1 struct { 28 | *testing.Fake 29 | } 30 | 31 | func (c *FakeApiregistrationV1beta1) APIServices() v1beta1.APIServiceInterface { 32 | return newFakeAPIServices(c) 33 | } 34 | 35 | // RESTClient returns a RESTClient that is used to communicate 36 | // with API server by this client implementation. 37 | func (c *FakeApiregistrationV1beta1) RESTClient() rest.Interface { 38 | var ret *rest.RESTClient 39 | return ret 40 | } 41 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "os" 21 | 22 | genericapiserver "k8s.io/apiserver/pkg/server" 23 | "k8s.io/component-base/cli" 24 | "k8s.io/kube-aggregator/pkg/cmd/server" 25 | 26 | // force compilation of packages we'll later rely upon 27 | _ "k8s.io/kube-aggregator/pkg/apis/apiregistration/install" 28 | _ "k8s.io/kube-aggregator/pkg/apis/apiregistration/validation" 29 | _ "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset" 30 | _ "k8s.io/kube-aggregator/pkg/client/listers/apiregistration/v1" 31 | _ "k8s.io/kube-aggregator/pkg/client/listers/apiregistration/v1beta1" 32 | ) 33 | 34 | func main() { 35 | ctx := genericapiserver.SetupSignalContext() 36 | options := server.NewDefaultOptions(os.Stdout, os.Stderr) 37 | cmd := server.NewCommandStartAggregator(ctx, options) 38 | code := cli.Run(cmd) 39 | os.Exit(code) 40 | } 41 | -------------------------------------------------------------------------------- /pkg/controllers/cache.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package controllers 18 | 19 | import ( 20 | "fmt" 21 | 22 | "k8s.io/klog/v2" 23 | 24 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 25 | "k8s.io/client-go/tools/cache" 26 | ) 27 | 28 | // WaitForCacheSync is a wrapper around cache.WaitForCacheSync that generates log messages 29 | // indicating that the controller identified by controllerName is waiting for syncs, followed by 30 | // either a successful or failed sync. 31 | func WaitForCacheSync(controllerName string, stopCh <-chan struct{}, cacheSyncs ...cache.InformerSynced) bool { 32 | klog.Infof("Waiting for caches to sync for %s controller", controllerName) 33 | 34 | if !cache.WaitForCacheSync(stopCh, cacheSyncs...) { 35 | utilruntime.HandleError(fmt.Errorf("Unable to sync caches for %s controller", controllerName)) 36 | return false 37 | } 38 | 39 | klog.Infof("Caches are synced for %s controller", controllerName) 40 | return true 41 | } 42 | -------------------------------------------------------------------------------- /pkg/apis/apiregistration/v1/zz_generated.prerelease-lifecycle.go: -------------------------------------------------------------------------------- 1 | //go:build !ignore_autogenerated 2 | // +build !ignore_autogenerated 3 | 4 | /* 5 | Copyright The Kubernetes Authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | // Code generated by prerelease-lifecycle-gen. DO NOT EDIT. 21 | 22 | package v1 23 | 24 | // APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. 25 | // It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. 26 | func (in *APIService) APILifecycleIntroduced() (major, minor int) { 27 | return 1, 10 28 | } 29 | 30 | // APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. 31 | // It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. 32 | func (in *APIServiceList) APILifecycleIntroduced() (major, minor int) { 33 | return 1, 10 34 | } 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > ⚠️ **This is an automatically published [staged repository](https://git.k8s.io/kubernetes/staging#external-repository-staging-area) for Kubernetes**. 2 | > Contributions, including issues and pull requests, should be made to the main Kubernetes repository: [https://github.com/kubernetes/kubernetes](https://github.com/kubernetes/kubernetes). 3 | > This repository is read-only for importing, and not used for direct contributions. 4 | > See [CONTRIBUTING.md](./CONTRIBUTING.md) for more details. 5 | 6 | # kube-aggregator 7 | 8 | Implements the [Aggregated API Servers](https://github.com/kubernetes/design-proposals-archive/blob/main/api-machinery/aggregated-api-servers.md) design proposal. 9 | 10 | It provides: 11 | 12 | * an API for registering API servers. 13 | * Summaries of discovery information from all the aggregated APIs 14 | * HTTP proxying of requests from clients on to specific API backends 15 | 16 | 17 | ## Purpose 18 | 19 | We want to divide the single monolithic API server into multiple aggregated 20 | servers. Anyone should be able to write their own aggregated API server to expose APIs they want. 21 | Cluster admins should be able to expose new APIs at runtime by bringing up new 22 | aggregated servers. 23 | 24 | 25 | ## Compatibility 26 | 27 | HEAD of this repo will match HEAD of k8s.io/apiserver, k8s.io/apimachinery, and k8s.io/client-go. 28 | 29 | ## Where does it come from? 30 | 31 | `kube-aggregator` is synced from https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/kube-aggregator. 32 | Code changes are made in that location, merged into `k8s.io/kubernetes` and later synced here. 33 | 34 | -------------------------------------------------------------------------------- /pkg/controllers/openapi/aggregator/metrics.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2019 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package aggregator 18 | 19 | import ( 20 | "k8s.io/component-base/metrics" 21 | "k8s.io/component-base/metrics/legacyregistry" 22 | ) 23 | 24 | var ( 25 | regenerationCounter = metrics.NewCounterVec( 26 | &metrics.CounterOpts{ 27 | Name: "aggregator_openapi_v2_regeneration_count", 28 | Help: "Counter of OpenAPI v2 spec regeneration count broken down by causing APIService name and reason.", 29 | StabilityLevel: metrics.ALPHA, 30 | }, 31 | []string{"apiservice", "reason"}, 32 | ) 33 | regenerationDurationGauge = metrics.NewGaugeVec( 34 | &metrics.GaugeOpts{ 35 | Name: "aggregator_openapi_v2_regeneration_duration", 36 | Help: "Gauge of OpenAPI v2 spec regeneration duration in seconds.", 37 | StabilityLevel: metrics.ALPHA, 38 | }, 39 | []string{"reason"}, 40 | ) 41 | ) 42 | 43 | func init() { 44 | legacyregistry.MustRegister(regenerationCounter) 45 | legacyregistry.MustRegister(regenerationDurationGauge) 46 | } 47 | -------------------------------------------------------------------------------- /pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by informer-gen. DO NOT EDIT. 18 | 19 | package internalinterfaces 20 | 21 | import ( 22 | time "time" 23 | 24 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 | runtime "k8s.io/apimachinery/pkg/runtime" 26 | cache "k8s.io/client-go/tools/cache" 27 | clientset "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset" 28 | ) 29 | 30 | // NewInformerFunc takes clientset.Interface and time.Duration to return a SharedIndexInformer. 31 | type NewInformerFunc func(clientset.Interface, time.Duration) cache.SharedIndexInformer 32 | 33 | // SharedInformerFactory a small interface to allow for adding an informer without an import cycle 34 | type SharedInformerFactory interface { 35 | Start(stopCh <-chan struct{}) 36 | InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer 37 | } 38 | 39 | // TweakListOptionsFunc is a function that transforms a v1.ListOptions. 40 | type TweakListOptionsFunc func(*v1.ListOptions) 41 | -------------------------------------------------------------------------------- /artifacts/self-contained/etcd-pod.yaml: -------------------------------------------------------------------------------- 1 | kind: ReplicationController 2 | apiVersion: v1 3 | metadata: 4 | name: etcd 5 | labels: 6 | etcd: "true" 7 | spec: 8 | replicas: 1 9 | selector: 10 | etcd: "true" 11 | template: 12 | metadata: 13 | labels: 14 | etcd: "true" 15 | spec: 16 | containers: 17 | - name: etcd 18 | image: gcr.io/etcd-development/etcd:v3.0.15 19 | command: 20 | - "etcd" 21 | - "--listen-client-urls=https://0.0.0.0:4001" 22 | - "--advertise-client-urls=https://etcd.kube-public.svc:4001" 23 | - "--trusted-ca-file=/var/run/serving-ca/ca.crt" 24 | - "--cert-file=/var/run/serving-cert/tls.crt" 25 | - "--key-file=/var/run/serving-cert/tls.key" 26 | - "--client-cert-auth=true" 27 | - "--listen-peer-urls=https://0.0.0.0:7001" 28 | - "--initial-advertise-peer-urls=https://etcd.kube-public.svc:7001" 29 | - "--peer-trusted-ca-file=/var/run/serving-ca/ca.crt" 30 | - "--peer-cert-file=/var/run/serving-cert/tls.crt" 31 | - "--peer-key-file=/var/run/serving-cert/tls.key" 32 | - "--peer-client-cert-auth=true" 33 | - "--initial-cluster=default=https://etcd.kube-public.svc:7001" 34 | ports: 35 | - containerPort: 4001 36 | volumeMounts: 37 | - mountPath: /var/run/serving-cert 38 | name: volume-serving-cert 39 | - mountPath: /var/run/serving-ca 40 | name: volume-etcd-ca 41 | volumes: 42 | - secret: 43 | defaultMode: 420 44 | secretName: serving-etcd 45 | name: volume-serving-cert 46 | - configMap: 47 | defaultMode: 420 48 | name: etcd-ca 49 | name: volume-etcd-ca 50 | 51 | -------------------------------------------------------------------------------- /pkg/apis/apiregistration/v1/zz_generated.defaults.go: -------------------------------------------------------------------------------- 1 | //go:build !ignore_autogenerated 2 | // +build !ignore_autogenerated 3 | 4 | /* 5 | Copyright The Kubernetes Authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | // Code generated by defaulter-gen. DO NOT EDIT. 21 | 22 | package v1 23 | 24 | import ( 25 | runtime "k8s.io/apimachinery/pkg/runtime" 26 | ) 27 | 28 | // RegisterDefaults adds defaulters functions to the given scheme. 29 | // Public to allow building arbitrary schemes. 30 | // All generated defaulters are covering - they call all nested defaulters. 31 | func RegisterDefaults(scheme *runtime.Scheme) error { 32 | scheme.AddTypeDefaultingFunc(&APIService{}, func(obj interface{}) { SetObjectDefaults_APIService(obj.(*APIService)) }) 33 | scheme.AddTypeDefaultingFunc(&APIServiceList{}, func(obj interface{}) { SetObjectDefaults_APIServiceList(obj.(*APIServiceList)) }) 34 | return nil 35 | } 36 | 37 | func SetObjectDefaults_APIService(in *APIService) { 38 | if in.Spec.Service != nil { 39 | SetDefaults_ServiceReference(in.Spec.Service) 40 | } 41 | } 42 | 43 | func SetObjectDefaults_APIServiceList(in *APIServiceList) { 44 | for i := range in.Items { 45 | a := &in.Items[i] 46 | SetObjectDefaults_APIService(a) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /pkg/client/informers/externalversions/apiregistration/v1/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by informer-gen. DO NOT EDIT. 18 | 19 | package v1 20 | 21 | import ( 22 | internalinterfaces "k8s.io/kube-aggregator/pkg/client/informers/externalversions/internalinterfaces" 23 | ) 24 | 25 | // Interface provides access to all the informers in this group version. 26 | type Interface interface { 27 | // APIServices returns a APIServiceInformer. 28 | APIServices() APIServiceInformer 29 | } 30 | 31 | type version struct { 32 | factory internalinterfaces.SharedInformerFactory 33 | namespace string 34 | tweakListOptions internalinterfaces.TweakListOptionsFunc 35 | } 36 | 37 | // New returns a new Interface. 38 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { 39 | return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} 40 | } 41 | 42 | // APIServices returns a APIServiceInformer. 43 | func (v *version) APIServices() APIServiceInformer { 44 | return &aPIServiceInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} 45 | } 46 | -------------------------------------------------------------------------------- /pkg/apis/apiregistration/v1beta1/zz_generated.defaults.go: -------------------------------------------------------------------------------- 1 | //go:build !ignore_autogenerated 2 | // +build !ignore_autogenerated 3 | 4 | /* 5 | Copyright The Kubernetes Authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | // Code generated by defaulter-gen. DO NOT EDIT. 21 | 22 | package v1beta1 23 | 24 | import ( 25 | runtime "k8s.io/apimachinery/pkg/runtime" 26 | ) 27 | 28 | // RegisterDefaults adds defaulters functions to the given scheme. 29 | // Public to allow building arbitrary schemes. 30 | // All generated defaulters are covering - they call all nested defaulters. 31 | func RegisterDefaults(scheme *runtime.Scheme) error { 32 | scheme.AddTypeDefaultingFunc(&APIService{}, func(obj interface{}) { SetObjectDefaults_APIService(obj.(*APIService)) }) 33 | scheme.AddTypeDefaultingFunc(&APIServiceList{}, func(obj interface{}) { SetObjectDefaults_APIServiceList(obj.(*APIServiceList)) }) 34 | return nil 35 | } 36 | 37 | func SetObjectDefaults_APIService(in *APIService) { 38 | if in.Spec.Service != nil { 39 | SetDefaults_ServiceReference(in.Spec.Service) 40 | } 41 | } 42 | 43 | func SetObjectDefaults_APIServiceList(in *APIServiceList) { 44 | for i := range in.Items { 45 | a := &in.Items[i] 46 | SetObjectDefaults_APIService(a) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /pkg/apis/roundtrip_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2024 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package apis 18 | 19 | import ( 20 | "testing" 21 | 22 | "k8s.io/apimachinery/pkg/api/apitesting/fuzzer" 23 | "k8s.io/apimachinery/pkg/api/apitesting/roundtrip" 24 | "k8s.io/apimachinery/pkg/runtime" 25 | "k8s.io/apimachinery/pkg/util/sets" 26 | "k8s.io/kube-aggregator/pkg/apis/apiregistration/install" 27 | apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" 28 | apiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1" 29 | ) 30 | 31 | func TestRoundtripToUnstructured(t *testing.T) { 32 | scheme := runtime.NewScheme() 33 | install.Install(scheme) 34 | 35 | roundtrip.RoundtripToUnstructured(t, scheme, fuzzer.MergeFuzzerFuncs(), sets.New( 36 | apiregistrationv1.SchemeGroupVersion.WithKind("CreateOptions"), 37 | apiregistrationv1.SchemeGroupVersion.WithKind("PatchOptions"), 38 | apiregistrationv1.SchemeGroupVersion.WithKind("UpdateOptions"), 39 | apiregistrationv1beta1.SchemeGroupVersion.WithKind("CreateOptions"), 40 | apiregistrationv1beta1.SchemeGroupVersion.WithKind("PatchOptions"), 41 | apiregistrationv1beta1.SchemeGroupVersion.WithKind("UpdateOptions"), 42 | ), nil) 43 | } 44 | -------------------------------------------------------------------------------- /pkg/client/informers/externalversions/apiregistration/v1beta1/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by informer-gen. DO NOT EDIT. 18 | 19 | package v1beta1 20 | 21 | import ( 22 | internalinterfaces "k8s.io/kube-aggregator/pkg/client/informers/externalversions/internalinterfaces" 23 | ) 24 | 25 | // Interface provides access to all the informers in this group version. 26 | type Interface interface { 27 | // APIServices returns a APIServiceInformer. 28 | APIServices() APIServiceInformer 29 | } 30 | 31 | type version struct { 32 | factory internalinterfaces.SharedInformerFactory 33 | namespace string 34 | tweakListOptions internalinterfaces.TweakListOptionsFunc 35 | } 36 | 37 | // New returns a new Interface. 38 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { 39 | return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} 40 | } 41 | 42 | // APIServices returns a APIServiceInformer. 43 | func (v *version) APIServices() APIServiceInformer { 44 | return &aPIServiceInformer{factory: v.factory, tweakListOptions: v.tweakListOptions} 45 | } 46 | -------------------------------------------------------------------------------- /pkg/apiserver/metrics.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package apiserver 18 | 19 | import ( 20 | "k8s.io/component-base/metrics" 21 | "k8s.io/component-base/metrics/legacyregistry" 22 | ) 23 | 24 | var x509MissingSANCounter = metrics.NewCounter( 25 | &metrics.CounterOpts{ 26 | Subsystem: "kube_aggregator", 27 | Namespace: "apiserver", 28 | Name: "x509_missing_san_total", 29 | Help: "Counts the number of requests to servers missing SAN extension " + 30 | "in their serving certificate OR the number of connection failures " + 31 | "due to the lack of x509 certificate SAN extension missing " + 32 | "(either/or, based on the runtime environment)", 33 | StabilityLevel: metrics.ALPHA, 34 | }, 35 | ) 36 | 37 | var x509InsecureSHA1Counter = metrics.NewCounter( 38 | &metrics.CounterOpts{ 39 | Subsystem: "kube_aggregator", 40 | Namespace: "apiserver", 41 | Name: "x509_insecure_sha1_total", 42 | Help: "Counts the number of requests to servers with insecure SHA1 signatures " + 43 | "in their serving certificate OR the number of connection failures " + 44 | "due to the insecure SHA1 signatures (either/or, based on the runtime environment)", 45 | StabilityLevel: metrics.ALPHA, 46 | }, 47 | ) 48 | 49 | func init() { 50 | legacyregistry.MustRegister(x509MissingSANCounter) 51 | legacyregistry.MustRegister(x509InsecureSHA1Counter) 52 | } 53 | -------------------------------------------------------------------------------- /pkg/client/listers/apiregistration/v1/apiservice.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by lister-gen. DO NOT EDIT. 18 | 19 | package v1 20 | 21 | import ( 22 | labels "k8s.io/apimachinery/pkg/labels" 23 | listers "k8s.io/client-go/listers" 24 | cache "k8s.io/client-go/tools/cache" 25 | apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" 26 | ) 27 | 28 | // APIServiceLister helps list APIServices. 29 | // All objects returned here must be treated as read-only. 30 | type APIServiceLister interface { 31 | // List lists all APIServices in the indexer. 32 | // Objects returned here must be treated as read-only. 33 | List(selector labels.Selector) (ret []*apiregistrationv1.APIService, err error) 34 | // Get retrieves the APIService from the index for a given name. 35 | // Objects returned here must be treated as read-only. 36 | Get(name string) (*apiregistrationv1.APIService, error) 37 | APIServiceListerExpansion 38 | } 39 | 40 | // aPIServiceLister implements the APIServiceLister interface. 41 | type aPIServiceLister struct { 42 | listers.ResourceIndexer[*apiregistrationv1.APIService] 43 | } 44 | 45 | // NewAPIServiceLister returns a new APIServiceLister. 46 | func NewAPIServiceLister(indexer cache.Indexer) APIServiceLister { 47 | return &aPIServiceLister{listers.New[*apiregistrationv1.APIService](indexer, apiregistrationv1.Resource("apiservice"))} 48 | } 49 | -------------------------------------------------------------------------------- /pkg/client/clientset_generated/clientset/typed/apiregistration/v1/fake/fake_apiservice.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package fake 20 | 21 | import ( 22 | gentype "k8s.io/client-go/gentype" 23 | v1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" 24 | apiregistrationv1 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1" 25 | ) 26 | 27 | // fakeAPIServices implements APIServiceInterface 28 | type fakeAPIServices struct { 29 | *gentype.FakeClientWithList[*v1.APIService, *v1.APIServiceList] 30 | Fake *FakeApiregistrationV1 31 | } 32 | 33 | func newFakeAPIServices(fake *FakeApiregistrationV1) apiregistrationv1.APIServiceInterface { 34 | return &fakeAPIServices{ 35 | gentype.NewFakeClientWithList[*v1.APIService, *v1.APIServiceList]( 36 | fake.Fake, 37 | "", 38 | v1.SchemeGroupVersion.WithResource("apiservices"), 39 | v1.SchemeGroupVersion.WithKind("APIService"), 40 | func() *v1.APIService { return &v1.APIService{} }, 41 | func() *v1.APIServiceList { return &v1.APIServiceList{} }, 42 | func(dst, src *v1.APIServiceList) { dst.ListMeta = src.ListMeta }, 43 | func(list *v1.APIServiceList) []*v1.APIService { return gentype.ToPointerSlice(list.Items) }, 44 | func(list *v1.APIServiceList, items []*v1.APIService) { list.Items = gentype.FromPointerSlice(items) }, 45 | ), 46 | fake, 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /pkg/client/listers/apiregistration/v1beta1/apiservice.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by lister-gen. DO NOT EDIT. 18 | 19 | package v1beta1 20 | 21 | import ( 22 | labels "k8s.io/apimachinery/pkg/labels" 23 | listers "k8s.io/client-go/listers" 24 | cache "k8s.io/client-go/tools/cache" 25 | apiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1" 26 | ) 27 | 28 | // APIServiceLister helps list APIServices. 29 | // All objects returned here must be treated as read-only. 30 | type APIServiceLister interface { 31 | // List lists all APIServices in the indexer. 32 | // Objects returned here must be treated as read-only. 33 | List(selector labels.Selector) (ret []*apiregistrationv1beta1.APIService, err error) 34 | // Get retrieves the APIService from the index for a given name. 35 | // Objects returned here must be treated as read-only. 36 | Get(name string) (*apiregistrationv1beta1.APIService, error) 37 | APIServiceListerExpansion 38 | } 39 | 40 | // aPIServiceLister implements the APIServiceLister interface. 41 | type aPIServiceLister struct { 42 | listers.ResourceIndexer[*apiregistrationv1beta1.APIService] 43 | } 44 | 45 | // NewAPIServiceLister returns a new APIServiceLister. 46 | func NewAPIServiceLister(indexer cache.Indexer) APIServiceLister { 47 | return &aPIServiceLister{listers.New[*apiregistrationv1beta1.APIService](indexer, apiregistrationv1beta1.Resource("apiservice"))} 48 | } 49 | -------------------------------------------------------------------------------- /pkg/apis/apiregistration/v1/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // +k8s:deepcopy-gen=package 18 | // +k8s:protobuf-gen=package 19 | // +k8s:conversion-gen=k8s.io/kube-aggregator/pkg/apis/apiregistration 20 | // +k8s:openapi-gen=true 21 | // +k8s:defaulter-gen=TypeMeta 22 | // +k8s:prerelease-lifecycle-gen=true 23 | // +k8s:openapi-model-package=io.k8s.kube-aggregator.pkg.apis.apiregistration.v1 24 | 25 | // +groupName=apiregistration.k8s.io 26 | 27 | // Package v1 contains the API Registration API, which is responsible for 28 | // registering an API `Group`/`Version` with another kubernetes like API server. 29 | // The `APIService` holds information about the other API server in 30 | // `APIServiceSpec` type as well as general `TypeMeta` and `ObjectMeta`. The 31 | // `APIServiceSpec` type have the main configuration needed to do the 32 | // aggregation. Any request coming for specified `Group`/`Version` will be 33 | // directed to the service defined by `ServiceReference` (on port 443) after 34 | // validating the target using provided `CABundle` or skipping validation 35 | // if development flag `InsecureSkipTLSVerify` is set. `Priority` is controlling 36 | // the order of this API group in the overall discovery document. 37 | // The return status is a set of conditions for this aggregation. Currently 38 | // there is only one condition named "Available", if true, it means the 39 | // api/server requests will be redirected to specified API server. 40 | package v1 41 | -------------------------------------------------------------------------------- /pkg/controllers/status/metrics/metrics_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2020 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package metrics 18 | 19 | import ( 20 | "strings" 21 | "testing" 22 | 23 | "k8s.io/component-base/metrics/testutil" 24 | ) 25 | 26 | func TestAPIServiceAvailabilityCollection(t *testing.T) { 27 | collector := newAvailabilityCollector() 28 | 29 | availableAPIService := "available" 30 | unavailableAPIService := "unavailable" 31 | 32 | collector.SetAPIServiceAvailable(availableAPIService) 33 | collector.SetAPIServiceUnavailable(unavailableAPIService) 34 | 35 | err := testutil.CustomCollectAndCompare(collector, strings.NewReader(` 36 | # HELP aggregator_unavailable_apiservice [ALPHA] Gauge of APIServices which are marked as unavailable broken down by APIService name. 37 | # TYPE aggregator_unavailable_apiservice gauge 38 | aggregator_unavailable_apiservice{name="available"} 0 39 | aggregator_unavailable_apiservice{name="unavailable"} 1 40 | `)) 41 | if err != nil { 42 | t.Fatal(err) 43 | } 44 | 45 | collector.ClearState() 46 | 47 | collector.ForgetAPIService(availableAPIService) 48 | collector.ForgetAPIService(unavailableAPIService) 49 | 50 | err = testutil.CustomCollectAndCompare(collector, strings.NewReader(` 51 | # HELP aggregator_unavailable_apiservice [ALPHA] Gauge of APIServices which are marked as unavailable broken down by APIService name. 52 | # TYPE aggregator_unavailable_apiservice gauge 53 | `)) 54 | if err != nil { 55 | t.Fatal(err) 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /pkg/apis/apiregistration/v1beta1/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // +k8s:deepcopy-gen=package 18 | // +k8s:protobuf-gen=package 19 | // +k8s:conversion-gen=k8s.io/kube-aggregator/pkg/apis/apiregistration 20 | // +k8s:openapi-gen=true 21 | // +k8s:defaulter-gen=TypeMeta 22 | // +k8s:prerelease-lifecycle-gen=true 23 | // +k8s:openapi-model-package=io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1 24 | 25 | // +groupName=apiregistration.k8s.io 26 | 27 | // Package v1beta1 contains the API Registration API, which is responsible for 28 | // registering an API `Group`/`Version` with another kubernetes like API server. 29 | // The `APIService` holds information about the other API server in 30 | // `APIServiceSpec` type as well as general `TypeMeta` and `ObjectMeta`. The 31 | // `APIServiceSpec` type have the main configuration needed to do the 32 | // aggregation. Any request coming for specified `Group`/`Version` will be 33 | // directed to the service defined by `ServiceReference` (on port 443) after 34 | // validating the target using provided `CABundle` or skipping validation 35 | // if development flag `InsecureSkipTLSVerify` is set. `Priority` is controlling 36 | // the order of this API group in the overall discovery document. 37 | // The return status is a set of conditions for this aggregation. Currently 38 | // there is only one condition named "Available", if true, it means the 39 | // api/server requests will be redirected to specified API server. 40 | package v1beta1 41 | -------------------------------------------------------------------------------- /pkg/apis/apiregistration/register.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package apiregistration 18 | 19 | import ( 20 | "k8s.io/apimachinery/pkg/runtime" 21 | "k8s.io/apimachinery/pkg/runtime/schema" 22 | ) 23 | 24 | // GroupName is the API group for apiregistration 25 | const GroupName = "apiregistration.k8s.io" 26 | 27 | // SchemeGroupVersion is group version used to register these objects 28 | var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: runtime.APIVersionInternal} 29 | 30 | // Kind takes an unqualified kind and returns back a Group qualified GroupKind 31 | func Kind(kind string) schema.GroupKind { 32 | return SchemeGroupVersion.WithKind(kind).GroupKind() 33 | } 34 | 35 | // Resource takes an unqualified resource and returns back a Group qualified GroupResource 36 | func Resource(resource string) schema.GroupResource { 37 | return SchemeGroupVersion.WithResource(resource).GroupResource() 38 | } 39 | 40 | var ( 41 | // SchemeBuilder is the scheme builder with scheme init functions to run for this API package 42 | SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) 43 | // AddToScheme is a common registration function for mapping packaged scoped group & version keys to a scheme 44 | AddToScheme = SchemeBuilder.AddToScheme 45 | ) 46 | 47 | // Adds the list of known types to the given scheme. 48 | func addKnownTypes(scheme *runtime.Scheme) error { 49 | scheme.AddKnownTypes(SchemeGroupVersion, 50 | &APIService{}, 51 | &APIServiceList{}, 52 | ) 53 | return nil 54 | } 55 | -------------------------------------------------------------------------------- /pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/fake/fake_apiservice.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package fake 20 | 21 | import ( 22 | gentype "k8s.io/client-go/gentype" 23 | v1beta1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1" 24 | apiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1" 25 | ) 26 | 27 | // fakeAPIServices implements APIServiceInterface 28 | type fakeAPIServices struct { 29 | *gentype.FakeClientWithList[*v1beta1.APIService, *v1beta1.APIServiceList] 30 | Fake *FakeApiregistrationV1beta1 31 | } 32 | 33 | func newFakeAPIServices(fake *FakeApiregistrationV1beta1) apiregistrationv1beta1.APIServiceInterface { 34 | return &fakeAPIServices{ 35 | gentype.NewFakeClientWithList[*v1beta1.APIService, *v1beta1.APIServiceList]( 36 | fake.Fake, 37 | "", 38 | v1beta1.SchemeGroupVersion.WithResource("apiservices"), 39 | v1beta1.SchemeGroupVersion.WithKind("APIService"), 40 | func() *v1beta1.APIService { return &v1beta1.APIService{} }, 41 | func() *v1beta1.APIServiceList { return &v1beta1.APIServiceList{} }, 42 | func(dst, src *v1beta1.APIServiceList) { dst.ListMeta = src.ListMeta }, 43 | func(list *v1beta1.APIServiceList) []*v1beta1.APIService { return gentype.ToPointerSlice(list.Items) }, 44 | func(list *v1beta1.APIServiceList, items []*v1beta1.APIService) { 45 | list.Items = gentype.FromPointerSlice(items) 46 | }, 47 | ), 48 | fake, 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /pkg/apis/apiregistration/v1/zz_generated.model_name.go: -------------------------------------------------------------------------------- 1 | //go:build !ignore_autogenerated 2 | // +build !ignore_autogenerated 3 | 4 | /* 5 | Copyright The Kubernetes Authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | // Code generated by openapi-gen. DO NOT EDIT. 21 | 22 | package v1 23 | 24 | // OpenAPIModelName returns the OpenAPI model name for this type. 25 | func (in APIService) OpenAPIModelName() string { 26 | return "io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIService" 27 | } 28 | 29 | // OpenAPIModelName returns the OpenAPI model name for this type. 30 | func (in APIServiceCondition) OpenAPIModelName() string { 31 | return "io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceCondition" 32 | } 33 | 34 | // OpenAPIModelName returns the OpenAPI model name for this type. 35 | func (in APIServiceList) OpenAPIModelName() string { 36 | return "io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceList" 37 | } 38 | 39 | // OpenAPIModelName returns the OpenAPI model name for this type. 40 | func (in APIServiceSpec) OpenAPIModelName() string { 41 | return "io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceSpec" 42 | } 43 | 44 | // OpenAPIModelName returns the OpenAPI model name for this type. 45 | func (in APIServiceStatus) OpenAPIModelName() string { 46 | return "io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.APIServiceStatus" 47 | } 48 | 49 | // OpenAPIModelName returns the OpenAPI model name for this type. 50 | func (in ServiceReference) OpenAPIModelName() string { 51 | return "io.k8s.kube-aggregator.pkg.apis.apiregistration.v1.ServiceReference" 52 | } 53 | -------------------------------------------------------------------------------- /pkg/apis/apiregistration/v1beta1/zz_generated.model_name.go: -------------------------------------------------------------------------------- 1 | //go:build !ignore_autogenerated 2 | // +build !ignore_autogenerated 3 | 4 | /* 5 | Copyright The Kubernetes Authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | // Code generated by openapi-gen. DO NOT EDIT. 21 | 22 | package v1beta1 23 | 24 | // OpenAPIModelName returns the OpenAPI model name for this type. 25 | func (in APIService) OpenAPIModelName() string { 26 | return "io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.APIService" 27 | } 28 | 29 | // OpenAPIModelName returns the OpenAPI model name for this type. 30 | func (in APIServiceCondition) OpenAPIModelName() string { 31 | return "io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.APIServiceCondition" 32 | } 33 | 34 | // OpenAPIModelName returns the OpenAPI model name for this type. 35 | func (in APIServiceList) OpenAPIModelName() string { 36 | return "io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.APIServiceList" 37 | } 38 | 39 | // OpenAPIModelName returns the OpenAPI model name for this type. 40 | func (in APIServiceSpec) OpenAPIModelName() string { 41 | return "io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.APIServiceSpec" 42 | } 43 | 44 | // OpenAPIModelName returns the OpenAPI model name for this type. 45 | func (in APIServiceStatus) OpenAPIModelName() string { 46 | return "io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.APIServiceStatus" 47 | } 48 | 49 | // OpenAPIModelName returns the OpenAPI model name for this type. 50 | func (in ServiceReference) OpenAPIModelName() string { 51 | return "io.k8s.kube-aggregator.pkg.apis.apiregistration.v1beta1.ServiceReference" 52 | } 53 | -------------------------------------------------------------------------------- /pkg/apis/openapi_models_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package apis 18 | 19 | import ( 20 | "reflect" 21 | "testing" 22 | 23 | "k8s.io/apimachinery/pkg/runtime" 24 | "k8s.io/kube-openapi/pkg/util" 25 | 26 | apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" 27 | apiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1" 28 | ) 29 | 30 | var groups = []runtime.SchemeBuilder{ 31 | apiregistrationv1.SchemeBuilder, 32 | apiregistrationv1beta1.SchemeBuilder, 33 | } 34 | 35 | func TestOpenAPIDefinitionNames(t *testing.T) { 36 | scheme := runtime.NewScheme() 37 | for _, builder := range groups { 38 | if err := builder.AddToScheme(scheme); err != nil { 39 | t.Fatalf("unexpected error adding to scheme: %v", err) 40 | } 41 | } 42 | 43 | kinds := scheme.AllKnownTypes() 44 | for gvk := range kinds { 45 | if gvk.Version == runtime.APIVersionInternal { 46 | continue 47 | } 48 | t.Run(gvk.String(), func(t *testing.T) { 49 | example, err := scheme.New(gvk) 50 | if err != nil { 51 | t.Fatalf("unexpected error creating example: %v", err) 52 | } 53 | 54 | namer, ok := example.(util.OpenAPIModelNamer) 55 | if !ok { 56 | t.Fatalf("type %v does not implement OpenAPICanonicalTypeName\n", gvk) 57 | } 58 | lookupName := namer.OpenAPIModelName() 59 | 60 | rtype := reflect.TypeOf(example).Elem() 61 | reflectName := util.ToRESTFriendlyName(rtype.PkgPath() + "." + rtype.Name()) 62 | 63 | if lookupName != reflectName { 64 | t.Errorf("expected %v, got %v", reflectName, lookupName) 65 | } 66 | }) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /pkg/client/informers/externalversions/apiregistration/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by informer-gen. DO NOT EDIT. 18 | 19 | package apiregistration 20 | 21 | import ( 22 | v1 "k8s.io/kube-aggregator/pkg/client/informers/externalversions/apiregistration/v1" 23 | v1beta1 "k8s.io/kube-aggregator/pkg/client/informers/externalversions/apiregistration/v1beta1" 24 | internalinterfaces "k8s.io/kube-aggregator/pkg/client/informers/externalversions/internalinterfaces" 25 | ) 26 | 27 | // Interface provides access to each of this group's versions. 28 | type Interface interface { 29 | // V1 provides access to shared informers for resources in V1. 30 | V1() v1.Interface 31 | // V1beta1 provides access to shared informers for resources in V1beta1. 32 | V1beta1() v1beta1.Interface 33 | } 34 | 35 | type group struct { 36 | factory internalinterfaces.SharedInformerFactory 37 | namespace string 38 | tweakListOptions internalinterfaces.TweakListOptionsFunc 39 | } 40 | 41 | // New returns a new Interface. 42 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { 43 | return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} 44 | } 45 | 46 | // V1 returns a new v1.Interface. 47 | func (g *group) V1() v1.Interface { 48 | return v1.New(g.factory, g.namespace, g.tweakListOptions) 49 | } 50 | 51 | // V1beta1 returns a new v1beta1.Interface. 52 | func (g *group) V1beta1() v1beta1.Interface { 53 | return v1beta1.New(g.factory, g.namespace, g.tweakListOptions) 54 | } 55 | -------------------------------------------------------------------------------- /pkg/registry/apiservice/rest/storage_apiservice.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package rest 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | "k8s.io/apiserver/pkg/registry/generic" 22 | "k8s.io/apiserver/pkg/registry/rest" 23 | genericapiserver "k8s.io/apiserver/pkg/server" 24 | serverstorage "k8s.io/apiserver/pkg/server/storage" 25 | 26 | "k8s.io/kube-aggregator/pkg/apis/apiregistration" 27 | v1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" 28 | aggregatorscheme "k8s.io/kube-aggregator/pkg/apiserver/scheme" 29 | apiservicestorage "k8s.io/kube-aggregator/pkg/registry/apiservice/etcd" 30 | ) 31 | 32 | // NewRESTStorage returns an APIGroupInfo object that will work against apiservice. 33 | func NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter, shouldServeBeta bool) genericapiserver.APIGroupInfo { 34 | apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo(apiregistration.GroupName, aggregatorscheme.Scheme, metav1.ParameterCodec, aggregatorscheme.Codecs) 35 | 36 | storage := map[string]rest.Storage{} 37 | 38 | if resource := "apiservices"; apiResourceConfigSource.ResourceEnabled(v1.SchemeGroupVersion.WithResource(resource)) { 39 | apiServiceREST := apiservicestorage.NewREST(aggregatorscheme.Scheme, restOptionsGetter) 40 | storage[resource] = apiServiceREST 41 | storage[resource+"/status"] = apiservicestorage.NewStatusREST(aggregatorscheme.Scheme, apiServiceREST) 42 | } 43 | 44 | if len(storage) > 0 { 45 | apiGroupInfo.VersionedResourcesStorageMap["v1"] = storage 46 | } 47 | 48 | return apiGroupInfo 49 | } 50 | -------------------------------------------------------------------------------- /hack/update-codegen.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright 2016 The Kubernetes Authors. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -o errexit 18 | set -o nounset 19 | set -o pipefail 20 | 21 | SCRIPT_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. 22 | CODEGEN_PKG=${CODEGEN_PKG:-$(cd "${SCRIPT_ROOT}"; ls -d -1 ./vendor/k8s.io/code-generator 2>/dev/null || echo ../code-generator)} 23 | 24 | source "${CODEGEN_PKG}/kube_codegen.sh" 25 | 26 | THIS_PKG="k8s.io/kube-aggregator" 27 | 28 | kube::codegen::gen_helpers \ 29 | --boilerplate "${SCRIPT_ROOT}/hack/boilerplate.go.txt" \ 30 | "${SCRIPT_ROOT}/pkg/apis" 31 | 32 | if [[ -n "${API_KNOWN_VIOLATIONS_DIR:-}" ]]; then 33 | report_filename="${API_KNOWN_VIOLATIONS_DIR}/aggregator_violation_exceptions.list" 34 | if [[ "${UPDATE_API_KNOWN_VIOLATIONS:-}" == "true" ]]; then 35 | update_report="--update-report" 36 | fi 37 | fi 38 | 39 | kube::codegen::gen_openapi \ 40 | --output-dir "${SCRIPT_ROOT}/pkg/generated/openapi" \ 41 | --output-pkg "${THIS_PKG}/pkg/generated/openapi" \ 42 | --report-filename "${report_filename:-"/dev/null"}" \ 43 | --output-model-name-file "zz_generated.model_name.go" \ 44 | ${update_report:+"${update_report}"} \ 45 | --boilerplate "${SCRIPT_ROOT}/hack/boilerplate.go.txt" \ 46 | "${SCRIPT_ROOT}/pkg/apis" 47 | 48 | kube::codegen::gen_client \ 49 | --with-watch \ 50 | --output-dir "${SCRIPT_ROOT}/pkg/client" \ 51 | --output-pkg "${THIS_PKG}/pkg/client" \ 52 | --clientset-name "clientset_generated" \ 53 | --versioned-name "clientset" \ 54 | --boilerplate "${SCRIPT_ROOT}/hack/boilerplate.go.txt" \ 55 | --prefers-protobuf \ 56 | "${SCRIPT_ROOT}/pkg/apis" 57 | -------------------------------------------------------------------------------- /pkg/client/clientset_generated/clientset/fake/register.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package fake 20 | 21 | import ( 22 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 23 | runtime "k8s.io/apimachinery/pkg/runtime" 24 | schema "k8s.io/apimachinery/pkg/runtime/schema" 25 | serializer "k8s.io/apimachinery/pkg/runtime/serializer" 26 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 27 | apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" 28 | apiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1" 29 | ) 30 | 31 | var scheme = runtime.NewScheme() 32 | var codecs = serializer.NewCodecFactory(scheme) 33 | 34 | var localSchemeBuilder = runtime.SchemeBuilder{ 35 | apiregistrationv1.AddToScheme, 36 | apiregistrationv1beta1.AddToScheme, 37 | } 38 | 39 | // AddToScheme adds all types of this clientset into the given scheme. This allows composition 40 | // of clientsets, like in: 41 | // 42 | // import ( 43 | // "k8s.io/client-go/kubernetes" 44 | // clientsetscheme "k8s.io/client-go/kubernetes/scheme" 45 | // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" 46 | // ) 47 | // 48 | // kclientset, _ := kubernetes.NewForConfig(c) 49 | // _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) 50 | // 51 | // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types 52 | // correctly. 53 | var AddToScheme = localSchemeBuilder.AddToScheme 54 | 55 | func init() { 56 | v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"}) 57 | utilruntime.Must(AddToScheme(scheme)) 58 | } 59 | -------------------------------------------------------------------------------- /pkg/client/clientset_generated/clientset/scheme/register.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package scheme 20 | 21 | import ( 22 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 23 | runtime "k8s.io/apimachinery/pkg/runtime" 24 | schema "k8s.io/apimachinery/pkg/runtime/schema" 25 | serializer "k8s.io/apimachinery/pkg/runtime/serializer" 26 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 27 | apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" 28 | apiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1" 29 | ) 30 | 31 | var Scheme = runtime.NewScheme() 32 | var Codecs = serializer.NewCodecFactory(Scheme) 33 | var ParameterCodec = runtime.NewParameterCodec(Scheme) 34 | var localSchemeBuilder = runtime.SchemeBuilder{ 35 | apiregistrationv1.AddToScheme, 36 | apiregistrationv1beta1.AddToScheme, 37 | } 38 | 39 | // AddToScheme adds all types of this clientset into the given scheme. This allows composition 40 | // of clientsets, like in: 41 | // 42 | // import ( 43 | // "k8s.io/client-go/kubernetes" 44 | // clientsetscheme "k8s.io/client-go/kubernetes/scheme" 45 | // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" 46 | // ) 47 | // 48 | // kclientset, _ := kubernetes.NewForConfig(c) 49 | // _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) 50 | // 51 | // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types 52 | // correctly. 53 | var AddToScheme = localSchemeBuilder.AddToScheme 54 | 55 | func init() { 56 | v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) 57 | utilruntime.Must(AddToScheme(Scheme)) 58 | } 59 | -------------------------------------------------------------------------------- /pkg/controllers/openapiv3/aggregator/downloader_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package aggregator 18 | 19 | import ( 20 | "encoding/json" 21 | "net/http" 22 | "testing" 23 | 24 | "github.com/stretchr/testify/assert" 25 | 26 | "k8s.io/kube-openapi/pkg/handler3" 27 | ) 28 | 29 | type handlerTest struct { 30 | etag string 31 | data []byte 32 | } 33 | 34 | var _ http.Handler = handlerTest{} 35 | 36 | func (h handlerTest) ServeHTTP(w http.ResponseWriter, r *http.Request) { 37 | // Create an APIService with a handler for one group/version 38 | if r.URL.Path == "/openapi/v3" { 39 | group := &handler3.OpenAPIV3Discovery{ 40 | Paths: map[string]handler3.OpenAPIV3DiscoveryGroupVersion{ 41 | "apis/group/version": { 42 | ServerRelativeURL: "/openapi/v3/apis/group/version?hash=" + h.etag, 43 | }, 44 | }, 45 | } 46 | 47 | j, _ := json.Marshal(group) 48 | w.Write(j) 49 | return 50 | } 51 | 52 | if r.URL.Path == "/openapi/v3/apis/group/version" { 53 | if len(h.etag) > 0 { 54 | w.Header().Add("Etag", h.etag) 55 | } 56 | ifNoneMatches := r.Header["If-None-Match"] 57 | for _, match := range ifNoneMatches { 58 | if match == h.etag { 59 | w.WriteHeader(http.StatusNotModified) 60 | return 61 | } 62 | } 63 | w.Write(h.data) 64 | } 65 | } 66 | 67 | func TestDownloadOpenAPISpec(t *testing.T) { 68 | s := Downloader{} 69 | 70 | groups, _, err := s.OpenAPIV3Root( 71 | handlerTest{data: []byte(""), etag: ""}) 72 | assert.NoError(t, err) 73 | if assert.NotNil(t, groups) { 74 | assert.Len(t, groups.Paths, 1) 75 | if assert.Contains(t, groups.Paths, "apis/group/version") { 76 | assert.NotEmpty(t, groups.Paths["apis/group/version"].ServerRelativeURL) 77 | } 78 | } 79 | 80 | } 81 | -------------------------------------------------------------------------------- /pkg/apis/apiregistration/v1/register.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | "k8s.io/apimachinery/pkg/runtime" 22 | "k8s.io/apimachinery/pkg/runtime/schema" 23 | ) 24 | 25 | // GroupName is the API group for apiregistration 26 | const GroupName = "apiregistration.k8s.io" 27 | 28 | // SchemeGroupVersion is group version used to register these objects 29 | var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1"} 30 | 31 | // Resource takes an unqualified resource and returns back a Group qualified GroupResource 32 | func Resource(resource string) schema.GroupResource { 33 | return SchemeGroupVersion.WithResource(resource).GroupResource() 34 | } 35 | 36 | var ( 37 | // SchemeBuilder is the scheme builder with scheme init functions to run for this API package 38 | // TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api. 39 | // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. 40 | SchemeBuilder runtime.SchemeBuilder 41 | localSchemeBuilder = &SchemeBuilder 42 | // AddToScheme is a common registration function for mapping packaged scoped group & version keys to a scheme 43 | AddToScheme = localSchemeBuilder.AddToScheme 44 | ) 45 | 46 | func init() { 47 | // We only register manually written functions here. The registration of the 48 | // generated functions takes place in the generated files. The separation 49 | // makes the code compile even when the generated files are missing. 50 | localSchemeBuilder.Register(addKnownTypes, addDefaultingFuncs) 51 | } 52 | 53 | // Adds the list of known types to the given scheme. 54 | func addKnownTypes(scheme *runtime.Scheme) error { 55 | scheme.AddKnownTypes(SchemeGroupVersion, 56 | &APIService{}, 57 | &APIServiceList{}, 58 | ) 59 | metav1.AddToGroupVersion(scheme, SchemeGroupVersion) 60 | return nil 61 | } 62 | -------------------------------------------------------------------------------- /pkg/apis/apiregistration/v1beta1/register.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1beta1 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | "k8s.io/apimachinery/pkg/runtime" 22 | "k8s.io/apimachinery/pkg/runtime/schema" 23 | ) 24 | 25 | // GroupName is the API group for apiregistration 26 | const GroupName = "apiregistration.k8s.io" 27 | 28 | // SchemeGroupVersion is group version used to register these objects 29 | var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1beta1"} 30 | 31 | // Resource takes an unqualified resource and returns back a Group qualified GroupResource 32 | func Resource(resource string) schema.GroupResource { 33 | return SchemeGroupVersion.WithResource(resource).GroupResource() 34 | } 35 | 36 | var ( 37 | // SchemeBuilder is the scheme builder with scheme init functions to run for this API package 38 | // TODO: move SchemeBuilder with zz_generated.deepcopy.go to k8s.io/api. 39 | // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes. 40 | SchemeBuilder runtime.SchemeBuilder 41 | localSchemeBuilder = &SchemeBuilder 42 | // AddToScheme is a common registration function for mapping packaged scoped group & version keys to a scheme 43 | AddToScheme = localSchemeBuilder.AddToScheme 44 | ) 45 | 46 | func init() { 47 | // We only register manually written functions here. The registration of the 48 | // generated functions takes place in the generated files. The separation 49 | // makes the code compile even when the generated files are missing. 50 | localSchemeBuilder.Register(addKnownTypes, addDefaultingFuncs) 51 | } 52 | 53 | // Adds the list of known types to the given scheme. 54 | func addKnownTypes(scheme *runtime.Scheme) error { 55 | scheme.AddKnownTypes(SchemeGroupVersion, 56 | &APIService{}, 57 | &APIServiceList{}, 58 | ) 59 | metav1.AddToGroupVersion(scheme, SchemeGroupVersion) 60 | return nil 61 | } 62 | -------------------------------------------------------------------------------- /pkg/controllers/openapi/aggregator/priority_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package aggregator 18 | 19 | import ( 20 | "reflect" 21 | "testing" 22 | 23 | apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" 24 | ) 25 | 26 | func newAPIServiceForTest(name, group string, minGroupPriority, versionPriority int32, svc *apiregistrationv1.ServiceReference) *apiregistrationv1.APIService { 27 | r := apiregistrationv1.APIService{} 28 | r.Spec.Group = group 29 | r.Spec.GroupPriorityMinimum = minGroupPriority 30 | r.Spec.VersionPriority = versionPriority 31 | r.Spec.Service = svc 32 | r.Name = name 33 | return &r 34 | } 35 | 36 | func assertSortedServices(t *testing.T, actual []*apiregistrationv1.APIService, expectedNames []string) { 37 | actualNames := []string{} 38 | for _, a := range actual { 39 | actualNames = append(actualNames, a.Name) 40 | } 41 | if !reflect.DeepEqual(actualNames, expectedNames) { 42 | t.Errorf("Expected %s got %s.", expectedNames, actualNames) 43 | } 44 | } 45 | 46 | func TestAPIServiceSort(t *testing.T) { 47 | list := []*apiregistrationv1.APIService{ 48 | newAPIServiceForTest("FirstService", "Group1", 10, 5, &apiregistrationv1.ServiceReference{}), 49 | newAPIServiceForTest("SecondService", "Group2", 15, 3, &apiregistrationv1.ServiceReference{}), 50 | newAPIServiceForTest("FirstServiceInternal", "Group1", 16, 3, &apiregistrationv1.ServiceReference{}), 51 | newAPIServiceForTest("ThirdService", "Group3", 15, 3, &apiregistrationv1.ServiceReference{}), 52 | newAPIServiceForTest("local_service_1", "Group4", 15, 1, nil), 53 | newAPIServiceForTest("local_service_3", "Group5", 15, 2, nil), 54 | newAPIServiceForTest("local_service_2", "Group6", 15, 3, nil), 55 | } 56 | sortByPriority(list) 57 | assertSortedServices(t, list, []string{"local_service_1", "local_service_2", "local_service_3", "FirstService", "FirstServiceInternal", "SecondService", "ThirdService"}) 58 | } 59 | -------------------------------------------------------------------------------- /pkg/client/informers/externalversions/generic.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by informer-gen. DO NOT EDIT. 18 | 19 | package externalversions 20 | 21 | import ( 22 | fmt "fmt" 23 | 24 | schema "k8s.io/apimachinery/pkg/runtime/schema" 25 | cache "k8s.io/client-go/tools/cache" 26 | v1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" 27 | v1beta1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1" 28 | ) 29 | 30 | // GenericInformer is type of SharedIndexInformer which will locate and delegate to other 31 | // sharedInformers based on type 32 | type GenericInformer interface { 33 | Informer() cache.SharedIndexInformer 34 | Lister() cache.GenericLister 35 | } 36 | 37 | type genericInformer struct { 38 | informer cache.SharedIndexInformer 39 | resource schema.GroupResource 40 | } 41 | 42 | // Informer returns the SharedIndexInformer. 43 | func (f *genericInformer) Informer() cache.SharedIndexInformer { 44 | return f.informer 45 | } 46 | 47 | // Lister returns the GenericLister. 48 | func (f *genericInformer) Lister() cache.GenericLister { 49 | return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource) 50 | } 51 | 52 | // ForResource gives generic access to a shared informer of the matching type 53 | // TODO extend this to unknown resources with a client pool 54 | func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { 55 | switch resource { 56 | // Group=apiregistration.k8s.io, Version=v1 57 | case v1.SchemeGroupVersion.WithResource("apiservices"): 58 | return &genericInformer{resource: resource.GroupResource(), informer: f.Apiregistration().V1().APIServices().Informer()}, nil 59 | 60 | // Group=apiregistration.k8s.io, Version=v1beta1 61 | case v1beta1.SchemeGroupVersion.WithResource("apiservices"): 62 | return &genericInformer{resource: resource.GroupResource(), informer: f.Apiregistration().V1beta1().APIServices().Informer()}, nil 63 | 64 | } 65 | 66 | return nil, fmt.Errorf("no informer found for %v", resource) 67 | } 68 | -------------------------------------------------------------------------------- /pkg/controllers/openapiv3/aggregator/downloader.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package aggregator 18 | 19 | import ( 20 | "encoding/json" 21 | "fmt" 22 | "net/http" 23 | 24 | "k8s.io/apiserver/pkg/authentication/user" 25 | "k8s.io/apiserver/pkg/endpoints/request" 26 | "k8s.io/apiserver/pkg/util/responsewriter" 27 | "k8s.io/kube-openapi/pkg/handler3" 28 | ) 29 | 30 | type NotFoundError struct { 31 | } 32 | 33 | func (e *NotFoundError) Error() string { 34 | return "" 35 | } 36 | 37 | // Downloader is the OpenAPI downloader type. It will try to download spec from /openapi/v3 and /openap/v3// endpoints. 38 | type Downloader struct { 39 | } 40 | 41 | // NewDownloader creates a new OpenAPI Downloader. 42 | func NewDownloader() Downloader { 43 | return Downloader{} 44 | } 45 | 46 | func (s *Downloader) handlerWithUser(handler http.Handler, info user.Info) http.Handler { 47 | return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 48 | req = req.WithContext(request.WithUser(req.Context(), info)) 49 | handler.ServeHTTP(w, req) 50 | }) 51 | } 52 | 53 | // OpenAPIV3Root downloads the OpenAPI V3 root document from an APIService 54 | func (s *Downloader) OpenAPIV3Root(handler http.Handler) (*handler3.OpenAPIV3Discovery, int, error) { 55 | handler = s.handlerWithUser(handler, &user.DefaultInfo{Name: aggregatorUser}) 56 | handler = http.TimeoutHandler(handler, specDownloadTimeout, "request timed out") 57 | 58 | req, err := http.NewRequest("GET", "/openapi/v3", nil) 59 | if err != nil { 60 | return nil, 0, err 61 | } 62 | writer := responsewriter.NewInMemoryResponseWriter() 63 | handler.ServeHTTP(writer, req) 64 | 65 | switch writer.RespCode() { 66 | case http.StatusNotFound: 67 | return nil, writer.RespCode(), nil 68 | case http.StatusOK: 69 | groups := handler3.OpenAPIV3Discovery{} 70 | if err := json.Unmarshal(writer.Data(), &groups); err != nil { 71 | return nil, writer.RespCode(), err 72 | } 73 | return &groups, writer.RespCode(), nil 74 | } 75 | return nil, writer.RespCode(), fmt.Errorf("Error, could not get list of group versions for APIService") 76 | } 77 | -------------------------------------------------------------------------------- /hack/godep-deps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2017 The Kubernetes Authors. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | 18 | # overall flow 19 | # 1. make a clean gopath 20 | # 2. godep restore based on k8s.io/kuberentes provided manifest 21 | # 3. go get anything unlisted. This handles deps from k8s.io/* 22 | # 4. remove old vendoring data 23 | # 5. vendor packages we need 24 | # 6. remove anything vendored from k8s.io/* from vendor, but not manifest. 25 | # This allows go get to work and still be able to flatten dependencies. 26 | # 6. copy new vendored packages and save them 27 | 28 | set -o errexit 29 | set -o nounset 30 | set -o pipefail 31 | 32 | goPath=$(mktemp -d "${TMPDIR:-/tmp/}$(basename 0).XXXXXXXXXXXX") 33 | echo ${goPath} 34 | 35 | export GOPATH=${goPath} 36 | 37 | mkdir -p ${goPath}/src/k8s.io/kube-aggregator 38 | cp -R . ${goPath}/src/k8s.io/kube-aggregator 39 | 40 | pushd ${goPath}/src/k8s.io/kube-aggregator 41 | rm -rf vendor || true 42 | 43 | # restore what we have in our new manifest that we've sync 44 | godep restore 45 | 46 | # we have to some crazy schenanigans for client-go until it can keep its syncs up to date 47 | # we have to restore its old/bad deps 48 | go get -d k8s.io/client-go/... || true 49 | pushd ${goPath}/src/k8s.io/client-go 50 | godep restore 51 | rm -rf ${goPath}/src/k8s.io/apimachinery 52 | rm -rf ${goPath}/src/k8s.io/apiserver 53 | popd 54 | 55 | # the manifest doesn't include any levels of k8s.io dependencies so load them using the go get 56 | # assume you sync all the repos at the same time, the leves you get will be correct 57 | go get -d ./... || true 58 | 59 | 60 | # save the new levels of dependencies 61 | rm -rf vendor || true 62 | rm -rf Godeps || true 63 | godep save ./... 64 | 65 | # remove the vendored k8s.io/* go files 66 | rm -rf vendor/k8s.io 67 | popd 68 | 69 | # remove the vendor dir we have and move the one we just made 70 | rm -rf vendor || true 71 | rm -rf Godeps || true 72 | git rm -rf vendor || true 73 | git rm -rf Godeps || true 74 | mv ${goPath}/src/k8s.io/kube-aggregator/vendor . 75 | mv ${goPath}/src/k8s.io/kube-aggregator/Godeps . 76 | git add vendor 77 | git add Godeps 78 | git commit -m "sync: resync vendor folder" 79 | 80 | -------------------------------------------------------------------------------- /pkg/controllers/openapi/aggregator/priority.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package aggregator 18 | 19 | import ( 20 | "sort" 21 | 22 | apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" 23 | ) 24 | 25 | // byPriority can be used in sort.Sort to sort specs with their priorities. 26 | type byPriority struct { 27 | apiServices []*apiregistrationv1.APIService 28 | groupPriorities map[string]int32 29 | } 30 | 31 | func (a byPriority) Len() int { return len(a.apiServices) } 32 | func (a byPriority) Swap(i, j int) { 33 | a.apiServices[i], a.apiServices[j] = a.apiServices[j], a.apiServices[i] 34 | } 35 | func (a byPriority) Less(i, j int) bool { 36 | // All local specs will come first 37 | if a.apiServices[i].Spec.Service == nil && a.apiServices[j].Spec.Service != nil { 38 | return true 39 | } 40 | if a.apiServices[i].Spec.Service != nil && a.apiServices[j].Spec.Service == nil { 41 | return false 42 | } 43 | // WARNING: This will result in not following priorities for local APIServices. 44 | if a.apiServices[i].Spec.Service == nil { 45 | // Sort local specs with their name. This is the order in the delegation chain (aggregator first). 46 | return a.apiServices[i].Name < a.apiServices[j].Name 47 | } 48 | var iPriority, jPriority int32 49 | if a.apiServices[i].Spec.Group == a.apiServices[j].Spec.Group { 50 | iPriority = a.apiServices[i].Spec.VersionPriority 51 | jPriority = a.apiServices[i].Spec.VersionPriority 52 | } else { 53 | iPriority = a.groupPriorities[a.apiServices[i].Spec.Group] 54 | jPriority = a.groupPriorities[a.apiServices[j].Spec.Group] 55 | } 56 | if iPriority != jPriority { 57 | // Sort by priority, higher first 58 | return iPriority > jPriority 59 | } 60 | // Sort by service name. 61 | return a.apiServices[i].Name < a.apiServices[j].Name 62 | } 63 | 64 | func sortByPriority(apiServices []*apiregistrationv1.APIService) { 65 | b := byPriority{ 66 | apiServices: apiServices, 67 | groupPriorities: map[string]int32{}, 68 | } 69 | for _, apiService := range apiServices { 70 | if apiService.Spec.Service == nil { 71 | continue 72 | } 73 | if pr, found := b.groupPriorities[apiService.Spec.Group]; !found || apiService.Spec.GroupPriorityMinimum > pr { 74 | b.groupPriorities[apiService.Spec.Group] = apiService.Spec.GroupPriorityMinimum 75 | } 76 | } 77 | sort.Sort(b) 78 | } 79 | -------------------------------------------------------------------------------- /artifacts/hostpath-pods/insecure-etcd-pod.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: kube-aggregator 5 | namespace: kube-public 6 | spec: 7 | hostNetwork: true 8 | containers: 9 | - name: kube-aggregator 10 | image: kube-aggregator 11 | imagePullPolicy: IfNotPresent 12 | args: 13 | - "/usr/local/bin/kube-aggregator" 14 | - "--secure-port=9443" 15 | - "--kubeconfig=/var/run/auth-client/kube-aggregator.kubeconfig" 16 | - "--authentication-kubeconfig=/var/run/auth-client/kube-aggregator.kubeconfig" 17 | - "--authorization-kubeconfig=/var/run/auth-client/kube-aggregator.kubeconfig" 18 | - "--proxy-client-cert-file=/var/run/auth-proxy-client/client-auth-proxy.crt" 19 | - "--proxy-client-key-file=/var/run/auth-proxy-client/client-auth-proxy.key" 20 | - "--tls-cert-file=/var/run/serving-cert/serving-kube-aggregator.crt" 21 | - "--tls-private-key-file=/var/run/serving-cert/serving-kube-aggregator.key" 22 | - "--client-ca-file=/var/run/client-ca/client-ca.crt" 23 | - "--requestheader-username-headers=X-Remote-User" 24 | - "--requestheader-group-headers=X-Remote-Group" 25 | - "--requestheader-extra-headers-prefix=X-Remote-Extra-" 26 | - "--requestheader-client-ca-file=/var/run/request-header-ca/request-header-ca.crt" 27 | - "--etcd-servers=http://127.0.0.1:2379" 28 | ports: 29 | - containerPort: 9443 30 | hostPort: 9443 31 | volumeMounts: 32 | - mountPath: /var/run/request-header-ca 33 | name: volume-request-header-ca 34 | readOnly: true 35 | - mountPath: /var/run/client-ca 36 | name: volume-client-ca 37 | readOnly: true 38 | - mountPath: /var/run/auth-proxy-client 39 | name: volume-auth-proxy-client 40 | readOnly: true 41 | - mountPath: /var/run/etcd-client-cert 42 | name: volume-etcd-client-cert 43 | readOnly: true 44 | - mountPath: /var/run/serving-ca 45 | name: volume-serving-ca 46 | readOnly: true 47 | - mountPath: /var/run/serving-cert 48 | name: volume-serving-cert 49 | readOnly: true 50 | - mountPath: /var/run/etcd-ca 51 | name: volume-etcd-ca 52 | readOnly: true 53 | - mountPath: /var/run/auth-client 54 | name: volume-auth-client 55 | readOnly: true 56 | volumes: 57 | - name: volume-request-header-ca 58 | hostPath: 59 | path: /var/run/kubernetes/ 60 | - name: volume-client-ca 61 | hostPath: 62 | path: /var/run/kubernetes/ 63 | - name: volume-auth-proxy-client 64 | hostPath: 65 | path: /var/run/kubernetes/ 66 | - name: volume-etcd-client-cert 67 | hostPath: 68 | path: /var/run/kubernetes/ 69 | - name: volume-serving-cert 70 | hostPath: 71 | path: /var/run/kubernetes/ 72 | - name: volume-serving-ca 73 | hostPath: 74 | path: /var/run/kubernetes/ 75 | - name: volume-etcd-ca 76 | hostPath: 77 | path: /var/run/kubernetes/ 78 | - name: volume-auth-client 79 | hostPath: 80 | path: /var/run/kubernetes/ 81 | -------------------------------------------------------------------------------- /pkg/apiserver/resolvers.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package apiserver 18 | 19 | import ( 20 | "net/url" 21 | 22 | "k8s.io/apiserver/pkg/util/proxy" 23 | listersv1 "k8s.io/client-go/listers/core/v1" 24 | ) 25 | 26 | // A ServiceResolver knows how to get a URL given a service. 27 | type ServiceResolver interface { 28 | ResolveEndpoint(namespace, name string, port int32) (*url.URL, error) 29 | } 30 | 31 | // NewEndpointServiceResolver returns a ServiceResolver that chooses one of the 32 | // service's endpoints. 33 | func NewEndpointServiceResolver(services listersv1.ServiceLister, endpointSliceGetter proxy.EndpointSliceGetter) ServiceResolver { 34 | return &aggregatorEndpointRouting{ 35 | services: services, 36 | endpointSliceGetter: endpointSliceGetter, 37 | } 38 | } 39 | 40 | type aggregatorEndpointRouting struct { 41 | services listersv1.ServiceLister 42 | endpointSliceGetter proxy.EndpointSliceGetter 43 | } 44 | 45 | func (r *aggregatorEndpointRouting) ResolveEndpoint(namespace, name string, port int32) (*url.URL, error) { 46 | return proxy.ResolveEndpoint(r.services, r.endpointSliceGetter, namespace, name, port) 47 | } 48 | 49 | // NewClusterIPServiceResolver returns a ServiceResolver that directly calls the 50 | // service's cluster IP. 51 | func NewClusterIPServiceResolver(services listersv1.ServiceLister) ServiceResolver { 52 | return &aggregatorClusterRouting{ 53 | services: services, 54 | } 55 | } 56 | 57 | type aggregatorClusterRouting struct { 58 | services listersv1.ServiceLister 59 | } 60 | 61 | func (r *aggregatorClusterRouting) ResolveEndpoint(namespace, name string, port int32) (*url.URL, error) { 62 | return proxy.ResolveCluster(r.services, namespace, name, port) 63 | } 64 | 65 | // NewLoopbackServiceResolver returns a ServiceResolver that routes 66 | // the kubernetes/default service with port 443 to loopback. 67 | func NewLoopbackServiceResolver(delegate ServiceResolver, host *url.URL) ServiceResolver { 68 | return &loopbackResolver{ 69 | delegate: delegate, 70 | host: host, 71 | } 72 | } 73 | 74 | type loopbackResolver struct { 75 | delegate ServiceResolver 76 | host *url.URL 77 | } 78 | 79 | func (r *loopbackResolver) ResolveEndpoint(namespace, name string, port int32) (*url.URL, error) { 80 | if namespace == "default" && name == "kubernetes" && port == 443 { 81 | return r.host, nil 82 | } 83 | return r.delegate.ResolveEndpoint(namespace, name, port) 84 | } 85 | -------------------------------------------------------------------------------- /artifacts/self-contained/kubernetes-discover-pod.yaml: -------------------------------------------------------------------------------- 1 | kind: ReplicationController 2 | apiVersion: v1 3 | metadata: 4 | name: kube-aggregator 5 | labels: 6 | kube-aggregator: "true" 7 | spec: 8 | replicas: 1 9 | selector: 10 | kube-aggregator: "true" 11 | template: 12 | metadata: 13 | labels: 14 | kube-aggregator: "true" 15 | spec: 16 | containers: 17 | - name: kube-aggregator 18 | image: kube-aggregator:latest 19 | imagePullPolicy: Never 20 | livenessProbe: 21 | failureThreshold: 3 22 | httpGet: 23 | path: /version 24 | port: 443 25 | scheme: HTTPS 26 | periodSeconds: 10 27 | successThreshold: 1 28 | timeoutSeconds: 1 29 | readinessProbe: 30 | failureThreshold: 3 31 | httpGet: 32 | path: /version 33 | port: 443 34 | scheme: HTTPS 35 | periodSeconds: 10 36 | successThreshold: 1 37 | timeoutSeconds: 1 38 | args: 39 | - "--proxy-client-cert-file=/var/run/auth-proxy-client/tls.crt" 40 | - "--proxy-client-key-file=/var/run/auth-proxy-client/tls.key" 41 | - "--tls-cert-file=/var/run/serving-cert/tls.crt" 42 | - "--tls-private-key-file=/var/run/serving-cert/tls.key" 43 | - "--etcd-servers=https://etcd.kube-public.svc:4001" 44 | - "--etcd-certfile=/var/run/etcd-client-cert/tls.crt" 45 | - "--etcd-keyfile=/var/run/etcd-client-cert/tls.key" 46 | - "--etcd-cafile=/var/run/etcd-ca/ca.crt" 47 | ports: 48 | - containerPort: 443 49 | volumeMounts: 50 | - mountPath: /var/run/request-header-ca 51 | name: volume-request-header-ca 52 | - mountPath: /var/run/client-ca 53 | name: volume-client-ca 54 | - mountPath: /var/run/auth-proxy-client 55 | name: volume-auth-proxy-client 56 | - mountPath: /var/run/etcd-client-cert 57 | name: volume-etcd-client-cert 58 | - mountPath: /var/run/serving-ca 59 | name: volume-serving-ca 60 | - mountPath: /var/run/serving-cert 61 | name: volume-serving-cert 62 | - mountPath: /var/run/etcd-ca 63 | name: volume-etcd-ca 64 | serviceAccountName: kube-aggregator 65 | volumes: 66 | - configMap: 67 | defaultMode: 420 68 | name: request-header-ca 69 | name: volume-request-header-ca 70 | - configMap: 71 | defaultMode: 420 72 | name: client-ca 73 | name: volume-client-ca 74 | - name: volume-auth-proxy-client 75 | secret: 76 | defaultMode: 420 77 | secretName: auth-proxy-client 78 | - name: volume-etcd-client-cert 79 | secret: 80 | defaultMode: 420 81 | secretName: kube-aggregator-etcd 82 | - name: volume-serving-cert 83 | secret: 84 | defaultMode: 420 85 | secretName: serving-kube-aggregator 86 | - configMap: 87 | defaultMode: 420 88 | name: kube-aggregator-ca 89 | name: volume-serving-ca 90 | - configMap: 91 | defaultMode: 420 92 | name: etcd-ca 93 | name: volume-etcd-ca 94 | -------------------------------------------------------------------------------- /hack/sync-from-kubernetes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2017 The Kubernetes Authors. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | 18 | # overall flow 19 | # 1. fetch the current level of k8s.io/kubernetes 20 | # 2. check out the k8s.io/kubernetes HEAD into a separate branch 21 | # 3. rewrite the history on that branch to *only* include staging/src/k8s.io/kube-aggregator 22 | # 4. locate all commits between the last time we sync'ed and now 23 | # 5. switch back to the starting branch 24 | # 6. for each commit, cherry-pick it (which will keep authorship) into current branch 25 | # 7. update metadata files indicating which commits we've sync'ed to 26 | 27 | set -e 28 | 29 | ROOT=$(dirname "${BASH_SOURCE}")/.. 30 | dir=$(mktemp -d "${TMPDIR:-/tmp/}$(basename 0).XXXXXXXXXXXX") 31 | 32 | git remote add upstream-kube git@github.com:kubernetes/kubernetes.git || true 33 | git fetch upstream-kube 34 | 35 | currBranch=$(git rev-parse --abbrev-ref HEAD) 36 | previousKubeSHA=$(cat kubernetes-sha) 37 | previousBranchSHA=$(cat filter-branch-sha) 38 | 39 | git branch -D kube-sync || true 40 | git checkout upstream-kube/master -b kube-sync 41 | git reset --hard upstream-kube/master 42 | newKubeSHA=$(git log --oneline --format='%H' kube-sync -1) 43 | 44 | # this command rewrite git history to *only* include staging/src/k8s.io/kube-aggregator 45 | git filter-branch -f --subdirectory-filter staging/src/k8s.io/kube-aggregator HEAD 46 | 47 | newBranchSHA=$(git log --oneline --format='%H' kube-sync -1) 48 | git log --no-merges --format='%H' --reverse ${previousBranchSHA}..HEAD > ${dir}/commits 49 | 50 | git checkout ${currBranch} 51 | 52 | # we must reset Godeps.json to what it looked like BEFORE the last vendor sync so that any 53 | # new Godep.json changes from k8s.io/kubernetes will apply cleanly. Since its always auto-generated 54 | # it doesn't matter that we're removing it 55 | lastResyncCommit=$(git rev-list -n 1 --grep "sync: resync vendor folder" HEAD) 56 | cleanGodepJsonCommit=$(git rev-list -n 1 ${lastResyncCommit}^) 57 | git checkout ${cleanGodepJsonCommit} Godeps/Godeps.json 58 | git commit -m "sync: reset Godeps.json" -- Godeps/Godeps.json 59 | 60 | while read commitSHA; do 61 | echo "working ${commitSHA}" 62 | git cherry-pick ${commitSHA} 63 | done <${dir}/commits 64 | 65 | # update the vendored godeps 66 | ${ROOT}/hack/godep-deps.sh 67 | 68 | # track the k8s.io/kubernetes commit SHA so we can always determine which level of kube this repo matches 69 | # track the filtered branch commit SHA so that we can determine which commits need to be picked 70 | echo ${newKubeSHA} > kubernetes-sha 71 | echo ${newBranchSHA} > filter-branch-sha 72 | git commit -m "sync(k8s.io/kubernetes): ${newKubeSHA}" -- kubernetes-sha filter-branch-sha 73 | -------------------------------------------------------------------------------- /pkg/client/clientset_generated/clientset/typed/apiregistration/v1/apiservice.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package v1 20 | 21 | import ( 22 | context "context" 23 | 24 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 | types "k8s.io/apimachinery/pkg/types" 26 | watch "k8s.io/apimachinery/pkg/watch" 27 | gentype "k8s.io/client-go/gentype" 28 | apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" 29 | scheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" 30 | ) 31 | 32 | // APIServicesGetter has a method to return a APIServiceInterface. 33 | // A group's client should implement this interface. 34 | type APIServicesGetter interface { 35 | APIServices() APIServiceInterface 36 | } 37 | 38 | // APIServiceInterface has methods to work with APIService resources. 39 | type APIServiceInterface interface { 40 | Create(ctx context.Context, aPIService *apiregistrationv1.APIService, opts metav1.CreateOptions) (*apiregistrationv1.APIService, error) 41 | Update(ctx context.Context, aPIService *apiregistrationv1.APIService, opts metav1.UpdateOptions) (*apiregistrationv1.APIService, error) 42 | // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). 43 | UpdateStatus(ctx context.Context, aPIService *apiregistrationv1.APIService, opts metav1.UpdateOptions) (*apiregistrationv1.APIService, error) 44 | Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error 45 | DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error 46 | Get(ctx context.Context, name string, opts metav1.GetOptions) (*apiregistrationv1.APIService, error) 47 | List(ctx context.Context, opts metav1.ListOptions) (*apiregistrationv1.APIServiceList, error) 48 | Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) 49 | Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (result *apiregistrationv1.APIService, err error) 50 | APIServiceExpansion 51 | } 52 | 53 | // aPIServices implements APIServiceInterface 54 | type aPIServices struct { 55 | *gentype.ClientWithList[*apiregistrationv1.APIService, *apiregistrationv1.APIServiceList] 56 | } 57 | 58 | // newAPIServices returns a APIServices 59 | func newAPIServices(c *ApiregistrationV1Client) *aPIServices { 60 | return &aPIServices{ 61 | gentype.NewClientWithList[*apiregistrationv1.APIService, *apiregistrationv1.APIServiceList]( 62 | "apiservices", 63 | c.RESTClient(), 64 | scheme.ParameterCodec, 65 | "", 66 | func() *apiregistrationv1.APIService { return &apiregistrationv1.APIService{} }, 67 | func() *apiregistrationv1.APIServiceList { return &apiregistrationv1.APIServiceList{} }, 68 | gentype.PrefersProtobuf[*apiregistrationv1.APIService](), 69 | ), 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/apiservice.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package v1beta1 20 | 21 | import ( 22 | context "context" 23 | 24 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 | types "k8s.io/apimachinery/pkg/types" 26 | watch "k8s.io/apimachinery/pkg/watch" 27 | gentype "k8s.io/client-go/gentype" 28 | apiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1" 29 | scheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" 30 | ) 31 | 32 | // APIServicesGetter has a method to return a APIServiceInterface. 33 | // A group's client should implement this interface. 34 | type APIServicesGetter interface { 35 | APIServices() APIServiceInterface 36 | } 37 | 38 | // APIServiceInterface has methods to work with APIService resources. 39 | type APIServiceInterface interface { 40 | Create(ctx context.Context, aPIService *apiregistrationv1beta1.APIService, opts v1.CreateOptions) (*apiregistrationv1beta1.APIService, error) 41 | Update(ctx context.Context, aPIService *apiregistrationv1beta1.APIService, opts v1.UpdateOptions) (*apiregistrationv1beta1.APIService, error) 42 | // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). 43 | UpdateStatus(ctx context.Context, aPIService *apiregistrationv1beta1.APIService, opts v1.UpdateOptions) (*apiregistrationv1beta1.APIService, error) 44 | Delete(ctx context.Context, name string, opts v1.DeleteOptions) error 45 | DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error 46 | Get(ctx context.Context, name string, opts v1.GetOptions) (*apiregistrationv1beta1.APIService, error) 47 | List(ctx context.Context, opts v1.ListOptions) (*apiregistrationv1beta1.APIServiceList, error) 48 | Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) 49 | Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *apiregistrationv1beta1.APIService, err error) 50 | APIServiceExpansion 51 | } 52 | 53 | // aPIServices implements APIServiceInterface 54 | type aPIServices struct { 55 | *gentype.ClientWithList[*apiregistrationv1beta1.APIService, *apiregistrationv1beta1.APIServiceList] 56 | } 57 | 58 | // newAPIServices returns a APIServices 59 | func newAPIServices(c *ApiregistrationV1beta1Client) *aPIServices { 60 | return &aPIServices{ 61 | gentype.NewClientWithList[*apiregistrationv1beta1.APIService, *apiregistrationv1beta1.APIServiceList]( 62 | "apiservices", 63 | c.RESTClient(), 64 | scheme.ParameterCodec, 65 | "", 66 | func() *apiregistrationv1beta1.APIService { return &apiregistrationv1beta1.APIService{} }, 67 | func() *apiregistrationv1beta1.APIServiceList { return &apiregistrationv1beta1.APIServiceList{} }, 68 | gentype.PrefersProtobuf[*apiregistrationv1beta1.APIService](), 69 | ), 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /pkg/client/clientset_generated/clientset/typed/apiregistration/v1/apiregistration_client.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package v1 20 | 21 | import ( 22 | http "net/http" 23 | 24 | rest "k8s.io/client-go/rest" 25 | apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" 26 | scheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" 27 | ) 28 | 29 | type ApiregistrationV1Interface interface { 30 | RESTClient() rest.Interface 31 | APIServicesGetter 32 | } 33 | 34 | // ApiregistrationV1Client is used to interact with features provided by the apiregistration.k8s.io group. 35 | type ApiregistrationV1Client struct { 36 | restClient rest.Interface 37 | } 38 | 39 | func (c *ApiregistrationV1Client) APIServices() APIServiceInterface { 40 | return newAPIServices(c) 41 | } 42 | 43 | // NewForConfig creates a new ApiregistrationV1Client for the given config. 44 | // NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), 45 | // where httpClient was generated with rest.HTTPClientFor(c). 46 | func NewForConfig(c *rest.Config) (*ApiregistrationV1Client, error) { 47 | config := *c 48 | setConfigDefaults(&config) 49 | httpClient, err := rest.HTTPClientFor(&config) 50 | if err != nil { 51 | return nil, err 52 | } 53 | return NewForConfigAndClient(&config, httpClient) 54 | } 55 | 56 | // NewForConfigAndClient creates a new ApiregistrationV1Client for the given config and http client. 57 | // Note the http client provided takes precedence over the configured transport values. 58 | func NewForConfigAndClient(c *rest.Config, h *http.Client) (*ApiregistrationV1Client, error) { 59 | config := *c 60 | setConfigDefaults(&config) 61 | client, err := rest.RESTClientForConfigAndClient(&config, h) 62 | if err != nil { 63 | return nil, err 64 | } 65 | return &ApiregistrationV1Client{client}, nil 66 | } 67 | 68 | // NewForConfigOrDie creates a new ApiregistrationV1Client for the given config and 69 | // panics if there is an error in the config. 70 | func NewForConfigOrDie(c *rest.Config) *ApiregistrationV1Client { 71 | client, err := NewForConfig(c) 72 | if err != nil { 73 | panic(err) 74 | } 75 | return client 76 | } 77 | 78 | // New creates a new ApiregistrationV1Client for the given RESTClient. 79 | func New(c rest.Interface) *ApiregistrationV1Client { 80 | return &ApiregistrationV1Client{c} 81 | } 82 | 83 | func setConfigDefaults(config *rest.Config) { 84 | gv := apiregistrationv1.SchemeGroupVersion 85 | config.GroupVersion = &gv 86 | config.APIPath = "/apis" 87 | config.NegotiatedSerializer = rest.CodecFactoryForGeneratedClient(scheme.Scheme, scheme.Codecs).WithoutConversion() 88 | 89 | if config.UserAgent == "" { 90 | config.UserAgent = rest.DefaultKubernetesUserAgent() 91 | } 92 | } 93 | 94 | // RESTClient returns a RESTClient that is used to communicate 95 | // with API server by this client implementation. 96 | func (c *ApiregistrationV1Client) RESTClient() rest.Interface { 97 | if c == nil { 98 | return nil 99 | } 100 | return c.restClient 101 | } 102 | -------------------------------------------------------------------------------- /pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/apiregistration_client.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package v1beta1 20 | 21 | import ( 22 | http "net/http" 23 | 24 | rest "k8s.io/client-go/rest" 25 | apiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1" 26 | scheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" 27 | ) 28 | 29 | type ApiregistrationV1beta1Interface interface { 30 | RESTClient() rest.Interface 31 | APIServicesGetter 32 | } 33 | 34 | // ApiregistrationV1beta1Client is used to interact with features provided by the apiregistration.k8s.io group. 35 | type ApiregistrationV1beta1Client struct { 36 | restClient rest.Interface 37 | } 38 | 39 | func (c *ApiregistrationV1beta1Client) APIServices() APIServiceInterface { 40 | return newAPIServices(c) 41 | } 42 | 43 | // NewForConfig creates a new ApiregistrationV1beta1Client for the given config. 44 | // NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), 45 | // where httpClient was generated with rest.HTTPClientFor(c). 46 | func NewForConfig(c *rest.Config) (*ApiregistrationV1beta1Client, error) { 47 | config := *c 48 | setConfigDefaults(&config) 49 | httpClient, err := rest.HTTPClientFor(&config) 50 | if err != nil { 51 | return nil, err 52 | } 53 | return NewForConfigAndClient(&config, httpClient) 54 | } 55 | 56 | // NewForConfigAndClient creates a new ApiregistrationV1beta1Client for the given config and http client. 57 | // Note the http client provided takes precedence over the configured transport values. 58 | func NewForConfigAndClient(c *rest.Config, h *http.Client) (*ApiregistrationV1beta1Client, error) { 59 | config := *c 60 | setConfigDefaults(&config) 61 | client, err := rest.RESTClientForConfigAndClient(&config, h) 62 | if err != nil { 63 | return nil, err 64 | } 65 | return &ApiregistrationV1beta1Client{client}, nil 66 | } 67 | 68 | // NewForConfigOrDie creates a new ApiregistrationV1beta1Client for the given config and 69 | // panics if there is an error in the config. 70 | func NewForConfigOrDie(c *rest.Config) *ApiregistrationV1beta1Client { 71 | client, err := NewForConfig(c) 72 | if err != nil { 73 | panic(err) 74 | } 75 | return client 76 | } 77 | 78 | // New creates a new ApiregistrationV1beta1Client for the given RESTClient. 79 | func New(c rest.Interface) *ApiregistrationV1beta1Client { 80 | return &ApiregistrationV1beta1Client{c} 81 | } 82 | 83 | func setConfigDefaults(config *rest.Config) { 84 | gv := apiregistrationv1beta1.SchemeGroupVersion 85 | config.GroupVersion = &gv 86 | config.APIPath = "/apis" 87 | config.NegotiatedSerializer = rest.CodecFactoryForGeneratedClient(scheme.Scheme, scheme.Codecs).WithoutConversion() 88 | 89 | if config.UserAgent == "" { 90 | config.UserAgent = rest.DefaultKubernetesUserAgent() 91 | } 92 | } 93 | 94 | // RESTClient returns a RESTClient that is used to communicate 95 | // with API server by this client implementation. 96 | func (c *ApiregistrationV1beta1Client) RESTClient() rest.Interface { 97 | if c == nil { 98 | return nil 99 | } 100 | return c.restClient 101 | } 102 | -------------------------------------------------------------------------------- /hack/register-all-apis-from.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright 2017 The Kubernetes Authors. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | set -o errexit 18 | set -o nounset 19 | set -o pipefail 20 | 21 | 22 | if LANG=C sed --help 2>&1 | grep -q GNU; then 23 | SED="sed" 24 | elif which gsed &>/dev/null; then 25 | SED="gsed" 26 | else 27 | echo "Failed to find GNU sed as sed or gsed. If you are on Mac: brew install gnu-sed." >&2 28 | exit 1 29 | fi 30 | 31 | dir=$(mktemp -d "${TMPDIR:-/tmp/}$(basename 0).XXXXXXXXXXXX") 32 | # Register function to be called on EXIT to remove generated binary. 33 | function cleanup { 34 | rm -rf "${dir}" 35 | } 36 | trap cleanup EXIT 37 | 38 | 39 | scriptDir=$(dirname "${BASH_SOURCE[0]}") 40 | 41 | # this uses discovery from a kube-like API server to register ALL the API versions that server provides 42 | # first argument is reference to kube-config file that points the API server you're adding from 43 | # second argument is the service namespace 44 | # third argument is the service name 45 | # fourth argument is reference to kube-config file that points to the aggregator you're using 46 | 47 | FROM_KUBECONFIG=${1} 48 | SERVICE_NAMESPACE=${2} 49 | SERVICE_NAME=${3} 50 | AGG_KUBECONFIG=${4} 51 | 52 | 53 | caBundle=$(base64 /var/run/kubernetes/server-ca.crt | awk 'BEGIN{ORS="";} {print}') 54 | 55 | # if we have a /api endpoint, then we need to register that 56 | if kubectl --kubeconfig="${FROM_KUBECONFIG}" get --raw / | grep -q /api/v1; then 57 | group="" 58 | version="v1" 59 | resourceName=${version}.${group} 60 | resourceFileName="${dir}/${resourceName}.yaml" 61 | cp "${scriptDir}/apiservice-template.yaml" "${resourceFileName}" 62 | ${SED} -i "s/RESOURCE_NAME/${resourceName}/" "${resourceFileName}" 63 | ${SED} -i "s/API_GROUP/${group}/" "${resourceFileName}" 64 | ${SED} -i "s/API_VERSION/${version}/" "${resourceFileName}" 65 | ${SED} -i "s/SERVICE_NAMESPACE/${SERVICE_NAMESPACE}/" "${resourceFileName}" 66 | ${SED} -i "s/SERVICE_NAME/${SERVICE_NAME}/" "${resourceFileName}" 67 | ${SED} -i "s/CA_BUNDLE/${caBundle}/" "${resourceFileName}" 68 | echo "registering ${resourceName} using ${resourceFileName}" 69 | 70 | kubectl --kubeconfig="${AGG_KUBECONFIG}" create -f "${resourceFileName}" 71 | fi 72 | 73 | while IFS=$'\n' read -r groupVersion; 74 | do groupVersions+=("$groupVersion"); 75 | done < <(kubectl get --raw / | grep /apis/ | sed 's/",.*//' | sed 's|.*"/apis/||' | grep '/') 76 | 77 | for groupVersion in "${groupVersions[@]}"; do 78 | group=$(echo "$groupVersion" | awk -F/ '{print $1}') 79 | version=$(echo "$groupVersion" | awk -F/ '{print $2}') 80 | resourceName=${version}.${group} 81 | resourceFileName=${dir}/${resourceName}.yaml 82 | cp "${scriptDir}/apiservice-template.yaml" "${resourceFileName}" 83 | ${SED} -i "s/RESOURCE_NAME/${resourceName}/" "${resourceFileName}" 84 | ${SED} -i "s/API_GROUP/${group}/" "${resourceFileName}" 85 | ${SED} -i "s/API_VERSION/${version}/" "${resourceFileName}" 86 | ${SED} -i "s/SERVICE_NAMESPACE/${SERVICE_NAMESPACE}/" "${resourceFileName}" 87 | ${SED} -i "s/SERVICE_NAME/${SERVICE_NAME}/" "${resourceFileName}" 88 | ${SED} -i "s/CA_BUNDLE/${caBundle}/" "${resourceFileName}" 89 | echo "registering ${resourceName} using ${resourceFileName}" 90 | 91 | kubectl --kubeconfig="${AGG_KUBECONFIG}" create -f "${resourceFileName}" 92 | done 93 | -------------------------------------------------------------------------------- /pkg/controllers/openapi/aggregator/downloader_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package aggregator 18 | 19 | import ( 20 | "fmt" 21 | "net/http" 22 | "testing" 23 | 24 | "github.com/stretchr/testify/assert" 25 | 26 | "k8s.io/kube-openapi/pkg/validation/spec" 27 | ) 28 | 29 | type handlerTest struct { 30 | etag string 31 | data []byte 32 | } 33 | 34 | var _ http.Handler = handlerTest{} 35 | 36 | func (h handlerTest) ServeHTTP(w http.ResponseWriter, r *http.Request) { 37 | if len(h.etag) > 0 { 38 | w.Header().Add("Etag", h.etag) 39 | } 40 | ifNoneMatches := r.Header["If-None-Match"] 41 | for _, match := range ifNoneMatches { 42 | if match == h.etag { 43 | w.WriteHeader(http.StatusNotModified) 44 | return 45 | } 46 | } 47 | w.Write(h.data) 48 | } 49 | 50 | type handlerDeprecatedTest struct { 51 | etag string 52 | data []byte 53 | } 54 | 55 | var _ http.Handler = handlerDeprecatedTest{} 56 | 57 | func (h handlerDeprecatedTest) ServeHTTP(w http.ResponseWriter, r *http.Request) { 58 | // old server returns 403 on new endpoint 59 | if r.URL.Path == "/openapi/v2" { 60 | w.WriteHeader(http.StatusForbidden) 61 | return 62 | } 63 | if len(h.etag) > 0 { 64 | w.Header().Add("Etag", h.etag) 65 | } 66 | ifNoneMatches := r.Header["If-None-Match"] 67 | for _, match := range ifNoneMatches { 68 | if match == h.etag { 69 | w.WriteHeader(http.StatusNotModified) 70 | return 71 | } 72 | } 73 | w.Write(h.data) 74 | } 75 | 76 | func assertDownloadedSpec(actualSpec *spec.Swagger, actualEtag string, err error, 77 | expectedSpecID string, expectedEtag string) error { 78 | if err != nil { 79 | return fmt.Errorf("downloadOpenAPISpec failed : %s", err) 80 | } 81 | if expectedSpecID == "" && actualSpec != nil { 82 | return fmt.Errorf("expected Not Modified, actual ID %s", actualSpec.ID) 83 | } 84 | if actualSpec != nil && actualSpec.ID != expectedSpecID { 85 | return fmt.Errorf("expected ID %s, actual ID %s", expectedSpecID, actualSpec.ID) 86 | } 87 | if actualEtag != expectedEtag { 88 | return fmt.Errorf("expected ETag '%s', actual ETag '%s'", expectedEtag, actualEtag) 89 | } 90 | return nil 91 | } 92 | 93 | func TestDownloadOpenAPISpec(t *testing.T) { 94 | s := Downloader{} 95 | 96 | // Test with no eTag 97 | actualSpec, actualEtag, _, err := s.Download(handlerTest{data: []byte("{\"id\": \"test\"}")}, "") 98 | assert.NoError(t, assertDownloadedSpec(actualSpec, actualEtag, err, "test", "\"6E8F849B434D4B98A569B9D7718876E9-356ECAB19D7FBE1336BABB1E70F8F3025050DE218BE78256BE81620681CFC9A268508E542B8B55974E17B2184BBFC8FFFAA577E51BE195D32B3CA2547818ABE4\"")) 99 | 100 | // Test with eTag 101 | actualSpec, actualEtag, _, err = s.Download( 102 | handlerTest{data: []byte("{\"id\": \"test\"}"), etag: "etag_test"}, "") 103 | assert.NoError(t, assertDownloadedSpec(actualSpec, actualEtag, err, "test", "etag_test")) 104 | 105 | // Test not modified 106 | actualSpec, actualEtag, _, err = s.Download( 107 | handlerTest{data: []byte("{\"id\": \"test\"}"), etag: "etag_test"}, "etag_test") 108 | assert.NoError(t, assertDownloadedSpec(actualSpec, actualEtag, err, "", "etag_test")) 109 | 110 | // Test different eTags 111 | actualSpec, actualEtag, _, err = s.Download( 112 | handlerTest{data: []byte("{\"id\": \"test\"}"), etag: "etag_test1"}, "etag_test2") 113 | assert.NoError(t, assertDownloadedSpec(actualSpec, actualEtag, err, "test", "etag_test1")) 114 | } 115 | -------------------------------------------------------------------------------- /pkg/apis/apiregistration/v1beta1/zz_generated.prerelease-lifecycle.go: -------------------------------------------------------------------------------- 1 | //go:build !ignore_autogenerated 2 | // +build !ignore_autogenerated 3 | 4 | /* 5 | Copyright The Kubernetes Authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | // Code generated by prerelease-lifecycle-gen. DO NOT EDIT. 21 | 22 | package v1beta1 23 | 24 | import ( 25 | schema "k8s.io/apimachinery/pkg/runtime/schema" 26 | ) 27 | 28 | // APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. 29 | // It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. 30 | func (in *APIService) APILifecycleIntroduced() (major, minor int) { 31 | return 1, 7 32 | } 33 | 34 | // APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. 35 | // It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. 36 | func (in *APIService) APILifecycleDeprecated() (major, minor int) { 37 | return 1, 19 38 | } 39 | 40 | // APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. 41 | // It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. 42 | func (in *APIService) APILifecycleReplacement() schema.GroupVersionKind { 43 | return schema.GroupVersionKind{Group: "apiregistration.k8s.io", Version: "v1", Kind: "APIService"} 44 | } 45 | 46 | // APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. 47 | // It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. 48 | func (in *APIService) APILifecycleRemoved() (major, minor int) { 49 | return 1, 22 50 | } 51 | 52 | // APILifecycleIntroduced is an autogenerated function, returning the release in which the API struct was introduced as int versions of major and minor for comparison. 53 | // It is controlled by "k8s:prerelease-lifecycle-gen:introduced" tags in types.go. 54 | func (in *APIServiceList) APILifecycleIntroduced() (major, minor int) { 55 | return 1, 7 56 | } 57 | 58 | // APILifecycleDeprecated is an autogenerated function, returning the release in which the API struct was or will be deprecated as int versions of major and minor for comparison. 59 | // It is controlled by "k8s:prerelease-lifecycle-gen:deprecated" tags in types.go or "k8s:prerelease-lifecycle-gen:introduced" plus three minor. 60 | func (in *APIServiceList) APILifecycleDeprecated() (major, minor int) { 61 | return 1, 19 62 | } 63 | 64 | // APILifecycleReplacement is an autogenerated function, returning the group, version, and kind that should be used instead of this deprecated type. 65 | // It is controlled by "k8s:prerelease-lifecycle-gen:replacement=,," tags in types.go. 66 | func (in *APIServiceList) APILifecycleReplacement() schema.GroupVersionKind { 67 | return schema.GroupVersionKind{Group: "apiregistration.k8s.io", Version: "v1", Kind: "APIServiceList"} 68 | } 69 | 70 | // APILifecycleRemoved is an autogenerated function, returning the release in which the API is no longer served as int versions of major and minor for comparison. 71 | // It is controlled by "k8s:prerelease-lifecycle-gen:removed" tags in types.go or "k8s:prerelease-lifecycle-gen:deprecated" plus three minor. 72 | func (in *APIServiceList) APILifecycleRemoved() (major, minor int) { 73 | return 1, 22 74 | } 75 | -------------------------------------------------------------------------------- /pkg/client/informers/externalversions/apiregistration/v1/apiservice.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by informer-gen. DO NOT EDIT. 18 | 19 | package v1 20 | 21 | import ( 22 | context "context" 23 | time "time" 24 | 25 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 | runtime "k8s.io/apimachinery/pkg/runtime" 27 | watch "k8s.io/apimachinery/pkg/watch" 28 | cache "k8s.io/client-go/tools/cache" 29 | apisapiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" 30 | clientset "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset" 31 | internalinterfaces "k8s.io/kube-aggregator/pkg/client/informers/externalversions/internalinterfaces" 32 | apiregistrationv1 "k8s.io/kube-aggregator/pkg/client/listers/apiregistration/v1" 33 | ) 34 | 35 | // APIServiceInformer provides access to a shared informer and lister for 36 | // APIServices. 37 | type APIServiceInformer interface { 38 | Informer() cache.SharedIndexInformer 39 | Lister() apiregistrationv1.APIServiceLister 40 | } 41 | 42 | type aPIServiceInformer struct { 43 | factory internalinterfaces.SharedInformerFactory 44 | tweakListOptions internalinterfaces.TweakListOptionsFunc 45 | } 46 | 47 | // NewAPIServiceInformer constructs a new informer for APIService type. 48 | // Always prefer using an informer factory to get a shared informer instead of getting an independent 49 | // one. This reduces memory footprint and number of connections to the server. 50 | func NewAPIServiceInformer(client clientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { 51 | return NewFilteredAPIServiceInformer(client, resyncPeriod, indexers, nil) 52 | } 53 | 54 | // NewFilteredAPIServiceInformer constructs a new informer for APIService type. 55 | // Always prefer using an informer factory to get a shared informer instead of getting an independent 56 | // one. This reduces memory footprint and number of connections to the server. 57 | func NewFilteredAPIServiceInformer(client clientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { 58 | return cache.NewSharedIndexInformer( 59 | cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ 60 | ListFunc: func(options metav1.ListOptions) (runtime.Object, error) { 61 | if tweakListOptions != nil { 62 | tweakListOptions(&options) 63 | } 64 | return client.ApiregistrationV1().APIServices().List(context.Background(), options) 65 | }, 66 | WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) { 67 | if tweakListOptions != nil { 68 | tweakListOptions(&options) 69 | } 70 | return client.ApiregistrationV1().APIServices().Watch(context.Background(), options) 71 | }, 72 | ListWithContextFunc: func(ctx context.Context, options metav1.ListOptions) (runtime.Object, error) { 73 | if tweakListOptions != nil { 74 | tweakListOptions(&options) 75 | } 76 | return client.ApiregistrationV1().APIServices().List(ctx, options) 77 | }, 78 | WatchFuncWithContext: func(ctx context.Context, options metav1.ListOptions) (watch.Interface, error) { 79 | if tweakListOptions != nil { 80 | tweakListOptions(&options) 81 | } 82 | return client.ApiregistrationV1().APIServices().Watch(ctx, options) 83 | }, 84 | }, client), 85 | &apisapiregistrationv1.APIService{}, 86 | resyncPeriod, 87 | indexers, 88 | ) 89 | } 90 | 91 | func (f *aPIServiceInformer) defaultInformer(client clientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { 92 | return NewFilteredAPIServiceInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) 93 | } 94 | 95 | func (f *aPIServiceInformer) Informer() cache.SharedIndexInformer { 96 | return f.factory.InformerFor(&apisapiregistrationv1.APIService{}, f.defaultInformer) 97 | } 98 | 99 | func (f *aPIServiceInformer) Lister() apiregistrationv1.APIServiceLister { 100 | return apiregistrationv1.NewAPIServiceLister(f.Informer().GetIndexer()) 101 | } 102 | -------------------------------------------------------------------------------- /pkg/client/informers/externalversions/apiregistration/v1beta1/apiservice.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by informer-gen. DO NOT EDIT. 18 | 19 | package v1beta1 20 | 21 | import ( 22 | context "context" 23 | time "time" 24 | 25 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 | runtime "k8s.io/apimachinery/pkg/runtime" 27 | watch "k8s.io/apimachinery/pkg/watch" 28 | cache "k8s.io/client-go/tools/cache" 29 | apisapiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1beta1" 30 | clientset "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset" 31 | internalinterfaces "k8s.io/kube-aggregator/pkg/client/informers/externalversions/internalinterfaces" 32 | apiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/client/listers/apiregistration/v1beta1" 33 | ) 34 | 35 | // APIServiceInformer provides access to a shared informer and lister for 36 | // APIServices. 37 | type APIServiceInformer interface { 38 | Informer() cache.SharedIndexInformer 39 | Lister() apiregistrationv1beta1.APIServiceLister 40 | } 41 | 42 | type aPIServiceInformer struct { 43 | factory internalinterfaces.SharedInformerFactory 44 | tweakListOptions internalinterfaces.TweakListOptionsFunc 45 | } 46 | 47 | // NewAPIServiceInformer constructs a new informer for APIService type. 48 | // Always prefer using an informer factory to get a shared informer instead of getting an independent 49 | // one. This reduces memory footprint and number of connections to the server. 50 | func NewAPIServiceInformer(client clientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { 51 | return NewFilteredAPIServiceInformer(client, resyncPeriod, indexers, nil) 52 | } 53 | 54 | // NewFilteredAPIServiceInformer constructs a new informer for APIService type. 55 | // Always prefer using an informer factory to get a shared informer instead of getting an independent 56 | // one. This reduces memory footprint and number of connections to the server. 57 | func NewFilteredAPIServiceInformer(client clientset.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { 58 | return cache.NewSharedIndexInformer( 59 | cache.ToListWatcherWithWatchListSemantics(&cache.ListWatch{ 60 | ListFunc: func(options v1.ListOptions) (runtime.Object, error) { 61 | if tweakListOptions != nil { 62 | tweakListOptions(&options) 63 | } 64 | return client.ApiregistrationV1beta1().APIServices().List(context.Background(), options) 65 | }, 66 | WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { 67 | if tweakListOptions != nil { 68 | tweakListOptions(&options) 69 | } 70 | return client.ApiregistrationV1beta1().APIServices().Watch(context.Background(), options) 71 | }, 72 | ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { 73 | if tweakListOptions != nil { 74 | tweakListOptions(&options) 75 | } 76 | return client.ApiregistrationV1beta1().APIServices().List(ctx, options) 77 | }, 78 | WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { 79 | if tweakListOptions != nil { 80 | tweakListOptions(&options) 81 | } 82 | return client.ApiregistrationV1beta1().APIServices().Watch(ctx, options) 83 | }, 84 | }, client), 85 | &apisapiregistrationv1beta1.APIService{}, 86 | resyncPeriod, 87 | indexers, 88 | ) 89 | } 90 | 91 | func (f *aPIServiceInformer) defaultInformer(client clientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { 92 | return NewFilteredAPIServiceInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) 93 | } 94 | 95 | func (f *aPIServiceInformer) Informer() cache.SharedIndexInformer { 96 | return f.factory.InformerFor(&apisapiregistrationv1beta1.APIService{}, f.defaultInformer) 97 | } 98 | 99 | func (f *aPIServiceInformer) Lister() apiregistrationv1beta1.APIServiceLister { 100 | return apiregistrationv1beta1.NewAPIServiceLister(f.Informer().GetIndexer()) 101 | } 102 | -------------------------------------------------------------------------------- /pkg/client/clientset_generated/clientset/fake/clientset_generated.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package fake 20 | 21 | import ( 22 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 23 | "k8s.io/apimachinery/pkg/runtime" 24 | "k8s.io/apimachinery/pkg/watch" 25 | "k8s.io/client-go/discovery" 26 | fakediscovery "k8s.io/client-go/discovery/fake" 27 | "k8s.io/client-go/testing" 28 | clientset "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset" 29 | apiregistrationv1 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1" 30 | fakeapiregistrationv1 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1/fake" 31 | apiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1" 32 | fakeapiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1/fake" 33 | ) 34 | 35 | // NewSimpleClientset returns a clientset that will respond with the provided objects. 36 | // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, 37 | // without applying any field management, validations and/or defaults. It shouldn't be considered a replacement 38 | // for a real clientset and is mostly useful in simple unit tests. 39 | // 40 | // Deprecated: NewClientset replaces this with support for field management, which significantly improves 41 | // server side apply testing. NewClientset is only available when apply configurations are generated (e.g. 42 | // via --with-applyconfig). 43 | func NewSimpleClientset(objects ...runtime.Object) *Clientset { 44 | o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) 45 | for _, obj := range objects { 46 | if err := o.Add(obj); err != nil { 47 | panic(err) 48 | } 49 | } 50 | 51 | cs := &Clientset{tracker: o} 52 | cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake} 53 | cs.AddReactor("*", "*", testing.ObjectReaction(o)) 54 | cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) { 55 | var opts metav1.ListOptions 56 | if watchAction, ok := action.(testing.WatchActionImpl); ok { 57 | opts = watchAction.ListOptions 58 | } 59 | gvr := action.GetResource() 60 | ns := action.GetNamespace() 61 | watch, err := o.Watch(gvr, ns, opts) 62 | if err != nil { 63 | return false, nil, err 64 | } 65 | return true, watch, nil 66 | }) 67 | 68 | return cs 69 | } 70 | 71 | // Clientset implements clientset.Interface. Meant to be embedded into a 72 | // struct to get a default implementation. This makes faking out just the method 73 | // you want to test easier. 74 | type Clientset struct { 75 | testing.Fake 76 | discovery *fakediscovery.FakeDiscovery 77 | tracker testing.ObjectTracker 78 | } 79 | 80 | func (c *Clientset) Discovery() discovery.DiscoveryInterface { 81 | return c.discovery 82 | } 83 | 84 | func (c *Clientset) Tracker() testing.ObjectTracker { 85 | return c.tracker 86 | } 87 | 88 | // IsWatchListSemanticsSupported informs the reflector that this client 89 | // doesn't support WatchList semantics. 90 | // 91 | // This is a synthetic method whose sole purpose is to satisfy the optional 92 | // interface check performed by the reflector. 93 | // Returning true signals that WatchList can NOT be used. 94 | // No additional logic is implemented here. 95 | func (c *Clientset) IsWatchListSemanticsUnSupported() bool { 96 | return true 97 | } 98 | 99 | var ( 100 | _ clientset.Interface = &Clientset{} 101 | _ testing.FakeClient = &Clientset{} 102 | ) 103 | 104 | // ApiregistrationV1 retrieves the ApiregistrationV1Client 105 | func (c *Clientset) ApiregistrationV1() apiregistrationv1.ApiregistrationV1Interface { 106 | return &fakeapiregistrationv1.FakeApiregistrationV1{Fake: &c.Fake} 107 | } 108 | 109 | // ApiregistrationV1beta1 retrieves the ApiregistrationV1beta1Client 110 | func (c *Clientset) ApiregistrationV1beta1() apiregistrationv1beta1.ApiregistrationV1beta1Interface { 111 | return &fakeapiregistrationv1beta1.FakeApiregistrationV1beta1{Fake: &c.Fake} 112 | } 113 | -------------------------------------------------------------------------------- /pkg/client/clientset_generated/clientset/clientset.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package clientset 20 | 21 | import ( 22 | fmt "fmt" 23 | http "net/http" 24 | 25 | discovery "k8s.io/client-go/discovery" 26 | rest "k8s.io/client-go/rest" 27 | flowcontrol "k8s.io/client-go/util/flowcontrol" 28 | apiregistrationv1 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1" 29 | apiregistrationv1beta1 "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/typed/apiregistration/v1beta1" 30 | ) 31 | 32 | type Interface interface { 33 | Discovery() discovery.DiscoveryInterface 34 | ApiregistrationV1() apiregistrationv1.ApiregistrationV1Interface 35 | ApiregistrationV1beta1() apiregistrationv1beta1.ApiregistrationV1beta1Interface 36 | } 37 | 38 | // Clientset contains the clients for groups. 39 | type Clientset struct { 40 | *discovery.DiscoveryClient 41 | apiregistrationV1 *apiregistrationv1.ApiregistrationV1Client 42 | apiregistrationV1beta1 *apiregistrationv1beta1.ApiregistrationV1beta1Client 43 | } 44 | 45 | // ApiregistrationV1 retrieves the ApiregistrationV1Client 46 | func (c *Clientset) ApiregistrationV1() apiregistrationv1.ApiregistrationV1Interface { 47 | return c.apiregistrationV1 48 | } 49 | 50 | // ApiregistrationV1beta1 retrieves the ApiregistrationV1beta1Client 51 | func (c *Clientset) ApiregistrationV1beta1() apiregistrationv1beta1.ApiregistrationV1beta1Interface { 52 | return c.apiregistrationV1beta1 53 | } 54 | 55 | // Discovery retrieves the DiscoveryClient 56 | func (c *Clientset) Discovery() discovery.DiscoveryInterface { 57 | if c == nil { 58 | return nil 59 | } 60 | return c.DiscoveryClient 61 | } 62 | 63 | // NewForConfig creates a new Clientset for the given config. 64 | // If config's RateLimiter is not set and QPS and Burst are acceptable, 65 | // NewForConfig will generate a rate-limiter in configShallowCopy. 66 | // NewForConfig is equivalent to NewForConfigAndClient(c, httpClient), 67 | // where httpClient was generated with rest.HTTPClientFor(c). 68 | func NewForConfig(c *rest.Config) (*Clientset, error) { 69 | configShallowCopy := *c 70 | 71 | if configShallowCopy.UserAgent == "" { 72 | configShallowCopy.UserAgent = rest.DefaultKubernetesUserAgent() 73 | } 74 | 75 | // share the transport between all clients 76 | httpClient, err := rest.HTTPClientFor(&configShallowCopy) 77 | if err != nil { 78 | return nil, err 79 | } 80 | 81 | return NewForConfigAndClient(&configShallowCopy, httpClient) 82 | } 83 | 84 | // NewForConfigAndClient creates a new Clientset for the given config and http client. 85 | // Note the http client provided takes precedence over the configured transport values. 86 | // If config's RateLimiter is not set and QPS and Burst are acceptable, 87 | // NewForConfigAndClient will generate a rate-limiter in configShallowCopy. 88 | func NewForConfigAndClient(c *rest.Config, httpClient *http.Client) (*Clientset, error) { 89 | configShallowCopy := *c 90 | if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 { 91 | if configShallowCopy.Burst <= 0 { 92 | return nil, fmt.Errorf("burst is required to be greater than 0 when RateLimiter is not set and QPS is set to greater than 0") 93 | } 94 | configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst) 95 | } 96 | 97 | var cs Clientset 98 | var err error 99 | cs.apiregistrationV1, err = apiregistrationv1.NewForConfigAndClient(&configShallowCopy, httpClient) 100 | if err != nil { 101 | return nil, err 102 | } 103 | cs.apiregistrationV1beta1, err = apiregistrationv1beta1.NewForConfigAndClient(&configShallowCopy, httpClient) 104 | if err != nil { 105 | return nil, err 106 | } 107 | 108 | cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfigAndClient(&configShallowCopy, httpClient) 109 | if err != nil { 110 | return nil, err 111 | } 112 | return &cs, nil 113 | } 114 | 115 | // NewForConfigOrDie creates a new Clientset for the given config and 116 | // panics if there is an error in the config. 117 | func NewForConfigOrDie(c *rest.Config) *Clientset { 118 | cs, err := NewForConfig(c) 119 | if err != nil { 120 | panic(err) 121 | } 122 | return cs 123 | } 124 | 125 | // New creates a new Clientset for the given RESTClient. 126 | func New(c rest.Interface) *Clientset { 127 | var cs Clientset 128 | cs.apiregistrationV1 = apiregistrationv1.New(c) 129 | cs.apiregistrationV1beta1 = apiregistrationv1beta1.New(c) 130 | 131 | cs.DiscoveryClient = discovery.NewDiscoveryClient(c) 132 | return &cs 133 | } 134 | -------------------------------------------------------------------------------- /pkg/apis/apiregistration/helpers.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package apiregistration 18 | 19 | import ( 20 | "sort" 21 | 22 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 23 | "k8s.io/apimachinery/pkg/version" 24 | ) 25 | 26 | // SortedByGroupAndVersion sorts APIServices into their different groups, and then sorts them based on their versions. 27 | // For example, the first element of the first array contains the APIService with the highest version number, in the 28 | // group with the highest priority; while the last element of the last array contains the APIService with the lowest 29 | // version number, in the group with the lowest priority. 30 | func SortedByGroupAndVersion(servers []*APIService) [][]*APIService { 31 | serversByGroupPriorityMinimum := ByGroupPriorityMinimum(servers) 32 | sort.Sort(serversByGroupPriorityMinimum) 33 | 34 | ret := [][]*APIService{} 35 | for _, curr := range serversByGroupPriorityMinimum { 36 | // check to see if we already have an entry for this group 37 | existingIndex := -1 38 | for j, groupInReturn := range ret { 39 | if groupInReturn[0].Spec.Group == curr.Spec.Group { 40 | existingIndex = j 41 | break 42 | } 43 | } 44 | 45 | if existingIndex >= 0 { 46 | ret[existingIndex] = append(ret[existingIndex], curr) 47 | sort.Sort(ByVersionPriority(ret[existingIndex])) 48 | continue 49 | } 50 | 51 | ret = append(ret, []*APIService{curr}) 52 | } 53 | 54 | return ret 55 | } 56 | 57 | // ByGroupPriorityMinimum sorts with the highest group number first, then by name. 58 | // This is not a simple reverse, because we want the name sorting to be alpha, not 59 | // reverse alpha. 60 | type ByGroupPriorityMinimum []*APIService 61 | 62 | func (s ByGroupPriorityMinimum) Len() int { return len(s) } 63 | func (s ByGroupPriorityMinimum) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 64 | func (s ByGroupPriorityMinimum) Less(i, j int) bool { 65 | if s[i].Spec.GroupPriorityMinimum != s[j].Spec.GroupPriorityMinimum { 66 | return s[i].Spec.GroupPriorityMinimum > s[j].Spec.GroupPriorityMinimum 67 | } 68 | return s[i].Name < s[j].Name 69 | } 70 | 71 | // ByVersionPriority sorts with the highest version number first, then by name. 72 | // This is not a simple reverse, because we want the name sorting to be alpha, not 73 | // reverse alpha. 74 | type ByVersionPriority []*APIService 75 | 76 | func (s ByVersionPriority) Len() int { return len(s) } 77 | func (s ByVersionPriority) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 78 | func (s ByVersionPriority) Less(i, j int) bool { 79 | if s[i].Spec.VersionPriority != s[j].Spec.VersionPriority { 80 | return s[i].Spec.VersionPriority > s[j].Spec.VersionPriority 81 | } 82 | return version.CompareKubeAwareVersionStrings(s[i].Spec.Version, s[j].Spec.Version) > 0 83 | } 84 | 85 | // NewLocalAvailableAPIServiceCondition returns a condition for an available local APIService. 86 | func NewLocalAvailableAPIServiceCondition() APIServiceCondition { 87 | return APIServiceCondition{ 88 | Type: Available, 89 | Status: ConditionTrue, 90 | LastTransitionTime: metav1.Now(), 91 | Reason: "Local", 92 | Message: "Local APIServices are always available", 93 | } 94 | } 95 | 96 | // GetAPIServiceConditionByType gets an *APIServiceCondition by APIServiceConditionType if present 97 | func GetAPIServiceConditionByType(apiService *APIService, conditionType APIServiceConditionType) *APIServiceCondition { 98 | for i := range apiService.Status.Conditions { 99 | if apiService.Status.Conditions[i].Type == conditionType { 100 | return &apiService.Status.Conditions[i] 101 | } 102 | } 103 | return nil 104 | } 105 | 106 | // SetAPIServiceCondition sets the status condition. It either overwrites the existing one or 107 | // creates a new one 108 | func SetAPIServiceCondition(apiService *APIService, newCondition APIServiceCondition) { 109 | existingCondition := GetAPIServiceConditionByType(apiService, newCondition.Type) 110 | if existingCondition == nil { 111 | apiService.Status.Conditions = append(apiService.Status.Conditions, newCondition) 112 | return 113 | } 114 | 115 | if existingCondition.Status != newCondition.Status { 116 | existingCondition.Status = newCondition.Status 117 | existingCondition.LastTransitionTime = newCondition.LastTransitionTime 118 | } 119 | 120 | existingCondition.Reason = newCondition.Reason 121 | existingCondition.Message = newCondition.Message 122 | } 123 | 124 | // IsAPIServiceConditionTrue indicates if the condition is present and strictly true 125 | func IsAPIServiceConditionTrue(apiService *APIService, conditionType APIServiceConditionType) bool { 126 | condition := GetAPIServiceConditionByType(apiService, conditionType) 127 | return condition != nil && condition.Status == ConditionTrue 128 | } 129 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | // This is a generated file. Do not edit directly. 2 | 3 | module k8s.io/kube-aggregator 4 | 5 | go 1.25.0 6 | 7 | godebug default=go1.25 8 | 9 | require ( 10 | github.com/emicklei/go-restful/v3 v3.12.2 11 | github.com/google/go-cmp v0.7.0 12 | github.com/spf13/cobra v1.10.0 13 | github.com/spf13/pflag v1.0.9 14 | github.com/stretchr/testify v1.11.1 15 | go.opentelemetry.io/otel v1.36.0 16 | go.opentelemetry.io/otel/sdk v1.36.0 17 | go.opentelemetry.io/otel/trace v1.36.0 18 | golang.org/x/net v0.47.0 19 | k8s.io/api v0.0.0-20251204222646-382014e64b8e 20 | k8s.io/apimachinery v0.0.0-20251204222123-56aa7d5cc8bb 21 | k8s.io/apiserver v0.0.0-20251204230936-a52843043e97 22 | k8s.io/client-go v0.0.0-20251204223340-453ad29ccd47 23 | k8s.io/code-generator v0.0.0-20251204225359-ce3f9b635c2d 24 | k8s.io/component-base v0.0.0-20251204225730-8cb15f10375f 25 | k8s.io/klog/v2 v2.130.1 26 | k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 27 | k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 28 | sigs.k8s.io/randfill v1.0.0 29 | sigs.k8s.io/structured-merge-diff/v6 v6.3.0 30 | ) 31 | 32 | require ( 33 | cel.dev/expr v0.24.0 // indirect 34 | github.com/NYTimes/gziphandler v1.1.1 // indirect 35 | github.com/antlr4-go/antlr/v4 v4.13.0 // indirect 36 | github.com/beorn7/perks v1.0.1 // indirect 37 | github.com/blang/semver/v4 v4.0.0 // indirect 38 | github.com/cenkalti/backoff/v4 v4.3.0 // indirect 39 | github.com/cespare/xxhash/v2 v2.3.0 // indirect 40 | github.com/coreos/go-semver v0.3.1 // indirect 41 | github.com/coreos/go-systemd/v22 v22.5.0 // indirect 42 | github.com/davecgh/go-spew v1.1.1 // indirect 43 | github.com/felixge/httpsnoop v1.0.4 // indirect 44 | github.com/fsnotify/fsnotify v1.9.0 // indirect 45 | github.com/fxamacker/cbor/v2 v2.9.0 // indirect 46 | github.com/go-logr/logr v1.4.3 // indirect 47 | github.com/go-logr/stdr v1.2.2 // indirect 48 | github.com/go-openapi/jsonpointer v0.21.0 // indirect 49 | github.com/go-openapi/jsonreference v0.20.2 // indirect 50 | github.com/go-openapi/swag v0.23.0 // indirect 51 | github.com/gogo/protobuf v1.3.2 // indirect 52 | github.com/golang/protobuf v1.5.4 // indirect 53 | github.com/google/btree v1.1.3 // indirect 54 | github.com/google/cel-go v0.26.0 // indirect 55 | github.com/google/gnostic-models v0.7.0 // indirect 56 | github.com/google/uuid v1.6.0 // indirect 57 | github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect 58 | github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect 59 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 // indirect 60 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 61 | github.com/josharian/intern v1.0.0 // indirect 62 | github.com/json-iterator/go v1.1.12 // indirect 63 | github.com/kylelemons/godebug v1.1.0 // indirect 64 | github.com/mailru/easyjson v0.7.7 // indirect 65 | github.com/moby/spdystream v0.5.0 // indirect 66 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect 67 | github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect 68 | github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect 69 | github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect 70 | github.com/pmezard/go-difflib v1.0.0 // indirect 71 | github.com/prometheus/client_golang v1.23.2 // indirect 72 | github.com/prometheus/client_model v0.6.2 // indirect 73 | github.com/prometheus/common v0.66.1 // indirect 74 | github.com/prometheus/procfs v0.16.1 // indirect 75 | github.com/stoewer/go-strcase v1.3.0 // indirect 76 | github.com/x448/float16 v0.8.4 // indirect 77 | go.etcd.io/etcd/api/v3 v3.6.5 // indirect 78 | go.etcd.io/etcd/client/pkg/v3 v3.6.5 // indirect 79 | go.etcd.io/etcd/client/v3 v3.6.5 // indirect 80 | go.opentelemetry.io/auto/sdk v1.1.0 // indirect 81 | go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.60.0 // indirect 82 | go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect 83 | go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect 84 | go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect 85 | go.opentelemetry.io/otel/metric v1.36.0 // indirect 86 | go.opentelemetry.io/proto/otlp v1.5.0 // indirect 87 | go.uber.org/multierr v1.11.0 // indirect 88 | go.uber.org/zap v1.27.0 // indirect 89 | go.yaml.in/yaml/v2 v2.4.3 // indirect 90 | go.yaml.in/yaml/v3 v3.0.4 // indirect 91 | golang.org/x/crypto v0.45.0 // indirect 92 | golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect 93 | golang.org/x/mod v0.29.0 // indirect 94 | golang.org/x/oauth2 v0.30.0 // indirect 95 | golang.org/x/sync v0.18.0 // indirect 96 | golang.org/x/sys v0.38.0 // indirect 97 | golang.org/x/term v0.37.0 // indirect 98 | golang.org/x/text v0.31.0 // indirect 99 | golang.org/x/time v0.9.0 // indirect 100 | golang.org/x/tools v0.38.0 // indirect 101 | google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb // indirect 102 | google.golang.org/genproto/googleapis/rpc v0.0.0-20250528174236-200df99c418a // indirect 103 | google.golang.org/grpc v1.72.2 // indirect 104 | google.golang.org/protobuf v1.36.8 // indirect 105 | gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect 106 | gopkg.in/inf.v0 v0.9.1 // indirect 107 | gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect 108 | gopkg.in/yaml.v3 v3.0.1 // indirect 109 | k8s.io/gengo/v2 v2.0.0-20250922181213-ec3ebc5fd46b // indirect 110 | k8s.io/kms v0.0.0-20251204230241-5c729e7c0a92 // indirect 111 | sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.2 // indirect 112 | sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect 113 | sigs.k8s.io/yaml v1.6.0 // indirect 114 | ) 115 | -------------------------------------------------------------------------------- /pkg/apis/apiregistration/v1/zz_generated.deepcopy.go: -------------------------------------------------------------------------------- 1 | //go:build !ignore_autogenerated 2 | // +build !ignore_autogenerated 3 | 4 | /* 5 | Copyright The Kubernetes Authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | // Code generated by deepcopy-gen. DO NOT EDIT. 21 | 22 | package v1 23 | 24 | import ( 25 | runtime "k8s.io/apimachinery/pkg/runtime" 26 | ) 27 | 28 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 29 | func (in *APIService) DeepCopyInto(out *APIService) { 30 | *out = *in 31 | out.TypeMeta = in.TypeMeta 32 | in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) 33 | in.Spec.DeepCopyInto(&out.Spec) 34 | in.Status.DeepCopyInto(&out.Status) 35 | return 36 | } 37 | 38 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIService. 39 | func (in *APIService) DeepCopy() *APIService { 40 | if in == nil { 41 | return nil 42 | } 43 | out := new(APIService) 44 | in.DeepCopyInto(out) 45 | return out 46 | } 47 | 48 | // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. 49 | func (in *APIService) DeepCopyObject() runtime.Object { 50 | if c := in.DeepCopy(); c != nil { 51 | return c 52 | } 53 | return nil 54 | } 55 | 56 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 57 | func (in *APIServiceCondition) DeepCopyInto(out *APIServiceCondition) { 58 | *out = *in 59 | in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) 60 | return 61 | } 62 | 63 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIServiceCondition. 64 | func (in *APIServiceCondition) DeepCopy() *APIServiceCondition { 65 | if in == nil { 66 | return nil 67 | } 68 | out := new(APIServiceCondition) 69 | in.DeepCopyInto(out) 70 | return out 71 | } 72 | 73 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 74 | func (in *APIServiceList) DeepCopyInto(out *APIServiceList) { 75 | *out = *in 76 | out.TypeMeta = in.TypeMeta 77 | in.ListMeta.DeepCopyInto(&out.ListMeta) 78 | if in.Items != nil { 79 | in, out := &in.Items, &out.Items 80 | *out = make([]APIService, len(*in)) 81 | for i := range *in { 82 | (*in)[i].DeepCopyInto(&(*out)[i]) 83 | } 84 | } 85 | return 86 | } 87 | 88 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIServiceList. 89 | func (in *APIServiceList) DeepCopy() *APIServiceList { 90 | if in == nil { 91 | return nil 92 | } 93 | out := new(APIServiceList) 94 | in.DeepCopyInto(out) 95 | return out 96 | } 97 | 98 | // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. 99 | func (in *APIServiceList) DeepCopyObject() runtime.Object { 100 | if c := in.DeepCopy(); c != nil { 101 | return c 102 | } 103 | return nil 104 | } 105 | 106 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 107 | func (in *APIServiceSpec) DeepCopyInto(out *APIServiceSpec) { 108 | *out = *in 109 | if in.Service != nil { 110 | in, out := &in.Service, &out.Service 111 | *out = new(ServiceReference) 112 | (*in).DeepCopyInto(*out) 113 | } 114 | if in.CABundle != nil { 115 | in, out := &in.CABundle, &out.CABundle 116 | *out = make([]byte, len(*in)) 117 | copy(*out, *in) 118 | } 119 | return 120 | } 121 | 122 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIServiceSpec. 123 | func (in *APIServiceSpec) DeepCopy() *APIServiceSpec { 124 | if in == nil { 125 | return nil 126 | } 127 | out := new(APIServiceSpec) 128 | in.DeepCopyInto(out) 129 | return out 130 | } 131 | 132 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 133 | func (in *APIServiceStatus) DeepCopyInto(out *APIServiceStatus) { 134 | *out = *in 135 | if in.Conditions != nil { 136 | in, out := &in.Conditions, &out.Conditions 137 | *out = make([]APIServiceCondition, len(*in)) 138 | for i := range *in { 139 | (*in)[i].DeepCopyInto(&(*out)[i]) 140 | } 141 | } 142 | return 143 | } 144 | 145 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIServiceStatus. 146 | func (in *APIServiceStatus) DeepCopy() *APIServiceStatus { 147 | if in == nil { 148 | return nil 149 | } 150 | out := new(APIServiceStatus) 151 | in.DeepCopyInto(out) 152 | return out 153 | } 154 | 155 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 156 | func (in *ServiceReference) DeepCopyInto(out *ServiceReference) { 157 | *out = *in 158 | if in.Port != nil { 159 | in, out := &in.Port, &out.Port 160 | *out = new(int32) 161 | **out = **in 162 | } 163 | return 164 | } 165 | 166 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceReference. 167 | func (in *ServiceReference) DeepCopy() *ServiceReference { 168 | if in == nil { 169 | return nil 170 | } 171 | out := new(ServiceReference) 172 | in.DeepCopyInto(out) 173 | return out 174 | } 175 | -------------------------------------------------------------------------------- /pkg/apis/apiregistration/v1beta1/zz_generated.deepcopy.go: -------------------------------------------------------------------------------- 1 | //go:build !ignore_autogenerated 2 | // +build !ignore_autogenerated 3 | 4 | /* 5 | Copyright The Kubernetes Authors. 6 | 7 | Licensed under the Apache License, Version 2.0 (the "License"); 8 | you may not use this file except in compliance with the License. 9 | You may obtain a copy of the License at 10 | 11 | http://www.apache.org/licenses/LICENSE-2.0 12 | 13 | Unless required by applicable law or agreed to in writing, software 14 | distributed under the License is distributed on an "AS IS" BASIS, 15 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | See the License for the specific language governing permissions and 17 | limitations under the License. 18 | */ 19 | 20 | // Code generated by deepcopy-gen. DO NOT EDIT. 21 | 22 | package v1beta1 23 | 24 | import ( 25 | runtime "k8s.io/apimachinery/pkg/runtime" 26 | ) 27 | 28 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 29 | func (in *APIService) DeepCopyInto(out *APIService) { 30 | *out = *in 31 | out.TypeMeta = in.TypeMeta 32 | in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) 33 | in.Spec.DeepCopyInto(&out.Spec) 34 | in.Status.DeepCopyInto(&out.Status) 35 | return 36 | } 37 | 38 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIService. 39 | func (in *APIService) DeepCopy() *APIService { 40 | if in == nil { 41 | return nil 42 | } 43 | out := new(APIService) 44 | in.DeepCopyInto(out) 45 | return out 46 | } 47 | 48 | // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. 49 | func (in *APIService) DeepCopyObject() runtime.Object { 50 | if c := in.DeepCopy(); c != nil { 51 | return c 52 | } 53 | return nil 54 | } 55 | 56 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 57 | func (in *APIServiceCondition) DeepCopyInto(out *APIServiceCondition) { 58 | *out = *in 59 | in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime) 60 | return 61 | } 62 | 63 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIServiceCondition. 64 | func (in *APIServiceCondition) DeepCopy() *APIServiceCondition { 65 | if in == nil { 66 | return nil 67 | } 68 | out := new(APIServiceCondition) 69 | in.DeepCopyInto(out) 70 | return out 71 | } 72 | 73 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 74 | func (in *APIServiceList) DeepCopyInto(out *APIServiceList) { 75 | *out = *in 76 | out.TypeMeta = in.TypeMeta 77 | in.ListMeta.DeepCopyInto(&out.ListMeta) 78 | if in.Items != nil { 79 | in, out := &in.Items, &out.Items 80 | *out = make([]APIService, len(*in)) 81 | for i := range *in { 82 | (*in)[i].DeepCopyInto(&(*out)[i]) 83 | } 84 | } 85 | return 86 | } 87 | 88 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIServiceList. 89 | func (in *APIServiceList) DeepCopy() *APIServiceList { 90 | if in == nil { 91 | return nil 92 | } 93 | out := new(APIServiceList) 94 | in.DeepCopyInto(out) 95 | return out 96 | } 97 | 98 | // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. 99 | func (in *APIServiceList) DeepCopyObject() runtime.Object { 100 | if c := in.DeepCopy(); c != nil { 101 | return c 102 | } 103 | return nil 104 | } 105 | 106 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 107 | func (in *APIServiceSpec) DeepCopyInto(out *APIServiceSpec) { 108 | *out = *in 109 | if in.Service != nil { 110 | in, out := &in.Service, &out.Service 111 | *out = new(ServiceReference) 112 | (*in).DeepCopyInto(*out) 113 | } 114 | if in.CABundle != nil { 115 | in, out := &in.CABundle, &out.CABundle 116 | *out = make([]byte, len(*in)) 117 | copy(*out, *in) 118 | } 119 | return 120 | } 121 | 122 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIServiceSpec. 123 | func (in *APIServiceSpec) DeepCopy() *APIServiceSpec { 124 | if in == nil { 125 | return nil 126 | } 127 | out := new(APIServiceSpec) 128 | in.DeepCopyInto(out) 129 | return out 130 | } 131 | 132 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 133 | func (in *APIServiceStatus) DeepCopyInto(out *APIServiceStatus) { 134 | *out = *in 135 | if in.Conditions != nil { 136 | in, out := &in.Conditions, &out.Conditions 137 | *out = make([]APIServiceCondition, len(*in)) 138 | for i := range *in { 139 | (*in)[i].DeepCopyInto(&(*out)[i]) 140 | } 141 | } 142 | return 143 | } 144 | 145 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIServiceStatus. 146 | func (in *APIServiceStatus) DeepCopy() *APIServiceStatus { 147 | if in == nil { 148 | return nil 149 | } 150 | out := new(APIServiceStatus) 151 | in.DeepCopyInto(out) 152 | return out 153 | } 154 | 155 | // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. 156 | func (in *ServiceReference) DeepCopyInto(out *ServiceReference) { 157 | *out = *in 158 | if in.Port != nil { 159 | in, out := &in.Port, &out.Port 160 | *out = new(int32) 161 | **out = **in 162 | } 163 | return 164 | } 165 | 166 | // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServiceReference. 167 | func (in *ServiceReference) DeepCopy() *ServiceReference { 168 | if in == nil { 169 | return nil 170 | } 171 | out := new(ServiceReference) 172 | in.DeepCopyInto(out) 173 | return out 174 | } 175 | -------------------------------------------------------------------------------- /pkg/apis/apiregistration/v1/helper/helpers.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package helper 18 | 19 | import ( 20 | "sort" 21 | "strings" 22 | 23 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 | "k8s.io/apimachinery/pkg/runtime/schema" 25 | "k8s.io/apimachinery/pkg/version" 26 | "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" 27 | ) 28 | 29 | // SortedByGroupAndVersion sorts APIServices into their different groups, and then sorts them based on their versions. 30 | // For example, the first element of the first array contains the APIService with the highest version number, in the 31 | // group with the highest priority; while the last element of the last array contains the APIService with the lowest 32 | // version number, in the group with the lowest priority. 33 | func SortedByGroupAndVersion(servers []*v1.APIService) [][]*v1.APIService { 34 | serversByGroupPriorityMinimum := ByGroupPriorityMinimum(servers) 35 | sort.Sort(serversByGroupPriorityMinimum) 36 | 37 | ret := [][]*v1.APIService{} 38 | for _, curr := range serversByGroupPriorityMinimum { 39 | // check to see if we already have an entry for this group 40 | existingIndex := -1 41 | for j, groupInReturn := range ret { 42 | if groupInReturn[0].Spec.Group == curr.Spec.Group { 43 | existingIndex = j 44 | break 45 | } 46 | } 47 | 48 | if existingIndex >= 0 { 49 | ret[existingIndex] = append(ret[existingIndex], curr) 50 | sort.Sort(ByVersionPriority(ret[existingIndex])) 51 | continue 52 | } 53 | 54 | ret = append(ret, []*v1.APIService{curr}) 55 | } 56 | 57 | return ret 58 | } 59 | 60 | // ByGroupPriorityMinimum sorts with the highest group number first, then by name. 61 | // This is not a simple reverse, because we want the name sorting to be alpha, not 62 | // reverse alpha. 63 | type ByGroupPriorityMinimum []*v1.APIService 64 | 65 | func (s ByGroupPriorityMinimum) Len() int { return len(s) } 66 | func (s ByGroupPriorityMinimum) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 67 | func (s ByGroupPriorityMinimum) Less(i, j int) bool { 68 | if s[i].Spec.GroupPriorityMinimum != s[j].Spec.GroupPriorityMinimum { 69 | return s[i].Spec.GroupPriorityMinimum > s[j].Spec.GroupPriorityMinimum 70 | } 71 | return s[i].Name < s[j].Name 72 | } 73 | 74 | // ByVersionPriority sorts with the highest version number first, then by name. 75 | // This is not a simple reverse, because we want the name sorting to be alpha, not 76 | // reverse alpha. 77 | type ByVersionPriority []*v1.APIService 78 | 79 | func (s ByVersionPriority) Len() int { return len(s) } 80 | func (s ByVersionPriority) Swap(i, j int) { s[i], s[j] = s[j], s[i] } 81 | func (s ByVersionPriority) Less(i, j int) bool { 82 | if s[i].Spec.VersionPriority != s[j].Spec.VersionPriority { 83 | return s[i].Spec.VersionPriority > s[j].Spec.VersionPriority 84 | } 85 | return version.CompareKubeAwareVersionStrings(s[i].Spec.Version, s[j].Spec.Version) > 0 86 | } 87 | 88 | // APIServiceNameToGroupVersion returns the GroupVersion for a given apiServiceName. The name 89 | // must be valid, but any object you get back from an informer will be valid. 90 | func APIServiceNameToGroupVersion(apiServiceName string) schema.GroupVersion { 91 | tokens := strings.SplitN(apiServiceName, ".", 2) 92 | return schema.GroupVersion{Group: tokens[1], Version: tokens[0]} 93 | } 94 | 95 | // NewLocalAvailableAPIServiceCondition returns a condition for an available local APIService. 96 | func NewLocalAvailableAPIServiceCondition() v1.APIServiceCondition { 97 | return v1.APIServiceCondition{ 98 | Type: v1.Available, 99 | Status: v1.ConditionTrue, 100 | LastTransitionTime: metav1.Now(), 101 | Reason: "Local", 102 | Message: "Local APIServices are always available", 103 | } 104 | } 105 | 106 | // SetAPIServiceCondition sets the status condition. It either overwrites the existing one or 107 | // creates a new one 108 | func SetAPIServiceCondition(apiService *v1.APIService, newCondition v1.APIServiceCondition) { 109 | existingCondition := GetAPIServiceConditionByType(apiService, newCondition.Type) 110 | if existingCondition == nil { 111 | apiService.Status.Conditions = append(apiService.Status.Conditions, newCondition) 112 | return 113 | } 114 | 115 | if existingCondition.Status != newCondition.Status { 116 | existingCondition.Status = newCondition.Status 117 | existingCondition.LastTransitionTime = newCondition.LastTransitionTime 118 | } 119 | 120 | existingCondition.Reason = newCondition.Reason 121 | existingCondition.Message = newCondition.Message 122 | } 123 | 124 | // IsAPIServiceConditionTrue indicates if the condition is present and strictly true 125 | func IsAPIServiceConditionTrue(apiService *v1.APIService, conditionType v1.APIServiceConditionType) bool { 126 | condition := GetAPIServiceConditionByType(apiService, conditionType) 127 | return condition != nil && condition.Status == v1.ConditionTrue 128 | } 129 | 130 | // GetAPIServiceConditionByType gets an *APIServiceCondition by APIServiceConditionType if present 131 | func GetAPIServiceConditionByType(apiService *v1.APIService, conditionType v1.APIServiceConditionType) *v1.APIServiceCondition { 132 | for i := range apiService.Status.Conditions { 133 | if apiService.Status.Conditions[i].Type == conditionType { 134 | return &apiService.Status.Conditions[i] 135 | } 136 | } 137 | return nil 138 | } 139 | -------------------------------------------------------------------------------- /hack/local-up-kube-aggregator.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright 2016 The Kubernetes Authors. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # starts kube-aggregator as a pod after you've run `local-up-cluster.sh` 18 | 19 | set -o errexit 20 | set -o nounset 21 | set -o pipefail 22 | 23 | AGG_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. 24 | KUBE_ROOT=${AGG_ROOT}/../../../.. 25 | source "${KUBE_ROOT}/hack/lib/init.sh" 26 | 27 | AGGREGATOR_SECURE_PORT=${AGGREGATOR_SECURE_PORT:-31090} 28 | API_HOST=${API_HOST:-localhost} 29 | API_HOST_IP=${API_HOST_IP:-"127.0.0.1"} 30 | AGGREGATOR_CERT_DIR=${AGGREGATOR_CERT_DIR:-"/var/run/kubernetes/aggregator"} 31 | 32 | KUBE_CERT_DIR=${KUBE_CERT_DIR:-"/var/run/kubernetes"} 33 | SERVING_CERT_CA_CERT=${SERVING_CERT_CA_CERT:-"${KUBE_CERT_DIR}/server-ca.crt"} 34 | CLIENT_CERT_CA_CERT=${CLIENT_CERT_CA_CERT:-"${KUBE_CERT_DIR}/client-ca.crt"} 35 | FRONT_PROXY_CLIENT_CERT_CA_CERT=${FRONT_PROXY_CLIENT_CERT_CA_CERT:-"${KUBE_CERT_DIR}/request-header-ca.crt"} 36 | SERVING_CERT=${SERVING_CERT:-"${KUBE_CERT_DIR}/serving-kube-aggregator.crt"} 37 | SERVING_KEY=${SERVING_KEY:-"${KUBE_CERT_DIR}/serving-kube-aggregator.key"} 38 | FRONT_PROXY_CLIENT_CERT=${FRONT_PROXY_CLIENT_CERT:-"${KUBE_CERT_DIR}/client-auth-proxy.crt"} 39 | FRONT_PROXY_CLIENT_KEY=${FRONT_PROXY_CLIENT_KEY:-"${KUBE_CERT_DIR}/client-auth-proxy.key"} 40 | 41 | 42 | # Ensure AGGREGATOR_CERT_DIR is created for auto-generated crt/key and kubeconfig 43 | mkdir -p "${AGGREGATOR_CERT_DIR}" &>/dev/null || sudo mkdir -p "${AGGREGATOR_CERT_DIR}" 44 | sudo=$(test -w "${AGGREGATOR_CERT_DIR}" || echo "sudo -E") 45 | 46 | # start_kube-aggregator relies on certificates created by start_apiserver 47 | function start_kube-aggregator { 48 | # Create serving and client CA. etcd only takes one arg 49 | kube::util::create_signing_certkey "${sudo}" "${AGGREGATOR_CERT_DIR}" "etcd" '"client auth","server auth"' 50 | kube::util::create_serving_certkey "${sudo}" "${AGGREGATOR_CERT_DIR}" "etcd-ca" etcd etcd.kube-public.svc 51 | # etcd doesn't seem to have separate signers for serving and client trust 52 | kube::util::create_client_certkey "${sudo}" "${AGGREGATOR_CERT_DIR}" "etcd-ca" kube-aggregator-etcd kube-aggregator-etcd 53 | 54 | # don't fail if the namespace already exists or something 55 | # If this fails for some reason, the script will fail during creation of other resources 56 | kubectl create namespace kube-public || true 57 | 58 | # grant permission to run delegated authentication and authorization checks 59 | kubectl delete clusterrolebinding kube-aggregator:system:auth-delegator > /dev/null 2>&1 || true 60 | kubectl delete clusterrolebinding kube-aggregator:system:kube-aggregator > /dev/null 2>&1 || true 61 | kubectl create clusterrolebinding kube-aggregator:system:auth-delegator --clusterrole=system:auth-delegator --serviceaccount=kube-public:kube-aggregator 62 | kubectl create clusterrolebinding kube-aggregator:system:kube-aggregator --clusterrole=system:kube-aggregator --serviceaccount=kube-public:kube-aggregator 63 | kubectl delete rolebinding -n kube-system kube-aggregator:authentication-reader > /dev/null 2>&1 || true 64 | kubectl create rolebinding -n kube-system kube-aggregator:authentication-reader --role=extension-apiserver-authentication-reader --serviceaccount=kube-public:kube-aggregator 65 | 66 | # make sure the resources we're about to create don't exist 67 | kubectl -n kube-public delete secret auth-proxy-client serving-etcd serving-kube-aggregator kube-aggregator-etcd > /dev/null 2>&1 || true 68 | kubectl -n kube-public delete configmap etcd-ca kube-aggregator-ca client-ca request-header-ca > /dev/null 2>&1 || true 69 | kubectl -n kube-public delete -f "${AGG_ROOT}/artifacts/self-contained" > /dev/null 2>&1 || true 70 | 71 | ${sudo} "$(which kubectl)" -n kube-public create secret tls auth-proxy-client --cert="${FRONT_PROXY_CLIENT_CERT}" --key="${FRONT_PROXY_CLIENT_KEY}" 72 | ${sudo} "$(which kubectl)" -n kube-public create secret tls serving-etcd --cert="${AGGREGATOR_CERT_DIR}/serving-etcd.crt" --key="${AGGREGATOR_CERT_DIR}/serving-etcd.key" 73 | ${sudo} "$(which kubectl)" -n kube-public create secret tls serving-kube-aggregator --cert="${SERVING_CERT}" --key="${SERVING_KEY}" 74 | ${sudo} "$(which kubectl)" -n kube-public create secret tls kube-aggregator-etcd --cert="${AGGREGATOR_CERT_DIR}/client-kube-aggregator-etcd.crt" --key="${AGGREGATOR_CERT_DIR}/client-kube-aggregator-etcd.key" 75 | kubectl -n kube-public create configmap etcd-ca --from-file="ca.crt=${AGGREGATOR_CERT_DIR}/etcd-ca.crt" || true 76 | kubectl -n kube-public create configmap kube-aggregator-ca --from-file="ca.crt=${SERVING_CERT_CA_CERT}" || true 77 | kubectl -n kube-public create configmap client-ca --from-file="ca.crt=${CLIENT_CERT_CA_CERT}" || true 78 | kubectl -n kube-public create configmap request-header-ca --from-file="ca.crt=${FRONT_PROXY_CLIENT_CERT_CA_CERT}" || true 79 | 80 | kubectl -n kube-public create -f "${AGG_ROOT}/artifacts/self-contained" 81 | 82 | # Wait for kube-aggregator to come up before launching the rest of the components. 83 | # This should work since we're creating a node port service. 84 | echo "Waiting for kube-aggregator to come up: https://${API_HOST_IP}:${AGGREGATOR_SECURE_PORT}/version" 85 | kube::util::wait_for_url "https://${API_HOST_IP}:${AGGREGATOR_SECURE_PORT}/version" "kube-aggregator: " 1 60 || exit 1 86 | } 87 | 88 | kube::util::test_openssl_installed 89 | kube::util::ensure-cfssl 90 | 91 | start_kube-aggregator 92 | 93 | echo "kube-aggregator available at https://${API_HOST_IP}:${AGGREGATOR_SECURE_PORT} from 'api.kube-public.svc'" 94 | -------------------------------------------------------------------------------- /pkg/controllers/openapi/aggregator/downloader.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2017 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package aggregator 18 | 19 | import ( 20 | "crypto/sha512" 21 | "fmt" 22 | "net/http" 23 | "strings" 24 | "sync/atomic" 25 | 26 | "k8s.io/apiserver/pkg/authentication/user" 27 | "k8s.io/apiserver/pkg/endpoints/request" 28 | "k8s.io/apiserver/pkg/util/responsewriter" 29 | "k8s.io/kube-openapi/pkg/validation/spec" 30 | ) 31 | 32 | type CacheableDownloader interface { 33 | UpdateHandler(http.Handler) 34 | Get() (*spec.Swagger, string, error) 35 | } 36 | 37 | // cacheableDownloader is a downloader that will always return the data 38 | // and the etag. 39 | type cacheableDownloader struct { 40 | name string 41 | downloader *Downloader 42 | // handler is the http Handler for the apiservice that can be replaced 43 | handler atomic.Pointer[http.Handler] 44 | etag string 45 | spec *spec.Swagger 46 | } 47 | 48 | // NewCacheableDownloader creates a downloader that also returns the etag, making it useful to use as a cached dependency. 49 | func NewCacheableDownloader(apiServiceName string, downloader *Downloader, handler http.Handler) CacheableDownloader { 50 | c := &cacheableDownloader{ 51 | name: apiServiceName, 52 | downloader: downloader, 53 | } 54 | c.handler.Store(&handler) 55 | return c 56 | } 57 | func (d *cacheableDownloader) UpdateHandler(handler http.Handler) { 58 | d.handler.Store(&handler) 59 | } 60 | 61 | func (d *cacheableDownloader) Get() (*spec.Swagger, string, error) { 62 | spec, etag, err := d.get() 63 | if err != nil { 64 | return spec, etag, fmt.Errorf("failed to download %v: %v", d.name, err) 65 | } 66 | return spec, etag, err 67 | } 68 | 69 | func (d *cacheableDownloader) get() (*spec.Swagger, string, error) { 70 | h := *d.handler.Load() 71 | swagger, etag, status, err := d.downloader.Download(h, d.etag) 72 | if err != nil { 73 | return nil, "", err 74 | } 75 | switch status { 76 | case http.StatusNotModified: 77 | // Nothing has changed, do nothing. 78 | case http.StatusOK: 79 | if swagger != nil { 80 | d.etag = etag 81 | d.spec = swagger 82 | break 83 | } 84 | fallthrough 85 | case http.StatusNotFound: 86 | return nil, "", ErrAPIServiceNotFound 87 | default: 88 | return nil, "", fmt.Errorf("invalid status code: %v", status) 89 | } 90 | return d.spec, d.etag, nil 91 | } 92 | 93 | // Downloader is the OpenAPI downloader type. It will try to download spec from /openapi/v2 or /swagger.json endpoint. 94 | type Downloader struct { 95 | } 96 | 97 | // NewDownloader creates a new OpenAPI Downloader. 98 | func NewDownloader() Downloader { 99 | return Downloader{} 100 | } 101 | 102 | func (s *Downloader) handlerWithUser(handler http.Handler, info user.Info) http.Handler { 103 | return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 104 | req = req.WithContext(request.WithUser(req.Context(), info)) 105 | handler.ServeHTTP(w, req) 106 | }) 107 | } 108 | 109 | func etagFor(data []byte) string { 110 | return fmt.Sprintf("%s%X\"", locallyGeneratedEtagPrefix, sha512.Sum512(data)) 111 | } 112 | 113 | // Download downloads openAPI spec from /openapi/v2 endpoint of the given handler. 114 | // httpStatus is only valid if err == nil 115 | func (s *Downloader) Download(handler http.Handler, etag string) (returnSpec *spec.Swagger, newEtag string, httpStatus int, err error) { 116 | handler = s.handlerWithUser(handler, &user.DefaultInfo{Name: aggregatorUser}) 117 | handler = http.TimeoutHandler(handler, specDownloadTimeout, "request timed out") 118 | 119 | req, err := http.NewRequest("GET", "/openapi/v2", nil) 120 | if err != nil { 121 | return nil, "", 0, err 122 | } 123 | req.Header.Add("Accept", "application/json") 124 | 125 | // Only pass eTag if it is not generated locally 126 | if len(etag) > 0 && !strings.HasPrefix(etag, locallyGeneratedEtagPrefix) { 127 | req.Header.Add("If-None-Match", etag) 128 | } 129 | 130 | writer := responsewriter.NewInMemoryResponseWriter() 131 | handler.ServeHTTP(writer, req) 132 | 133 | switch writer.RespCode() { 134 | case http.StatusNotModified: 135 | if len(etag) == 0 { 136 | return nil, etag, http.StatusNotModified, fmt.Errorf("http.StatusNotModified is not allowed in absence of etag") 137 | } 138 | return nil, etag, http.StatusNotModified, nil 139 | case http.StatusNotFound: 140 | // Gracefully skip 404, assuming the server won't provide any spec 141 | return nil, "", http.StatusNotFound, nil 142 | case http.StatusOK: 143 | openAPISpec := &spec.Swagger{} 144 | if err := openAPISpec.UnmarshalJSON(writer.Data()); err != nil { 145 | return nil, "", 0, err 146 | } 147 | newEtag = writer.Header().Get("Etag") 148 | if len(newEtag) == 0 { 149 | newEtag = etagFor(writer.Data()) 150 | if len(etag) > 0 && strings.HasPrefix(etag, locallyGeneratedEtagPrefix) { 151 | // The function call with an etag and server does not report an etag. 152 | // That means this server does not support etag and the etag that passed 153 | // to the function generated previously by us. Just compare etags and 154 | // return StatusNotModified if they are the same. 155 | if etag == newEtag { 156 | return nil, etag, http.StatusNotModified, nil 157 | } 158 | } 159 | } 160 | return openAPISpec, newEtag, http.StatusOK, nil 161 | default: 162 | return nil, "", 0, fmt.Errorf("failed to retrieve openAPI spec, http error: %s", writer.String()) 163 | } 164 | } 165 | -------------------------------------------------------------------------------- /pkg/controllers/openapi/controller.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2016 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package openapi 18 | 19 | import ( 20 | "fmt" 21 | "net/http" 22 | "time" 23 | 24 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 25 | "k8s.io/apimachinery/pkg/util/wait" 26 | "k8s.io/client-go/util/workqueue" 27 | "k8s.io/klog/v2" 28 | v1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" 29 | "k8s.io/kube-aggregator/pkg/controllers/openapi/aggregator" 30 | ) 31 | 32 | const ( 33 | successfulUpdateDelay = time.Minute 34 | successfulUpdateDelayLocal = time.Second 35 | failedUpdateMaxExpDelay = time.Hour 36 | ) 37 | 38 | type syncAction int 39 | 40 | const ( 41 | syncRequeue syncAction = iota 42 | syncRequeueRateLimited 43 | syncNothing 44 | ) 45 | 46 | // AggregationController periodically check for changes in OpenAPI specs of APIServices and update/remove 47 | // them if necessary. 48 | type AggregationController struct { 49 | openAPIAggregationManager aggregator.SpecAggregator 50 | queue workqueue.TypedRateLimitingInterface[string] 51 | downloader *aggregator.Downloader 52 | 53 | // To allow injection for testing. 54 | syncHandler func(key string) (syncAction, error) 55 | } 56 | 57 | // NewAggregationController creates new OpenAPI aggregation controller. 58 | func NewAggregationController(downloader *aggregator.Downloader, openAPIAggregationManager aggregator.SpecAggregator) *AggregationController { 59 | c := &AggregationController{ 60 | openAPIAggregationManager: openAPIAggregationManager, 61 | queue: workqueue.NewTypedRateLimitingQueueWithConfig( 62 | workqueue.NewTypedItemExponentialFailureRateLimiter[string](successfulUpdateDelay, failedUpdateMaxExpDelay), 63 | workqueue.TypedRateLimitingQueueConfig[string]{Name: "open_api_aggregation_controller"}, 64 | ), 65 | downloader: downloader, 66 | } 67 | 68 | c.syncHandler = c.sync 69 | 70 | return c 71 | } 72 | 73 | // Run starts OpenAPI AggregationController 74 | func (c *AggregationController) Run(stopCh <-chan struct{}) { 75 | defer utilruntime.HandleCrash() 76 | defer c.queue.ShutDown() 77 | 78 | klog.Info("Starting OpenAPI AggregationController") 79 | defer klog.Info("Shutting down OpenAPI AggregationController") 80 | 81 | go wait.Until(c.runWorker, time.Second, stopCh) 82 | 83 | <-stopCh 84 | } 85 | 86 | func (c *AggregationController) runWorker() { 87 | for c.processNextWorkItem() { 88 | } 89 | } 90 | 91 | // processNextWorkItem deals with one key off the queue. It returns false when it's time to quit. 92 | func (c *AggregationController) processNextWorkItem() bool { 93 | key, quit := c.queue.Get() 94 | defer c.queue.Done(key) 95 | if quit { 96 | return false 97 | } 98 | klog.V(4).Infof("OpenAPI AggregationController: Processing item %s", key) 99 | 100 | action, err := c.syncHandler(key) 101 | if err != nil { 102 | utilruntime.HandleError(fmt.Errorf("loading OpenAPI spec for %q failed with: %v", key, err)) 103 | } 104 | 105 | switch action { 106 | case syncRequeue: 107 | c.queue.AddAfter(key, successfulUpdateDelay) 108 | case syncRequeueRateLimited: 109 | klog.Infof("OpenAPI AggregationController: action for item %s: Rate Limited Requeue.", key) 110 | c.queue.AddRateLimited(key) 111 | case syncNothing: 112 | c.queue.Forget(key) 113 | } 114 | 115 | return true 116 | } 117 | 118 | func (c *AggregationController) sync(key string) (syncAction, error) { 119 | if err := c.openAPIAggregationManager.UpdateAPIServiceSpec(key); err != nil { 120 | if err == aggregator.ErrAPIServiceNotFound { 121 | return syncNothing, nil 122 | } else { 123 | return syncRequeueRateLimited, err 124 | } 125 | } 126 | return syncRequeue, nil 127 | } 128 | 129 | // AddAPIService adds a new API Service to OpenAPI Aggregation. 130 | func (c *AggregationController) AddAPIService(handler http.Handler, apiService *v1.APIService) { 131 | if apiService.Spec.Service == nil { 132 | return 133 | } 134 | if err := c.openAPIAggregationManager.AddUpdateAPIService(apiService, handler); err != nil { 135 | utilruntime.HandleError(fmt.Errorf("adding %q to AggregationController failed with: %v", apiService.Name, err)) 136 | } 137 | c.queue.AddAfter(apiService.Name, time.Second) 138 | } 139 | 140 | // UpdateAPIService updates API Service's info and handler. 141 | func (c *AggregationController) UpdateAPIService(handler http.Handler, apiService *v1.APIService) { 142 | if apiService.Spec.Service == nil { 143 | return 144 | } 145 | if err := c.openAPIAggregationManager.UpdateAPIServiceSpec(apiService.Name); err != nil { 146 | utilruntime.HandleError(fmt.Errorf("Error updating APIService %q with err: %v", apiService.Name, err)) 147 | } 148 | key := apiService.Name 149 | if c.queue.NumRequeues(key) > 0 { 150 | // The item has failed before. Remove it from failure queue and 151 | // update it in a second 152 | c.queue.Forget(key) 153 | c.queue.AddAfter(key, time.Second) 154 | } 155 | // Else: The item has been succeeded before and it will be updated soon (after successfulUpdateDelay) 156 | // we don't add it again as it will cause a duplication of items. 157 | } 158 | 159 | // RemoveAPIService removes API Service from OpenAPI Aggregation Controller. 160 | func (c *AggregationController) RemoveAPIService(apiServiceName string) { 161 | c.openAPIAggregationManager.RemoveAPIService(apiServiceName) 162 | // This will only remove it if it was failing before. If it was successful, processNextWorkItem will figure it out 163 | // and will not add it again to the queue. 164 | c.queue.Forget(apiServiceName) 165 | } 166 | --------------------------------------------------------------------------------