├── .github
├── ISSUE_TEMPLATE
│ ├── bug-report.yaml
│ ├── config.yml
│ └── enhancement.yaml
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── GOVERNANCE.md
├── LICENSE
├── MAINTAINERS.md
├── Makefile
├── README.md
├── README.zh.md
├── cmd
├── clusterresourcequota
│ ├── install.go
│ └── main.go
└── kubezoo
│ ├── app
│ ├── apiextensions.go
│ ├── apigroups.go
│ ├── customresource_handler.go
│ ├── helpers.go
│ ├── options
│ │ ├── globalflags.go
│ │ ├── options.go
│ │ ├── proxy.go
│ │ └── validation.go
│ └── server.go
│ └── main.go
├── config
└── setup
│ ├── all_in_one.yaml
│ ├── quota.tmpl.yaml
│ └── sample_tenant.yaml
├── docs
├── conformance.md
├── debug-kubezoo-locally.md
├── design-cn.md
├── design.md
├── developer-guide.md
├── faq.md
├── faq.zh.md
├── img
│ ├── architecture-overview.png
│ ├── bell-outline-badge.png
│ ├── cluster-scope-resource.png
│ ├── comparison.png
│ ├── custom-resource.png
│ ├── design-ideas.png
│ ├── kubezoo-overview-dark.png
│ ├── kubezoo-overview.png
│ └── namespace-scope-resource.png
├── manually-setup-cn.md
├── manually-setup.md
├── proposals
│ ├── 20221030-garbage-collection-of-tenant-resources.md
│ └── YYMMDD-template.md
├── resource-and-system-requirements.md
└── roadmap.md
├── go.mod
├── go.sum
├── hack
├── boilerplate.go.txt
├── dockerfiles
│ ├── clusterresourcequota.Dockerfile
│ └── kubezoo.Dockerfile
├── lib
│ ├── build.sh
│ ├── gen_pki.sh
│ └── init.sh
└── make-rules
│ ├── build.sh
│ └── local_up.sh
└── pkg
├── apis
├── generated
│ └── openapi
│ │ ├── openapi_generated.go
│ │ └── violations.report
├── openapi
│ └── zz_generated.openapi.go
├── quota
│ ├── install
│ │ └── zz.generated.install.go
│ ├── v1alpha1
│ │ ├── clusterresourcequota_defaults.go
│ │ ├── clusterresourcequota_hub.go
│ │ ├── clusterresourcequota_types.go
│ │ ├── doc.go
│ │ ├── generated.pb.go
│ │ ├── generated.proto
│ │ ├── well_known.go
│ │ ├── zz_generated.deepcopy.go
│ │ ├── zz_generated.default.go
│ │ ├── zz_generated.defaults.go
│ │ └── zz_generated.register.go
│ └── zz.generated.crd.go
└── tenant
│ ├── install
│ └── install.go
│ ├── v1alpha1
│ ├── doc.go
│ ├── generated.pb.go
│ ├── generated.proto
│ ├── register.go
│ ├── types.go
│ └── zz_generated.deepcopy.go
│ └── zz.generated.crd.go
├── clusterresourcequota
└── controllers
│ ├── clusterresourcequota_controller.go
│ ├── util.go
│ └── webhook.go
├── common
├── const.go
├── convertor.go
└── reststorage.go
├── controller
├── controller.go
├── controller_test.go
└── suite_test.go
├── convert
├── clusterrole.go
├── clusterrole_test.go
├── clusterrolebinding.go
├── clusterrolebinding_test.go
├── cross-object.go
├── cross-object_test.go
├── customresource.go
├── customresource_test.go
├── customresourcedefinition.go
├── customresourcedefinition_test.go
├── default.go
├── default_test.go
├── endpoints.go
├── endpoints_test.go
├── endpointslice.go
├── endpointslice_test.go
├── event.go
├── event_test.go
├── init.go
├── init_test.go
├── namespace.go
├── nativeresource.go
├── nope.go
├── objectreference.go
├── objectreference_test.go
├── ownerreference.go
├── ownerreference_test.go
├── pv.go
├── pv_test.go
├── pvc.go
├── pvc_test.go
├── role.go
├── role_test.go
├── rolebinding.go
├── rolebinding_test.go
├── tokenreview.go
├── tokenreview_test.go
├── volumeattachment.go
└── volumeattachment_test.go
├── dynamic
├── client_test.go
├── interface.go
├── scheme.go
└── simple.go
├── filters
├── discovery.go
├── discovery_test.go
├── tenant.go
└── tenant_test.go
├── generated
├── clientset
│ └── versioned
│ │ ├── clientset.go
│ │ ├── doc.go
│ │ ├── fake
│ │ ├── clientset_generated.go
│ │ ├── doc.go
│ │ └── register.go
│ │ ├── scheme
│ │ ├── doc.go
│ │ └── register.go
│ │ └── typed
│ │ ├── quota
│ │ └── v1alpha1
│ │ │ ├── clusterresourcequota.go
│ │ │ ├── doc.go
│ │ │ ├── fake
│ │ │ ├── doc.go
│ │ │ ├── fake_clusterresourcequota.go
│ │ │ └── fake_quota_client.go
│ │ │ ├── generated_expansion.go
│ │ │ └── quota_client.go
│ │ └── tenant
│ │ └── v1alpha1
│ │ ├── doc.go
│ │ ├── fake
│ │ ├── doc.go
│ │ ├── fake_tenant.go
│ │ └── fake_tenant_client.go
│ │ ├── generated_expansion.go
│ │ ├── tenant.go
│ │ └── tenant_client.go
├── informers
│ └── externalversions
│ │ ├── factory.go
│ │ ├── generic.go
│ │ ├── internalinterfaces
│ │ └── factory_interfaces.go
│ │ ├── quota
│ │ ├── interface.go
│ │ └── v1alpha1
│ │ │ ├── clusterresourcequota.go
│ │ │ └── interface.go
│ │ └── tenant
│ │ ├── interface.go
│ │ └── v1alpha1
│ │ ├── interface.go
│ │ └── tenant.go
├── listers
│ ├── quota
│ │ └── v1alpha1
│ │ │ ├── clusterresourcequota.go
│ │ │ └── expansion_generated.go
│ └── tenant
│ │ └── v1alpha1
│ │ ├── expansion_generated.go
│ │ └── tenant.go
└── openapi
│ └── zz_generated.openapi.go
├── proxy
├── connecterproxy.go
├── discovery.go
├── discovery_test.go
├── init.go
├── pod
│ └── proxy.go
├── proxy.go
├── proxy_test.go
├── reststorage.go
└── watch.go
├── rest
├── etcd.go
├── storage_rest.go
└── strategy.go
└── util
├── certs.go
├── certs_test.go
├── crd.go
├── crd_test.go
├── errors.go
├── errors_test.go
├── kubeconfig.go
├── util.go
└── util_test.go
/.github/ISSUE_TEMPLATE/bug-report.yaml:
--------------------------------------------------------------------------------
1 | name: Bug Report
2 | description: Report a bug encountered
3 | body:
4 | - type: textarea
5 | id: problem
6 | attributes:
7 | label: What happened?
8 | description: |
9 | Please provide as much info as possible. Not doing so may result in your bug not being addressed in a timely manner.
10 | If this matter is security related, please disclose it privately via https://security.bytedance.com
11 | validations:
12 | required: true
13 |
14 | - type: textarea
15 | id: expected
16 | attributes:
17 | label: What did you expect to happen?
18 | validations:
19 | required: true
20 |
21 | - type: textarea
22 | id: repro
23 | attributes:
24 | label: How can we reproduce it (as minimally and precisely as possible)?
25 | validations:
26 | required: true
27 |
28 | - type: textarea
29 | id: version
30 | attributes:
31 | label: Software version
32 | value: |
33 |
34 |
35 | ```console
36 | $ version
37 | # paste output here
38 | ```
39 |
40 | validations:
41 | required: false
42 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: true
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/enhancement.yaml:
--------------------------------------------------------------------------------
1 | name: Feature Tracking Issue
2 | description: Provide supporting details for a feature in development
3 | body:
4 | - type: textarea
5 | id: feature
6 | attributes:
7 | label: What would you like to be added?
8 | validations:
9 | required: true
10 |
11 | - type: textarea
12 | id: rationale
13 | attributes:
14 | label: Why is this needed?
15 | validations:
16 | required: true
17 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | #### What type of PR is this?
2 |
5 |
6 | #### What this PR does / why we need it:
7 |
8 | #### Which issue(s) this PR fixes:
9 |
10 | #### Special notes for your reviewer:
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | _output
3 | bin
4 | .vscode
5 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # CHANGELOG
2 |
3 | ## v0.1.0-beta.1
4 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # ByteDance Contributor Code of Conduct
2 |
3 | Our Pledge
4 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to make participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, or sexual identity and orientation.
5 |
6 | Our Standards
7 | Examples of behavior that contributes to creating a positive environment include:
8 | - Using welcoming and inclusive language
9 | - Being respectful of differing viewpoints and experiences
10 | - Gracefully accepting constructive criticism
11 | - Focusing on what is best for the community
12 | - Showing empathy towards other community members
13 |
14 | Examples of unacceptable behavior by participants include:
15 | - The use of sexualized language or imagery and unwelcome sexual attention or advances
16 | - Trolling, insulting/derogatory comments, and personal or political attacks
17 | - Public or private harassment
18 | - Publishing others’ private information, such as a physical or electronic address, without explicit permission
19 | - Other conduct which could reasonably be considered inappropriate in a professional setting
20 |
21 | Our Responsibilities
22 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
23 |
24 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
25 |
26 | Scope
27 | This Code of Conduct applies within all project spaces, and it also applies when an individual is representing the project or its community in public spaces. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
28 |
29 | Enforcement
30 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at kubewharf.conduct@bytedance.com. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
31 |
32 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project’s leadership.
33 |
34 | Attribution
35 | This Code of Conduct is adapted from the Contributor Covenant, version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
36 |
37 | For answers to common questions about this code of conduct, see https://www.contributor-covenant.org/faq
38 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM debian:bookworm
2 | ADD bin/kubezoo /usr/local/bin
3 |
--------------------------------------------------------------------------------
/GOVERNANCE.md:
--------------------------------------------------------------------------------
1 | # Governance
2 |
3 | The governance model adopted in KubeZoo is influenced by many CNCF projects.
4 |
5 | ## Principles
6 |
7 | - **Open**: KubeZoo is open source community. See (TODO: add Contributor License Agreement).
8 | - **Welcoming and respectful**: See [Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).
9 | - **Transparent and accessible**: Work and collaboration should be done in public.
10 | - **Merit**: Ideas and contributions are accepted according to their technical merit
11 | and alignment with project objectives, scope and design principles.
12 |
13 | ## Code of Conduct
14 |
15 | The KubeZoo [Code of Conduct](CODE_OF_CONDUCT.md) is aligned with the CNCF Code of Conduct.
16 |
17 | ## Community MemberShip
18 |
19 | See community membership (TODO: add community membership).
20 |
21 | ## Decision making process
22 |
23 | Decisions are made based on consensus between maintainers.
24 | Proposals and ideas can either be submitted for agreement via a github issue or PR,
25 | or by sending an email to (TODO: register an email for the org).
26 |
27 | In general, we prefer that technical issues and maintainer membership are amicably worked out between the persons involved.
28 | If a dispute cannot be decided independently, get a third-party maintainer (e.g. a mutual contact with some background
29 | on the issue, but not involved in the conflict) to intercede and the final decision will be made.
30 | Decision making process should be transparent to adhere to the principles of KubeZoo project.
31 |
32 | ## Credits
33 |
34 | Some contents in this documents have been borrowed from [OpenYurt](https://github.com/openyurtio/openyurt/blob/master/GOVERNANCE.md), [BFE](https://github.com/bfenetworks/bfe/blob/develop/GOVERNANCE.md), [CoreDNS](https://github.com/coredns/coredns/blob/master/GOVERNANCE.md) and [Kubernetes governance](https://github.com/kubernetes/community/blob/master/governance.md) projects.
35 |
--------------------------------------------------------------------------------
/MAINTAINERS.md:
--------------------------------------------------------------------------------
1 | # The KubeZoo Maintainers
2 |
3 | This file lists the maintainers of the KubeZoo project. The responsibilities of maintainers are listed in the [GOVERNANCE.md](GOVERNANCE.md) file.
4 |
5 | ## Project Maintainers
6 | | Name | GitHub ID | Affiliation |
7 | | ---- | --------- | ----------- |
8 | | Jingsi Ren | [Silverglass](https://github.com/Silverglass) | ByteDance |
9 | | Chen Xu | [xuchen-xiaoying](https://github.com/xuchen-xiaoying) | ByteDance |
10 | | Deliang Fan | [DeliangFan](https://github.com/DeliangFan) | ByteDance |
11 | | Jun Zhang | [zoumo](https://github.com/zoumo)| ByteDance |
12 | | Charles Zheng | [charleszheng44](https://github.com/charleszheng44) | ByteDance |
13 | | He Cao | [caohe](https://github.com/caohe) | ByteDance |
14 | | Kwan Yin Chan | [SOF3](https://github.com/SOF3) | ByteDance |
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # KubeZoo - Gateway Service for Kubernetes Multi-tenancy
2 |
3 | English | [简体中文](./README.zh.md)
4 |
5 |
6 | ## Overview
7 |
8 | KubeZoo is a lightweight gateway service that leverages the existing namespace model
9 | and add multi-tenancy capability to existing Kubernetes. KubeZoo provides
10 | view-level isolation among tenants by capturing and transforming the requests and responses.
11 | Please refer to [design doc](./docs/design.md) for details.
12 |
13 |
14 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | ## Why KubeZoo
24 |
25 | There exists [three common multi-tenancy](https://kubernetes.io/blog/2021/04/15/three-tenancy-models-for-kubernetes/) models for Kubernetes,
26 | i.e., Namespace as a Service (NaaS), Cluster as a Service (CaaS), Control Planes as a service (CPaaS). Each of them can be applied to address different
27 | use cases. However, our cases have some specific requirements and constraints that can not be met by the existing models,
28 | * ***Many Small Tenants*** - there usually exist hundreds of tenants who only need to run small batch workloads containing few pods for tens of minutes.
29 | * ***Short Turnaround Time*** - users/tenants are usually impatient, who desire to have their service to be ready in minutes.
30 | * ***Tight Manpower*** - managing thousands of clusters/control-planes can be labour-intensive and infeasible for medium-sized dev team.
31 |
32 | To address these cases, we present a new tenancy model, i.e., **Kubernetes API as a Service (KAaaS)**, which provides competent isolation with
33 | negligible overheads and operation costs. KubeZoo implements this model with all tenants sharing both the control-plane and data-plane, which is
34 | suitable for the scenarios where thousands of small tenants need to share an underlying Kubernetes cluster.
35 |
36 |
37 |
38 |
39 |
40 | For more details lease refer [FAQ](./docs/faq.md).
41 |
42 | ## Prerequisites
43 |
44 | Please check the [resource and system requirements](./docs/resource-and-system-requirements.md) before installing KubeZoo.
45 |
46 | ## Getting started
47 |
48 | KubeZoo supports Kubernetes versions up to 1.24. Using higher Kubernetes versions may cause
49 | compatibility issues. KubeZoo can be installed using any of the following methods:
50 |
51 | | Methods | Instruction | Estimated time |
52 | | --------------------------- | ------------------------------------------ | -------------- |
53 | | Deploy KubeZoo from scratch | [Deploy KubeZoo](./docs/manually-setup.md) | < 2 minutes |
54 |
55 | ## Community
56 |
57 | ### Contributing
58 |
59 | If you are willing to be a contributor for the KubeZoo project, please refer to our [CONTRIBUTING](CONTRIBUTING.md) document for details.
60 | We have also prepared a developer [guide](./docs/developer-guide.md) to help the code contributors.
61 |
62 | ### Contact
63 |
64 | If you have any questions or want to contribute, you are welcome to communicate most things via GitHub issues or pull requests.
65 | Or Contact to [Maintainers](./MAINTAINERS.md)
66 |
67 |
68 | ## License
69 |
70 | KubeZoo is under the Apache 2.0 license. See the [LICENSE](LICENSE) file for details.
71 | Certain implementations in KubeZoo rely on the existing code from Kubernetes and the credits go to the original Kubernetes authors.
72 |
--------------------------------------------------------------------------------
/README.zh.md:
--------------------------------------------------------------------------------
1 | # kubezoo-io/kubezooio
2 |
3 | [English](./README.md) | 简体中文
4 |
5 | ## 简介
6 |
7 | KubeZoo 是轻量级的 Kubernetes 多租户项目,基于协议转换的核心理念在一个物理的 K8S 控制面上虚拟多个控制面,具备轻量级、兼容原生 API 、无侵入等特点。
8 | 详细设计请参考 [设计文档](./docs/design-cn.md)
9 |
10 |
11 |
12 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | ## 为什么选择 KubeZoo
22 |
23 | 社区 Kubernetes Multi-Tenancy Working Group 定义 [3 种 Kubernetes 多租户模型](https://kubernetes.io/blog/2021/04/15/three-tenancy-models-for-kubernetes/),例如: Namespace as a Service (NaaS)、Cluster as a Service (CaaS)、Control Planes as a service (CPaaS),这些模型侧重于不同的场景。放眼公有云和部分私有云场景,通常会碰到如下问题:首先海量的小 K8S 集群更像是云上的常态;其次用户期望快速的交付一个 Kubernetes 环境;最后则是海量 Kubernetes 集群带来的巨大的运维管理成本。
24 |
25 | 增强 K8S 集群多租户功能,使其具备极低的资源和运维成本、秒级的生命周期管理、原生的 API 和安全能力,进而打造 Serverless K8S 底座,在 Serverless 大行其道的今天,其重要性不言而喻,亦是我们创造 KubeZoo 的初心。
26 |
27 |
28 |
29 |
30 |
31 | 您可以参考 [FAQ](./docs/faq.zh.md) 获得更多的信息。
32 |
33 | ## 前置依赖
34 |
35 | 请参考 [resource and system requirements](./docs/resource-and-system-requirements.md) 完成 KubeZoo 前置依赖检查。
36 |
37 | ## 部署
38 |
39 | KubeZoo 支持 Kubernetes 1.24 及以下版本,更高的 Kubernetes 版本可能会导致兼容相关的问题。您可以采用如下方式部署 KubeZoo:
40 |
41 |
42 | | Methods | Instruction | Estimated time |
43 | | --------------------------- | ------------------------------------------ | -------------- |
44 | | Deploy KubeZoo from scratch | [Deploy KubeZoo](./docs/manually-setup-cn.md) | < 2 minutes |
45 |
46 | ## 社区
47 |
48 | ### 贡献
49 |
50 | 若您期望成为 KubeZoo 的贡献者,请参考 [CONTRIBUTING](CONTRIBUTING.md) 文档,我们也提供开发者手册 [guide](./docs/developer-guide.md) 供您参考。
51 |
52 | ### 联系方式
53 |
54 | 如果您有任何疑问,欢迎提交 GitHub issues 或者 pull requests,或者联系我们的 [Maintainers](./MAINTAINERS.md)。
55 |
56 |
57 | ## 协议
58 |
59 | KubeZoo 采用 Apache 2.0 协议,协议详情请参考 [LICENSE](LICENSE),另外 KubeZoo 中的某些实现依赖于 Kubernetes 代码,此部分版权归属于 Kubernetes Authors。
--------------------------------------------------------------------------------
/cmd/clusterresourcequota/install.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 | apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
21 | apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
22 | utilruntime "k8s.io/apimachinery/pkg/util/runtime"
23 | scheme "k8s.io/client-go/kubernetes/scheme"
24 |
25 | quota "github.com/kubewharf/kubezoo/pkg/apis/quota"
26 | quotav1alpha1 "github.com/kubewharf/kubezoo/pkg/apis/quota/v1alpha1"
27 | )
28 |
29 | func init() {
30 | utilruntime.Must(apiextensionsv1beta1.AddToScheme(scheme.Scheme))
31 | utilruntime.Must(apiextensionsv1.AddToScheme(scheme.Scheme))
32 | utilruntime.Must(quotav1alpha1.AddToScheme(scheme.Scheme))
33 | }
34 |
35 | func NewV1CustomResourceDefinitions() []*apiextensionsv1.CustomResourceDefinition {
36 | crds := []*apiextensionsv1.CustomResourceDefinition{}
37 | crds = append(crds, quota.NewClusterResourceQuotaCRD())
38 | return crds
39 | }
40 |
--------------------------------------------------------------------------------
/cmd/kubezoo/app/helpers.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 app
18 |
19 | import (
20 | "fmt"
21 |
22 | apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
23 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24 | )
25 |
26 | var swaggerMetadataDescriptions = metav1.ObjectMeta{}.SwaggerDoc()
27 |
28 | // getColumnsForVersion returns the columns for given version or nil.
29 | // NOTE: the newly logically-defaulted columns is not pointing to the original CRD object.
30 | // One cannot mutate the original CRD columns using the logically-defaulted columns. Please iterate through
31 | // the original CRD object instead.
32 | func getColumnsForVersion(crd *apiextensionsv1.CustomResourceDefinition, version string) ([]apiextensionsv1.CustomResourceColumnDefinition, error) {
33 | for _, v := range crd.Spec.Versions {
34 | if version == v.Name {
35 | return serveDefaultColumnsIfEmpty(v.AdditionalPrinterColumns), nil
36 | }
37 | }
38 | return nil, fmt.Errorf("version %s not found in apiextensionsv1.CustomResourceDefinition: %v", version, crd.Name)
39 | }
40 |
41 | // serveDefaultColumnsIfEmpty applies logically defaulting to columns, if the input columns is empty.
42 | // NOTE: in this way, the newly logically-defaulted columns is not pointing to the original CRD object.
43 | // One cannot mutate the original CRD columns using the logically-defaulted columns. Please iterate through
44 | // the original CRD object instead.
45 | func serveDefaultColumnsIfEmpty(columns []apiextensionsv1.CustomResourceColumnDefinition) []apiextensionsv1.CustomResourceColumnDefinition {
46 | if len(columns) > 0 {
47 | return columns
48 | }
49 | return []apiextensionsv1.CustomResourceColumnDefinition{
50 | {Name: "Age", Type: "date", Description: swaggerMetadataDescriptions["creationTimestamp"], JSONPath: ".metadata.creationTimestamp"},
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/cmd/kubezoo/app/options/globalflags.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 options
18 |
19 | import (
20 | "github.com/spf13/pflag"
21 | "k8s.io/component-base/cli/globalflag"
22 | // ensure libs have a chance to globally register their flags
23 | _ "k8s.io/apiserver/pkg/admission"
24 | _ "k8s.io/kubernetes/pkg/cloudprovider/providers"
25 | )
26 |
27 | // AddCustomGlobalFlags explicitly registers flags that internal packages register
28 | // against the global flagsets from "flag". We do this in order to prevent
29 | // unwanted flags from leaking into the kube-apiserver's flagset.
30 | func AddCustomGlobalFlags(fs *pflag.FlagSet) {
31 | // Lookup flags in global flag set and re-register the values with our flagset.
32 |
33 | // Adds flags from k8s.io/kubernetes/pkg/cloudprovider/providers.
34 | registerLegacyGlobalFlags(fs)
35 |
36 | // Adds flags from k8s.io/apiserver/pkg/admission.
37 | globalflag.Register(fs, "default-not-ready-toleration-seconds")
38 | globalflag.Register(fs, "default-unreachable-toleration-seconds")
39 | }
40 |
41 | func registerLegacyGlobalFlags(fs *pflag.FlagSet) {
42 | globalflag.Register(fs, "cloud-provider-gce-lb-src-cidrs")
43 | globalflag.Register(fs, "cloud-provider-gce-l7lb-src-cidrs")
44 | fs.MarkDeprecated("cloud-provider-gce-lb-src-cidrs", "This flag will be removed once the GCE Cloud Provider is removed from kube-apiserver")
45 | }
46 |
--------------------------------------------------------------------------------
/cmd/kubezoo/app/options/proxy.go:
--------------------------------------------------------------------------------
1 | package options
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/spf13/pflag"
7 | )
8 |
9 | // ProxyOptions runs a kubezoo proxy server
10 | type ProxyOptions struct {
11 | // ca, cert and key file to build secure connection between kubezoo and upstream cluster
12 | ProxyClientCAFile string
13 | ProxyClientCertFile string
14 | ProxyClientKeyFile string
15 |
16 | ProxyClientQPS float32
17 | ProxyClientBurst int
18 |
19 | ClientCAFile string
20 | ClientCAKeyFile string
21 | UpstreamMaster string
22 | ServiceAccountKeyFile string
23 | BindAddress string
24 | SecurePort int
25 | }
26 |
27 | // NewProxyOptions creates a new ProxyOptions object
28 | func NewProxyOptions() *ProxyOptions {
29 | return &ProxyOptions{
30 | ProxyClientQPS: 1000,
31 | ProxyClientBurst: 2000,
32 | SecurePort: 6443,
33 | }
34 | }
35 |
36 | func (o *ProxyOptions) AddFlags(fs *pflag.FlagSet) {
37 | if o == nil {
38 | return
39 | }
40 | fs.StringVar(&o.ProxyClientCAFile, "proxy-client-ca-file", o.ProxyClientCAFile, "proxy client ca file to verify upstream cluster apiserver.")
41 | fs.StringVar(&o.ProxyClientCertFile, "proxy-client-cert-file", o.ProxyClientCertFile, "proxy client cert file to prove the identity of kubezoo proxy "+
42 | "server to upstream cluster apiserver.")
43 | fs.StringVar(&o.ProxyClientKeyFile, "proxy-client-key-file", o.ProxyClientKeyFile, "proxy client key file to prove the identity of kubezoo proxy "+
44 | "server to upstream cluster apiserver.")
45 | fs.Float32Var(&o.ProxyClientQPS, "proxy-client-qps", o.ProxyClientQPS,
46 | fmt.Sprintf("the maximum QPS to the upstream cluster apiserver, default to %v", o.ProxyClientQPS))
47 | fs.IntVar(&o.ProxyClientBurst, "proxy-client-burst", o.ProxyClientBurst,
48 | fmt.Sprintf("the maximun burst for thorttle to the upstream cluster apiserver, default to %v", o.ProxyClientBurst))
49 | fs.StringVar(&o.UpstreamMaster, "proxy-upstream-master", o.UpstreamMaster, "upstream apiserver master address")
50 | fs.StringVar(&o.BindAddress, "proxy-bind-address", o.BindAddress, "The server address of the tenants' kubeconfig file, N.B. this address should be a valid server address of the client-ca-file.")
51 | fs.IntVar(&o.SecurePort, "proxy-secure-port", o.SecurePort, "The port on which the kubezoo used to serve HTTPS with authentication and authorization.")
52 | fs.StringVar(&o.ClientCAKeyFile, "client-ca-key-file", o.ClientCAKeyFile, "Filename containing a PEM-encoded RSA or ECDSA private key used to sign tenant certificates.")
53 | return
54 | }
55 |
56 | func (o *ProxyOptions) Validate() []error {
57 | if o == nil {
58 | return nil
59 | }
60 |
61 | errors := []error{}
62 |
63 | if len(o.ProxyClientCAFile) == 0 {
64 | errors = append(errors, fmt.Errorf("--proxy-client-ca-file cannot be empty"))
65 | }
66 | if len(o.ProxyClientKeyFile) == 0 {
67 | errors = append(errors, fmt.Errorf("--proxy-client-key-file cannot be empty"))
68 | }
69 | if len(o.ProxyClientCertFile) == 0 {
70 | errors = append(errors, fmt.Errorf("--proxy-client-cert-file cannot be empty"))
71 | }
72 | if len(o.ClientCAKeyFile) == 0 {
73 | errors = append(errors, fmt.Errorf("--client-ca-key-file cannot be empty"))
74 | }
75 | if len(o.ClientCAFile) == 0 {
76 | errors = append(errors, fmt.Errorf("--client-ca-file cannot be empty"))
77 | }
78 | if len(o.UpstreamMaster) == 0 {
79 | errors = append(errors, fmt.Errorf("--proxy-upstream-master cannot be empty"))
80 | }
81 | if len(o.BindAddress) == 0 {
82 | errors = append(errors, fmt.Errorf("--proxy-bind-address cannot be empty"))
83 | }
84 | if o.SecurePort < 1 || o.SecurePort > 65535 {
85 | errors = append(errors, fmt.Errorf("--proxy-secure-port %v must be between 1 and 65535, inclusive. It cannot be turned off with 0", o.SecurePort))
86 | }
87 | return errors
88 | }
89 |
--------------------------------------------------------------------------------
/cmd/kubezoo/main.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 | "math/rand"
21 | "os"
22 | "time"
23 |
24 | "k8s.io/component-base/logs"
25 | _ "k8s.io/component-base/metrics/prometheus/clientgo" // load all the prometheus client-go plugins
26 |
27 | "github.com/kubewharf/kubezoo/cmd/kubezoo/app"
28 | )
29 |
30 | func main() {
31 | rand.Seed(time.Now().UnixNano())
32 |
33 | command := app.NewAPIServerCommand()
34 |
35 | logs.InitLogs()
36 | defer logs.FlushLogs()
37 |
38 | if err := command.Execute(); err != nil {
39 | os.Exit(1)
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/config/setup/sample_tenant.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: tenant.kubezoo.io/v1alpha1
2 | kind: Tenant
3 | metadata:
4 | name: "111111"
5 | spec:
6 | id: 111111
7 | quota:
8 | hard:
9 | cpu: "2"
10 | memory: 2G
11 |
--------------------------------------------------------------------------------
/docs/design-cn.md:
--------------------------------------------------------------------------------
1 | # 设计文档
2 |
3 | ## 理念简介
4 |
5 | KubeZoo 基于`协议转换`核心理念实现控制面多租户功能,通过在资源的 name/namespace 等字段上增加租户的唯一标识
6 | ,解决不同租户的同名资源在同一个上游 Kubernetes 集群命名冲突的问题。
7 |
8 | 
9 |
10 | ## 架构概览
11 |
12 | 如下图所示,KubeZoo 是一个独立部署的服务,它由一个无状态的 kubezoo-server 进程和 etcd 组成,具备良好的横向扩展能力。
13 | 它对租户提供统一的 Kubernetes 访问入口,并将来自租户的请求经过协议转换后转发至上游的 Kubernetes 集群,进而由上游的集群真正完成资源的表达。
14 | 上游 Kubernetes 的控制面主要为 Master 和 Etcd,数据面建议由弹性容器(如 AWS Fargate, Aliyun ECI 等)实现,从而具备更强网络、存储隔离能力,如 VPC 等等。
15 |
16 | 
17 |
18 | - KubeZoo:由无状态的 kubezoo-server 和 Etcd 组成。
19 | - K8S Master:
20 | - Master:apiserver / scheduler / controller-manager / Etcd
21 | - Virtual Kubelet:衔接控制面和数据面,对接不同的公有云厂商弹性容器服务,最终完成 Master 中 Pod / Service 等资源的表达。
22 | - Container Instance Service:公有云弹性容器服务,如 AWS Fargate, Aliyun ECI 等等。
23 |
24 | ## 租户管理
25 |
26 | KubeZoo 内置 Tenant 对象,用于描述租户的基本信息,其中 name 是必须字段,全局唯一,长度固定 6 位字符串(包括字符或者数字),
27 | 理论上可以管理 2176782336 个租户(36 ^ 6),Tenant 对象存储于 KubeZoo 的 etcd 中,其格式如下:
28 | ````
29 | apiVersion: tenant.kubezoo.io/v1alpha1
30 | kind: Tenant
31 | metadata:
32 | name: "foofoo"
33 | annotations:
34 | ...... # add schema for tenant(optional)
35 | spec:
36 | id: 0
37 | ````
38 |
39 | KubeZoo 提供证书签发的功能,管理员拥有 Tenant 生命周期管理的能力。每当管理员创建租户后,即为该租户签发一份 X509 证书,
40 | 证书中包含了租户的信息,如名字等等,并写入 annotations;同时将每个租户内置的 namespace,rbac 等同步到上游的 Kubernetes 中。
41 |
42 | ````
43 | apiVersion: tenant.kubezoo.io/v1alpha1
44 | kind: Tenant
45 | metadata:
46 | name: "foofoo"
47 | annotations:
48 | kubezoo.io/tenant.kubeconfig.base64: YXBpVmVy...ExRbz0K
49 | ......
50 | spec:
51 | id: 0
52 | status: {}
53 | ````
54 |
55 | 每当管理员删除租户时,会触发租户资源回收,KubeZoo 删除上游 Kubernetes 该租户的所有资源,并清理 KubeZoo 侧的元信息。
56 | 由于租户的生命周期管理本质上是 Tenant 对象元信息的管理、证书签发和资源同步,其过程简洁,无需创建物理的 Master / Etcd 和计算资源池,
57 | 因而 KubeZoo 具备轻量级、秒级的海量租户生命周期管理能力。
58 |
59 | ## 协议转换
60 |
61 | ### Namespace Scope Resource
62 |
63 | Kubernetes 大概有 40 多种 namespace scope 的资源,比如 deployment / statefulset / pod / configmap 等。
64 | 通过在每个资源的 namespace 字段关联租户信息,从而实现 namespace scope 资源的多租户能力。
65 |
66 | 
67 |
68 | ### Cluster Scope Resource
69 |
70 | Kubernetes 大概有 20 多种 cluster scope 的资源,比如 pv / namespace / storageclass 等等。通过在 name 关联租户信息,
71 | 从而实现 cluster scope 资源的多租户能力。
72 |
73 | 
74 |
75 |
76 | ### Custom Resource
77 |
78 | Custom Resource Definition(CRD) 是一种特殊的 cluster scope 资源,其 name 由 group + plural 组成,
79 | 我们选择在 group 前缀关联租户信息。
80 |
81 | 
82 |
--------------------------------------------------------------------------------
/docs/developer-guide.md:
--------------------------------------------------------------------------------
1 | # Developer Guide
2 |
3 | There's a `Makefile` in the root folder. Here are some common options:
4 |
5 | Build KubeZoo binary `kube-zoo`
6 | ```bash
7 | make build
8 | ```
9 |
10 | Build for specific architecture. (`amd64`,`arm`,`arm64`)
11 | ```bash
12 | GOOS=linux GOARCH=arm64 make build
13 | ```
14 |
15 | Build all docker images for all supported architectures.
16 | ```bash
17 | make release
18 | ```
19 |
20 | Build all docker images for specific architecture.
21 | ```bash
22 | make release ARCH=arm64
23 | ```
24 |
25 | Build kubezoo-e2e-test binary to test KubeZoo.
26 | ```bash
27 | make e2e
28 | ```
29 |
30 | [Debug KubeZoo locally](./debug-kubezoo-locally.md)
31 |
--------------------------------------------------------------------------------
/docs/faq.md:
--------------------------------------------------------------------------------
1 | # FAQ
2 |
3 | - Does kubezoo have any other restrictions except for not supporting daemonset resources?
4 |
5 | > Kubezoo supports most of the resources such as pod, deployment and statefulset by default, while restrict the cluster sharing resources such as daemonset and node. The reason is that when multiple tenants share a cluster, no tenant is expected to sense and manipulate nodes(including daemonset) for security and isolation purpose.
6 |
7 | - Does kubezoo support RBAC for tenants?
8 |
9 | > Yes, kubezoo impersonates tenant identities through the impersonate mechanism, so the RBAC API is consistent with native API of kubernetes.
10 |
11 | - Does CRD share across the tenants?
12 |
13 | > KubeZoo divides CRD into two categories: one is tenant CRD which among tenants are completely isolated. The other is system CRD in a public cloud scenario, which will be handled by the same controller in the backend cluster. System CRD can be configured with a special policy to ensure that they are available to one or more tenants who can create objects.
14 |
15 | - What if pods of different tenants are deployed on the same Node and their performance affects each other?
16 |
17 | > In the public cloud scenario, we could implement the data plane through some services such as elastic container instance with higher isolation to ensure the complete isolation of computing, storage, and network resources.
18 |
19 | - Does kubezoo need a dedicated kubectl?
20 |
21 | > No, kubezoo supports the full kubernetes API, so each tenant could use kubectl exactly the same way as a single cluster.
22 |
23 | - What are the advantages and disadvantages of kubezoo and kubernetes's HNC?
24 |
25 | > The HNC solution implements a hierarchical namespace structure that is still evolving and has not yet become the standard API of kubernetes yet. The advantage of kubezoo is that it provides the standard kubernetes API. In other words, if HNC will be supported by the standard kubernetes API in the future, then every tenant of kubezoo will be able to use HNC.
26 |
27 | - What is the landing scene of kubezoo?
28 |
29 | > From the perspective of private cloud, many small service resources have small demands. However, if a cluster is independently maintained for these small services, the operation and resource costs are high. Therefore, private cloud has a clear scenario. In the public cloud scenario, most tenants need only a lit resources, so the construction of serverless kubernetes based on kubezoo has the advantages of high efficiency and low cost.
--------------------------------------------------------------------------------
/docs/faq.zh.md:
--------------------------------------------------------------------------------
1 | # FAQ
2 |
3 | - KubeZoo 除不支持 DaemonSet 资源外,还有其他的限制吗?
4 |
5 | > KubeZoo 默认支持 Pod、Deployment、Statefulset 等绝大部分资源,但是限制对 Daemonset 和 Node 等集群共享资源的支持,原因是若多个租户共享一个集群时,出于安全和隔离的要求,不期望任何一个租户感知和操作节点(包括 Daemonset)。
6 |
7 | - KubeZoo 支持租户的 RBAC 吗?
8 |
9 | > 支持,KubeZoo 通过 impersonate 机制模拟租户身份,故 RBAC API 与原生集群是一致的。
10 |
11 | - 不同租户创建的 CRD 能共用吗?
12 |
13 | > KubeZoo 把 CRD 分为两类: 一种是租户级别的 CRD,各个租户之间的 CRD 是完全隔离的。另一种是在公有云场景下提供系统级别的 CRD,在后端集群上会由同一个 Controller 进行处理。系统级别的 CRD 可以配置为一种特殊的策略,保证它对于某一个或某一些租户是开放的,这些租户可以创建系统级别的 CRD 的对象。
14 |
15 | - 不同租户的 Pod 部署到相同的 Node 上,性能互相影响怎么办?
16 |
17 | > 在公有云场景下,Pod 可能会通过一些隔离性更高的服务,如弹性容器实例等进行数据面的实现,进而保证计算、存储和网络等资源的彻底隔离。
18 |
19 | - KubeZoo 可以采用 kubectl 命令行吗,和原生是否有区别?
20 |
21 | > 没有区别。KubeZoo 可以支持完整的 Kubernetes 的 API 视图,故每一个租户用 Kubectl 跟单集群的方式完全一样。唯一的不同是 KubeZoo 会为租户单独签发证书,发送 Kubeconfig,用户只需要指定正确的 Kubeconfig 即可。
22 |
23 | - KubeZoo 和 Kubernetes 自己的多租户方案 HNC 比较有哪些优势和不足呢?
24 |
25 | > HNC 方案实现了一种层级化的 namespace 的结构,目前还在演进当中的,尚未成为 Kubernetes 的标准 API。KubeZoo 的优势在于它可以提供标准的 Kubernetes API。换而言之,若以后标准 Kubernetes API 也支持 HNC,那 KubeZoo 的每个租户也能使用 HNC,相当于 KubeZoo 是 HNC 能力的一个超集。
26 |
27 | - KubeZoo 的实际落地场景?
28 |
29 | > 从私有云视角来看,很多小的业务资源量诉求小,但若为这些小业务各自独立维护一个集群,则运维和资源成本高,故在私有云具备明确的场景;在公有云场景下,绝大部分的租户资源体量小,基于 KubeZoo 构建 serverless K8S 具备高效、底成本的优势。
--------------------------------------------------------------------------------
/docs/img/architecture-overview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubewharf/kubezoo/8a3a05f83cfe0576c24d896d898683001bd833e5/docs/img/architecture-overview.png
--------------------------------------------------------------------------------
/docs/img/bell-outline-badge.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubewharf/kubezoo/8a3a05f83cfe0576c24d896d898683001bd833e5/docs/img/bell-outline-badge.png
--------------------------------------------------------------------------------
/docs/img/cluster-scope-resource.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubewharf/kubezoo/8a3a05f83cfe0576c24d896d898683001bd833e5/docs/img/cluster-scope-resource.png
--------------------------------------------------------------------------------
/docs/img/comparison.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubewharf/kubezoo/8a3a05f83cfe0576c24d896d898683001bd833e5/docs/img/comparison.png
--------------------------------------------------------------------------------
/docs/img/custom-resource.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubewharf/kubezoo/8a3a05f83cfe0576c24d896d898683001bd833e5/docs/img/custom-resource.png
--------------------------------------------------------------------------------
/docs/img/design-ideas.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubewharf/kubezoo/8a3a05f83cfe0576c24d896d898683001bd833e5/docs/img/design-ideas.png
--------------------------------------------------------------------------------
/docs/img/kubezoo-overview-dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubewharf/kubezoo/8a3a05f83cfe0576c24d896d898683001bd833e5/docs/img/kubezoo-overview-dark.png
--------------------------------------------------------------------------------
/docs/img/kubezoo-overview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubewharf/kubezoo/8a3a05f83cfe0576c24d896d898683001bd833e5/docs/img/kubezoo-overview.png
--------------------------------------------------------------------------------
/docs/img/namespace-scope-resource.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubewharf/kubezoo/8a3a05f83cfe0576c24d896d898683001bd833e5/docs/img/namespace-scope-resource.png
--------------------------------------------------------------------------------
/docs/manually-setup-cn.md:
--------------------------------------------------------------------------------
1 | ## 快速开始
2 |
3 | 本文介绍如何在 Kubernetes 集群上部署 KubeZoo. 虽然 KubeZoo 可以对接任何标准的 Kubernetes 集群,但是作为样例,
4 | 本文会以 `kind` 集群作为上游集群.
5 |
6 | ### 前置条件
7 |
8 | 请安装最新版本的
9 | - [kind](https://kind.sigs.k8s.io/docs/user/quick-start/#installation)
10 | - [kubectl](https://kubernetes.io/docs/tasks/tools/)
11 | - [yq](https://github.com/mikefarah/yq#install)
12 | - [cfssl](https://github.com/cloudflare/cfssl#installation)
13 |
14 | ### 创建本地环境
15 | 通过运行下面的命令在本地构建 kubezoo 的环境
16 | ```console
17 | make local-up
18 | ```
19 |
20 | 当所有流程都准备就绪后,kubezoo 将运行在本地的 6443 端口,请确保该端口没有被别的程序占用,你会看到以下输出
21 | ```
22 | Export kubezoo server to 6443
23 | Forwarding from 127.0.0.1:6443 -> 6443
24 | Forwarding from [::1]:6443 -> 6443
25 | ```
26 |
27 | ### 访问 KubeZoo!
28 |
29 | ```console
30 | $ kubectl api-resources --context zoo
31 | NAME SHORTNAMES APIVERSION NAMESPACED KIND
32 | ...
33 | tenants tenant.kubezoo.io/v1alpha1 false Tenant
34 | ```
35 |
36 | ### 创建一个租户
37 |
38 | ```console
39 | $ kubectl apply -f config/setup/sample_tenant.yaml --context zoo
40 | tenant.tenant.kubezoo.io/111111 created
41 | ```
42 |
43 | 租户名称必须是有效的6字符[RFC 1123][rfc1123-label]DNS标签前缀(`[A-Za-z0-9][A-Za-z0-9\-]{5}`)。
44 |
45 | ### 获取租户的 kubeconfigs 文件
46 |
47 | ```console
48 | $ kubectl get tenant 111111 --context zoo -o jsonpath='{.metadata.annotations.kubezoo\.io\/tenant\.kubeconfig\.base64}' | base64 --decode > 111111.kubeconfig
49 | ```
50 |
51 | ### 以租户的身份创建一个 pod
52 |
53 | ```console
54 | $ kubectl apply --kubeconfig 111111.kubeconfig -f- < 6443
27 | Forwarding from [::1]:6443 -> 6443
28 | ```
29 |
30 | ### Connect to the KubeZoo!
31 |
32 | ```console
33 | $ kubectl api-resources --context zoo
34 | NAME SHORTNAMES APIVERSION NAMESPACED KIND
35 | ...
36 | tenants tenant.kubezoo.io/v1alpha1 false Tenant
37 | ```
38 |
39 | ### Create a tenant
40 |
41 | ```console
42 | $ kubectl apply -f config/setup/sample_tenant.yaml --context zoo
43 | tenant.tenant.kubezoo.io/111111 created
44 | ```
45 |
46 | The tenant name must be a valid 6-character [RFC 1123][rfc1123-label] DNS label prefix (`[A-Za-z0-9][A-Za-z0-9\-]{5}`).
47 |
48 | ### Get the kubeconfigs of the tenant
49 |
50 | ```console
51 | $ kubectl get tenant 111111 --context zoo -o jsonpath='{.metadata.annotations.kubezoo\.io\/tenant\.kubeconfig\.base64}' | base64 --decode > 111111.kubeconfig
52 | ```
53 |
54 | ### Create a pod as the tenant
55 |
56 | ```console
57 | $ kubectl apply --kubeconfig 111111.kubeconfig -f- </dev/null 2>&1 || (echo "$bin is not installed" && exit 0)
54 | done
55 | }
56 |
57 | local_up() {
58 | echo "Creating the kind cluster $CLUSTER_NAME..."
59 | if kind get clusters | grep "${CLUSTER_NAME}"; then
60 | cleanup
61 | else
62 | kind create cluster --name "${CLUSTER_NAME}"
63 | fi
64 | kubectl config use-context "kind-${CLUSTER_NAME}"
65 |
66 | echo "Generating PKI and context..."
67 | bash "${ZOO_ROOT}"/hack/lib/gen_pki.sh gen_pki_setup_ctx
68 |
69 | # echo "Loading image on $CLUSTER_NAME..."
70 | docker pull kubezoo/kubezoo:"${LOCAL_UP_IMAGE_TAG}"
71 | docker pull kubezoo/clusterresourcequota:"${LOCAL_UP_IMAGE_TAG}"
72 | docker tag kubezoo/kubezoo:"${LOCAL_UP_IMAGE_TAG}" kubezoo/kubezoo:local-up
73 | docker tag kubezoo/clusterresourcequota:"${LOCAL_UP_IMAGE_TAG}" kubezoo/clusterresourcequota:local-up
74 |
75 | echo "Setting up ClusterResourceQuota on $CLUSTER_NAME..."
76 | # run quota controller and webhook
77 | kubectl --context "kind-${CLUSTER_NAME}" apply -f $ZOO_ROOT/_output/setup/quota.yaml
78 | while ! kubectl --context "kind-${CLUSTER_NAME}" get clusterresourcequota; do
79 | echo ">> clusterresourcequota is not ready, sleep 1s"
80 | sleep 1s
81 | done
82 |
83 | echo "Setting up kubezoo on $CLUSTER_NAME..."
84 | kubectl apply -f $ZOO_ROOT/config/setup/all_in_one.yaml
85 |
86 | while ! (kubectl --context "kind-${CLUSTER_NAME}" get pods kubezoo-0 | grep "Running"); do
87 | echo ">> wait for kubezoo server running"
88 | sleep 1s
89 | done
90 |
91 | echo "Export kubezoo server to 6443"
92 | kubectl --context "kind-${CLUSTER_NAME}" port-forward svc/kubezoo 6443:6443
93 |
94 | }
95 |
96 | preflight
97 | local_up
98 |
--------------------------------------------------------------------------------
/pkg/apis/quota/install/zz.generated.install.go:
--------------------------------------------------------------------------------
1 | // +build !ignore_autogenerated
2 |
3 | /*
4 | Copyright 2020 The Bytedance Authors.
5 |
6 | Licensed under the Apache License, Version 2.0 (the "License");
7 | you may not use this file except in compliance with the License.
8 | You may obtain a copy of the License at
9 |
10 | http://www.apache.org/licenses/LICENSE-2.0
11 |
12 | Unless required by applicable law or agreed to in writing, software
13 | distributed under the License is distributed on an "AS IS" BASIS,
14 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | See the License for the specific language governing permissions and
16 | limitations under the License.
17 | */
18 |
19 | // Code generated by crd-gen. DO NOT EDIT.
20 |
21 | package install
22 |
23 | import (
24 | quotav1alpha1 "github.com/kubewharf/kubezoo/pkg/apis/quota/v1alpha1"
25 | runtime "k8s.io/apimachinery/pkg/runtime"
26 | utilruntime "k8s.io/apimachinery/pkg/util/runtime"
27 | )
28 |
29 | func Install(scheme *runtime.Scheme) {
30 | utilruntime.Must(quotav1alpha1.AddToScheme(scheme))
31 | }
32 |
--------------------------------------------------------------------------------
/pkg/apis/quota/v1alpha1/clusterresourcequota_defaults.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2020 The Bytedance 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 v1alpha1
18 |
19 | // EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
20 |
21 | // SetDefaults_ClusterResourceQuota set additional defaults compared to its counterpart
22 | // nolint:golint
23 | func SetDefaults_ClusterResourceQuota(obj *ClusterResourceQuota) {
24 | // ADD YOUR DEFAULTS HERE!
25 | }
26 |
--------------------------------------------------------------------------------
/pkg/apis/quota/v1alpha1/clusterresourcequota_hub.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2020 The Bytedance 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 v1alpha1
18 |
19 | import (
20 | "sigs.k8s.io/controller-runtime/pkg/conversion"
21 | )
22 |
23 | var _ conversion.Hub = &ClusterResourceQuota{}
24 |
25 | // Hub marks this type as a conversion hub
26 | func (*ClusterResourceQuota) Hub() {}
27 |
--------------------------------------------------------------------------------
/pkg/apis/quota/v1alpha1/clusterresourcequota_types.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2020 The Bytedance 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 v1alpha1
18 |
19 | import (
20 | corev1 "k8s.io/api/core/v1"
21 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
22 | )
23 |
24 | // EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
25 | // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
26 |
27 | // ClusterResourceQuotaSpec defines the desired state of ClusterResourceQuota
28 | type ClusterResourceQuotaSpec struct {
29 | corev1.ResourceQuotaSpec `json:",inline" protobuf:"bytes,1,opt,name=resourceQuotaSpec"`
30 | // A label query over a set of resources, in this case namespaces.
31 | // +optional
32 | NamepsaceSelector *metav1.LabelSelector `json:"namespaceSelector,omitempty" protobuf:"bytes,2,opt,name=namespaceSelector"`
33 | // namespaces specifies which namespaces the cluster resource quota applies to.
34 | // +optional
35 | Namespaces []string `json:"namespaces,omitempty" protobuf:"bytes,3,rep,name=namespaces"`
36 | }
37 |
38 | // ClusterResourceQuotaStatus defines the observed state of ClusterResourceQuota
39 | type ClusterResourceQuotaStatus struct {
40 | corev1.ResourceQuotaStatus `json:",inline" protobuf:"bytes,1,opt,name=resourceQuotaStatus"`
41 | }
42 |
43 | // +genclient
44 | // +genclient:nonNamespaced
45 | // +k8s:openapi-gen=true
46 | // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
47 | // +kubebuilder:object:root=true
48 | // +kubebuilder:subresource:status
49 | // +kubebuilder:resource:scope=Cluster
50 | // +kubebuilder:storageversion
51 |
52 | // ClusterResourceQuota is the Schema for the clusterresourcequota API
53 | type ClusterResourceQuota struct {
54 | metav1.TypeMeta `json:",inline"`
55 | metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
56 |
57 | Spec ClusterResourceQuotaSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
58 | Status ClusterResourceQuotaStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
59 | }
60 |
61 | // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
62 | // +kubebuilder:object:root=true
63 |
64 | // ClusterResourceQuotaList contains a list of ClusterResourceQuota
65 | type ClusterResourceQuotaList struct {
66 | metav1.TypeMeta `json:",inline"`
67 | metav1.ListMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
68 | Items []ClusterResourceQuota `json:"items" protobuf:"bytes,2,rep,name=items"`
69 | }
70 |
--------------------------------------------------------------------------------
/pkg/apis/quota/v1alpha1/doc.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2020 The Bytedance 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 | // +groupName=quota.kubezoo.io
18 | // +k8s:openapi-gen=true
19 | // +k8s:deepcopy-gen=package
20 | // +k8s:defaulter-gen=TypeMeta
21 | package v1alpha1
22 |
--------------------------------------------------------------------------------
/pkg/apis/quota/v1alpha1/generated.proto:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 | // This file was autogenerated by go-to-protobuf. Do not edit it manually!
18 |
19 | syntax = "proto2";
20 |
21 | package github.com.kubewharf.kubezoo.pkg.apis.quota.v1alpha1;
22 |
23 | import "k8s.io/api/core/v1/generated.proto";
24 | import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto";
25 | import "k8s.io/apimachinery/pkg/runtime/generated.proto";
26 | import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto";
27 |
28 | // Package-wide variables from generator "generated".
29 | option go_package = "github.com/kubewharf/kubezoo/pkg/apis/quota/v1alpha1";
30 |
31 | // ClusterResourceQuota is the Schema for the clusterresourcequota API
32 | message ClusterResourceQuota {
33 | optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
34 |
35 | optional ClusterResourceQuotaSpec spec = 2;
36 |
37 | optional ClusterResourceQuotaStatus status = 3;
38 | }
39 |
40 | // ClusterResourceQuotaList contains a list of ClusterResourceQuota
41 | message ClusterResourceQuotaList {
42 | optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
43 |
44 | repeated ClusterResourceQuota items = 2;
45 | }
46 |
47 | // ClusterResourceQuotaSpec defines the desired state of ClusterResourceQuota
48 | message ClusterResourceQuotaSpec {
49 | optional .k8s.io.api.core.v1.ResourceQuotaSpec resourceQuotaSpec = 1;
50 |
51 | // A label query over a set of resources, in this case namespaces.
52 | // +optional
53 | optional .k8s.io.apimachinery.pkg.apis.meta.v1.LabelSelector namespaceSelector = 2;
54 |
55 | // namespaces specifies which namespaces the cluster resource quota applies to.
56 | // +optional
57 | repeated string namespaces = 3;
58 | }
59 |
60 | // ClusterResourceQuotaStatus defines the observed state of ClusterResourceQuota
61 | message ClusterResourceQuotaStatus {
62 | optional .k8s.io.api.core.v1.ResourceQuotaStatus resourceQuotaStatus = 1;
63 | }
64 |
65 |
--------------------------------------------------------------------------------
/pkg/apis/quota/v1alpha1/well_known.go:
--------------------------------------------------------------------------------
1 | package v1alpha1
2 |
3 | const (
4 | ClusterResourceQuotaCreatedby = "clusterresourcequota.quota.kubezoo.io/createdby"
5 | )
6 |
--------------------------------------------------------------------------------
/pkg/apis/quota/v1alpha1/zz_generated.default.go:
--------------------------------------------------------------------------------
1 | //go:build !ignore_autogenerated
2 | // +build !ignore_autogenerated
3 |
4 | /*
5 | Copyright 2020 The Bytedance 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 patagonia. DO NOT EDIT.
21 |
22 | package v1alpha1
23 |
24 | import (
25 | "k8s.io/apimachinery/pkg/runtime"
26 | )
27 |
28 | func init() {
29 | localSchemeBuilder.Register(addDefaultingFuncs)
30 | }
31 |
32 | func addDefaultingFuncs(scheme *runtime.Scheme) error {
33 | return RegisterDefaults(scheme)
34 | }
35 |
--------------------------------------------------------------------------------
/pkg/apis/quota/v1alpha1/zz_generated.defaults.go:
--------------------------------------------------------------------------------
1 | //go:build !ignore_autogenerated
2 | // +build !ignore_autogenerated
3 |
4 | /*
5 | Copyright 2020 The Bytedance 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 v1alpha1
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(&ClusterResourceQuota{}, func(obj interface{}) { SetObjectDefaults_ClusterResourceQuota(obj.(*ClusterResourceQuota)) })
33 | scheme.AddTypeDefaultingFunc(&ClusterResourceQuotaList{}, func(obj interface{}) { SetObjectDefaults_ClusterResourceQuotaList(obj.(*ClusterResourceQuotaList)) })
34 | return nil
35 | }
36 |
37 | func SetObjectDefaults_ClusterResourceQuota(in *ClusterResourceQuota) {
38 | SetDefaults_ClusterResourceQuota(in)
39 | }
40 |
41 | func SetObjectDefaults_ClusterResourceQuotaList(in *ClusterResourceQuotaList) {
42 | for i := range in.Items {
43 | a := &in.Items[i]
44 | SetObjectDefaults_ClusterResourceQuota(a)
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/pkg/apis/quota/v1alpha1/zz_generated.register.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2020 The Bytedance 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 register-gen. DO NOT EDIT.
18 |
19 | package v1alpha1
20 |
21 | import (
22 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
23 | "k8s.io/apimachinery/pkg/runtime"
24 | "k8s.io/apimachinery/pkg/runtime/schema"
25 | )
26 |
27 | // GroupName specifies the group name used to register the objects.
28 | const GroupName = "quota.kubezoo.io"
29 |
30 | // GroupVersion specifies the group and the version used to register the objects.
31 | var GroupVersion = v1.GroupVersion{Group: GroupName, Version: "v1alpha1"}
32 |
33 | // SchemeGroupVersion is group version used to register these objects
34 | // Deprecated: use GroupVersion instead.
35 | var SchemeGroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha1"}
36 |
37 | // Resource takes an unqualified resource and returns a Group qualified GroupResource
38 | func Resource(resource string) schema.GroupResource {
39 | return SchemeGroupVersion.WithResource(resource).GroupResource()
40 | }
41 |
42 | var (
43 | // localSchemeBuilder and AddToScheme will stay in k8s.io/kubernetes.
44 | SchemeBuilder runtime.SchemeBuilder
45 | localSchemeBuilder = &SchemeBuilder
46 | // Depreciated: use Install instead
47 | AddToScheme = localSchemeBuilder.AddToScheme
48 | Install = localSchemeBuilder.AddToScheme
49 | )
50 |
51 | func init() {
52 | // We only register manually written functions here. The registration of the
53 | // generated functions takes place in the generated files. The separation
54 | // makes the code compile even when the generated files are missing.
55 | localSchemeBuilder.Register(addKnownTypes)
56 | }
57 |
58 | // Adds the list of known types to Scheme.
59 | func addKnownTypes(scheme *runtime.Scheme) error {
60 | scheme.AddKnownTypes(SchemeGroupVersion,
61 | &ClusterResourceQuota{},
62 | &ClusterResourceQuotaList{},
63 | )
64 | // AddToGroupVersion allows the serialization of client types like ListOptions.
65 | v1.AddToGroupVersion(scheme, SchemeGroupVersion)
66 | return nil
67 | }
68 |
--------------------------------------------------------------------------------
/pkg/apis/tenant/install/install.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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/kubernetes/pkg/api/legacyscheme"
23 |
24 | "github.com/kubewharf/kubezoo/pkg/apis/tenant/v1alpha1"
25 | )
26 |
27 | func init() {
28 | Install(legacyscheme.Scheme)
29 | }
30 |
31 | // Install registers the API group and adds types to a scheme
32 | func Install(scheme *runtime.Scheme) {
33 | utilruntime.Must(v1alpha1.AddToScheme(scheme))
34 | }
35 |
--------------------------------------------------------------------------------
/pkg/apis/tenant/v1alpha1/doc.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 | // Api versions allow the api contract for a resource to be changed while keeping
18 | // backward compatibility by support multiple concurrent versions
19 | // of the same resource
20 |
21 | // +k8s:openapi-gen=true
22 | // +k8s:deepcopy-gen=package,register
23 | // +k8s:conversion-gen=github.com/kubewharf/kubezoo/pkg
24 | // +k8s:defaulter-gen=TypeMeta
25 | // +groupName=tenant.kubezoo.io
26 | package v1alpha1 // import "github.com/kubewharf/kubezoo/pkg/apis/tenant/v1alpha1"
27 |
--------------------------------------------------------------------------------
/pkg/apis/tenant/v1alpha1/generated.proto:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 | // This file was autogenerated by go-to-protobuf. Do not edit it manually!
18 |
19 | syntax = "proto2";
20 |
21 | package github.com.kubewharf.kubezoo.pkg.apis.tenant.v1alpha1;
22 |
23 | import "k8s.io/api/core/v1/generated.proto";
24 | import "k8s.io/apimachinery/pkg/api/resource/generated.proto";
25 | import "k8s.io/apimachinery/pkg/apis/meta/v1/generated.proto";
26 | import "k8s.io/apimachinery/pkg/runtime/schema/generated.proto";
27 |
28 | // Package-wide variables from generator "generated".
29 | option go_package = "github.com/kubewharf/kubezoo/pkg/apis/tenant/v1alpha1";
30 |
31 | message Tenant {
32 | optional .k8s.io.apimachinery.pkg.apis.meta.v1.ObjectMeta metadata = 1;
33 |
34 | // `spec` is the specification of the desired behavior of a flow-schema.
35 | // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
36 | // +optional
37 | optional TenantSpec spec = 2;
38 |
39 | // `status` is the current status of a flow-schema.
40 | // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
41 | // +optional
42 | optional TenantStatus status = 3;
43 | }
44 |
45 | // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
46 | // TenantList is a list of Tenant objects.
47 | message TenantList {
48 | // `metadata` is the standard list metadata.
49 | // More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
50 | // +optional
51 | optional .k8s.io.apimachinery.pkg.apis.meta.v1.ListMeta metadata = 1;
52 |
53 | // `items` is a list of tenant
54 | // +listType=atomic
55 | repeated Tenant items = 2;
56 | }
57 |
58 | message TenantQuota {
59 | // hard is the set of desired hard limits for each named resource.
60 | // More info: https://kubernetes.io/docs/concepts/policy/resource-quotas/
61 | // +optional
62 | map hard = 1;
63 | }
64 |
65 | // TenantSpec describes how the proxy-rule's specification looks like.
66 | message TenantSpec {
67 | optional int32 id = 1;
68 |
69 | optional TenantQuota quota = 2;
70 | }
71 |
72 | // TenantStatus represents the current state of a rule.
73 | message TenantStatus {
74 | // Current state of tenant.
75 | optional bool online = 1;
76 | }
77 |
78 |
--------------------------------------------------------------------------------
/pkg/apis/tenant/v1alpha1/register.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 v1alpha1
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 | var SchemeGroupVersion = schema.GroupVersion{
26 | Group: "tenant.kubezoo.io",
27 | Version: "v1alpha1",
28 | }
29 | var AddToScheme = func(scheme *runtime.Scheme) error {
30 | metav1.AddToGroupVersion(scheme, schema.GroupVersion{
31 | Group: "tenant.kubezoo.io",
32 | Version: "v1alpha1",
33 | })
34 | scheme.AddKnownTypes(schema.GroupVersion{
35 | Group: "tenant.kubezoo.io",
36 | Version: "v1alpha1",
37 | }, &Tenant{}, &TenantList{})
38 |
39 | scheme.AddKnownTypes(schema.GroupVersion{
40 | Group: "tenant.kubezoo.io",
41 | Version: runtime.APIVersionInternal,
42 | }, &Tenant{}, &TenantList{})
43 |
44 | return nil
45 | }
46 |
47 | // Resource takes an unqualified resource and returns a Group qualified GroupResource
48 | func Resource(resource string) schema.GroupResource {
49 | return SchemeGroupVersion.WithResource(resource).GroupResource()
50 | }
51 |
--------------------------------------------------------------------------------
/pkg/clusterresourcequota/controllers/util.go:
--------------------------------------------------------------------------------
1 | // Copyright 2022 The KubeZoo 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 | package controllers
16 |
17 | import (
18 | "context"
19 | "fmt"
20 | "time"
21 |
22 | "k8s.io/apimachinery/pkg/api/equality"
23 | "k8s.io/apimachinery/pkg/util/wait"
24 | "k8s.io/client-go/util/retry"
25 | "sigs.k8s.io/controller-runtime/pkg/client"
26 | "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
27 | )
28 |
29 | // DefaultRetry is the recommended retry for a conflict where multiple clients
30 | // are making changes to the same resource.
31 | var DefaultRetry = wait.Backoff{
32 | Steps: 5,
33 | Duration: 10 * time.Millisecond,
34 | Factor: 1.0,
35 | Jitter: 0.1,
36 | }
37 |
38 | type Updater interface {
39 | Update(ctx context.Context, obj client.Object, opts ...client.UpdateOption) error
40 | }
41 |
42 | func UpdateOnConflict(
43 | ctx context.Context,
44 | backoff wait.Backoff,
45 | apiReader client.Reader,
46 | apiWriter Updater,
47 | obj client.Object,
48 | f controllerutil.MutateFn,
49 | ) (controllerutil.OperationResult, error) {
50 | key := client.ObjectKeyFromObject(obj)
51 | firstTry := true
52 | result := controllerutil.OperationResultNone
53 | err := retry.RetryOnConflict(
54 | backoff,
55 | func() error {
56 | if firstTry {
57 | firstTry = false
58 | } else {
59 | // refresh obj from apiserver
60 | if err := apiReader.Get(ctx, key, obj); err != nil {
61 | return err
62 | }
63 | }
64 | existing := obj.DeepCopyObject()
65 | if err := mutate(f, key, obj); err != nil {
66 | return err
67 | }
68 | if equality.Semantic.DeepEqual(existing, obj) {
69 | // unchanged, finish trying
70 | return nil
71 | }
72 | if err := apiWriter.Update(ctx, obj); err != nil {
73 | // maybe conflict
74 | return err
75 | }
76 | // updated
77 | result = controllerutil.OperationResultUpdated
78 | return nil
79 | },
80 | )
81 | if err != nil {
82 | return controllerutil.OperationResultNone, err
83 | }
84 | return result, nil
85 | }
86 |
87 | // mutate wraps a MutateFn and applies validation to its result
88 | func mutate(f controllerutil.MutateFn, key client.ObjectKey, obj client.Object) error {
89 | if err := f(); err != nil {
90 | return err
91 | }
92 | if newKey := client.ObjectKeyFromObject(obj); key != newKey {
93 | return fmt.Errorf("mutateFn cannot mutate object name and/or object namespace")
94 | }
95 | return nil
96 | }
97 |
--------------------------------------------------------------------------------
/pkg/common/const.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 common
18 |
19 | const (
20 | TenantNamespaceLabelKey = "kubezoo.io/tenant"
21 |
22 | TenantQuotaNamePrefix = "kubezoo-tenant-quota"
23 | )
24 |
--------------------------------------------------------------------------------
/pkg/common/convertor.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 common
18 |
19 | import (
20 | "k8s.io/apimachinery/pkg/runtime"
21 | )
22 |
23 | // ObjectConvertor converts object between tenant and upstream cluster
24 | type ObjectConvertor interface {
25 | ConvertTenantObjectToUpstreamObject(obj runtime.Object, tenantID string, isNamespaceScoped bool) error
26 | ConvertUpstreamObjectToTenantObject(obj runtime.Object, tenantID string, isNamespaceScoped bool) error
27 | }
28 |
--------------------------------------------------------------------------------
/pkg/common/reststorage.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 common
18 |
19 | import (
20 | "net/http"
21 | "net/url"
22 |
23 | "k8s.io/apimachinery/pkg/runtime"
24 | "k8s.io/apimachinery/pkg/runtime/schema"
25 | "k8s.io/apiserver/pkg/registry/rest"
26 |
27 | "github.com/kubewharf/kubezoo/pkg/dynamic"
28 | )
29 |
30 | type APIGroupConfig struct {
31 | Group string
32 | // the map is version to resource to storage config
33 | StorageConfigs map[string]map[string]*StorageConfig
34 | }
35 |
36 | type StorageConfig struct {
37 | Kind schema.GroupVersionKind
38 | Resource string
39 | Subresource string
40 | ShortNames []string
41 |
42 | NamespaceScoped bool
43 |
44 | IsCustomResource bool
45 |
46 | IsConnecter bool
47 |
48 | // NewFunc returns a new instance of the type this registry returns for a
49 | // GET of a single object, e.g.:
50 | //
51 | // curl GET /apis/group/version/namespaces/my-ns/myresource/name-of-object
52 | NewFunc func() runtime.Object
53 |
54 | // NewListFunc returns a new list of the type this registry; it is the
55 | // type returned when the resource is listed, e.g.:
56 | //
57 | // curl GET /apis/group/version/namespaces/my-ns/myresource
58 | NewListFunc func() runtime.Object
59 |
60 | // dynamic client is used to communicate with upstream cluster
61 | DynamicClient dynamic.Interface
62 |
63 | Convertor ObjectConvertor
64 |
65 | TableConvertor rest.TableConvertor
66 |
67 | ProxyTransport http.RoundTripper
68 | UpstreamMaster *url.URL
69 | GroupVersionKindFunc GroupVersionKindFunc
70 | }
71 |
72 | type GroupVersionKindFunc func(containingGV schema.GroupVersion) schema.GroupVersionKind
73 |
--------------------------------------------------------------------------------
/pkg/convert/clusterrole.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 convert
18 |
19 | import (
20 | "github.com/pkg/errors"
21 | "k8s.io/apimachinery/pkg/runtime"
22 | rbacinternal "k8s.io/kubernetes/pkg/apis/rbac"
23 |
24 | "github.com/kubewharf/kubezoo/pkg/util"
25 | )
26 |
27 | // ClusterRoleTransformer implements the transformation between
28 | // client and upstream server for ClusterRole resource.
29 | type ClusterRoleTransformer struct {
30 | listTenantCRDs ListTenantCRDsFunc
31 | }
32 |
33 | var _ ObjectTransformer = &ClusterRoleTransformer{}
34 |
35 | // NewClusterRoleTransformer initiates a ClusterRoleTransformer
36 | // which implements the ObjectTransformer interfaces.
37 | func NewClusterRoleTransformer(listTenantCRDs ListTenantCRDsFunc) ObjectTransformer {
38 | return &ClusterRoleTransformer{
39 | listTenantCRDs: listTenantCRDs,
40 | }
41 | }
42 |
43 | // Forward transforms tenant object reference to upstream object reference.
44 | func (t *ClusterRoleTransformer) Forward(obj runtime.Object, tenantID string) (runtime.Object, error) {
45 | clusterRole, ok := obj.(*rbacinternal.ClusterRole)
46 | if !ok {
47 | return nil, errors.New("failed to assert runtime.Object to internal version of ClusterRole")
48 | }
49 | if err := t.transformRuleList(clusterRole.Rules, tenantID, transformRuleToUpstream); err != nil {
50 | return nil, errors.Wrap(err, "failed to transform rule list to upstream")
51 | }
52 | return clusterRole, nil
53 | }
54 |
55 | // Backward transforms upstream object reference to tenant object reference.
56 | func (t *ClusterRoleTransformer) Backward(obj runtime.Object, tenantID string) (runtime.Object, error) {
57 | clusterRole, ok := obj.(*rbacinternal.ClusterRole)
58 | if !ok {
59 | return nil, errors.New("failed to assert runtime.Object to internal version of ClusterRole")
60 | }
61 | if err := t.transformRuleList(clusterRole.Rules, tenantID, transformRuleToTenant); err != nil {
62 | return nil, errors.Wrap(err, "failed to transform rule list to tenant")
63 | }
64 | return clusterRole, nil
65 | }
66 |
67 | // transformRuleList transform the cluster role policy rules between upstream server
68 | // and client side.
69 | func (t *ClusterRoleTransformer) transformRuleList(ruleList []rbacinternal.PolicyRule, tenantID string, transform ruleTransformFunc) error {
70 | if len(ruleList) == 0 {
71 | return nil
72 | }
73 | crdList, err := t.listTenantCRDs(tenantID)
74 | if err != nil {
75 | return err
76 | }
77 | grm := util.NewCustomGroupResourcesMap(crdList)
78 | for i := range ruleList {
79 | if err := transform(&ruleList[i], grm, tenantID); err != nil {
80 | return err
81 | }
82 | }
83 | return nil
84 | }
85 |
--------------------------------------------------------------------------------
/pkg/convert/clusterrolebinding.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 convert
18 |
19 | import (
20 | "strings"
21 |
22 | "github.com/pkg/errors"
23 | "k8s.io/apimachinery/pkg/runtime"
24 | rbacinternal "k8s.io/kubernetes/pkg/apis/rbac"
25 |
26 | "github.com/kubewharf/kubezoo/pkg/util"
27 | )
28 |
29 | // ClusterRoleBindingTransformer implements the transformation between
30 | // client and upstream server for ClusterRoleBinding resource.
31 | type ClusterRoleBindingTransformer struct{}
32 |
33 | var _ ObjectTransformer = &ClusterRoleBindingTransformer{}
34 |
35 | // NewClusterRoleBindingTransformer initiates a ClusterRoleBindingTransformer
36 | // which implements the ObjectTransformer interfaces.
37 | func NewClusterRoleBindingTransformer() ObjectTransformer {
38 | return &ClusterRoleBindingTransformer{}
39 | }
40 |
41 | // Forward transforms tenant object reference to upstream object reference.
42 | func (t *ClusterRoleBindingTransformer) Forward(obj runtime.Object, tenantID string) (runtime.Object, error) {
43 | crb, ok := obj.(*rbacinternal.ClusterRoleBinding)
44 | if !ok {
45 | return nil, errors.Errorf("fail to assert object to internal version of role")
46 | }
47 |
48 | if err := transformSubjectList(crb.Subjects, tenantID, transformSubjectToUpstream); err != nil {
49 | return nil, errors.WithMessagef(err, "failed to transform subjects to upstream for clusterRoleBinding %s", crb.Name)
50 | }
51 | if crb.RoleRef.Kind == "ClusterRole" && len(crb.RoleRef.Name) > 0 {
52 | crb.RoleRef.Name = util.AddTenantIDPrefix(tenantID, crb.RoleRef.Name)
53 | }
54 | return crb, nil
55 | }
56 |
57 | // Backward transforms upstream object reference to tenant object reference.
58 | func (t *ClusterRoleBindingTransformer) Backward(obj runtime.Object, tenantID string) (runtime.Object, error) {
59 | crb, ok := obj.(*rbacinternal.ClusterRoleBinding)
60 | if !ok {
61 | return nil, errors.Errorf("fail to assert object to internal version of role")
62 | }
63 | if err := transformSubjectList(crb.Subjects, tenantID, transformSubjectToTenant); err != nil {
64 | return nil, errors.WithMessagef(err, "failed to transform subjects to tenant for clusterRoleBinding %s", crb.Name)
65 | }
66 | if crb.RoleRef.Kind == "ClusterRole" {
67 | if !strings.HasPrefix(crb.RoleRef.Name, tenantID) {
68 | return nil, errors.Errorf("invalid roleRef name %s in clusterRoleBinding %s, tenant id is %s", crb.RoleRef.Name, crb.Name, tenantID)
69 | }
70 | crb.RoleRef.Name = util.TrimTenantIDPrefix(tenantID, crb.RoleRef.Name)
71 | }
72 | return crb, nil
73 | }
74 |
--------------------------------------------------------------------------------
/pkg/convert/cross-object.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 convert
18 |
19 | import (
20 | "k8s.io/apimachinery/pkg/runtime"
21 | "k8s.io/klog"
22 |
23 | "github.com/kubewharf/kubezoo/pkg/common"
24 | )
25 |
26 | // ObjectTransformer transforms tenant object to/from upstream object
27 | // NOTE for both Forward and Backward, the first input and ouput are either
28 | // unstructured or internal object.
29 | type ObjectTransformer interface {
30 | // Forward transforms the tenant object to the upstream object.
31 | Forward(obj runtime.Object, tenantID string) (runtime.Object, error)
32 | // Backward transforms the upstream object to the tenant object.
33 | Backward(obj runtime.Object, tenantID string) (runtime.Object, error)
34 | }
35 |
36 | // CrossReferenceConvertor implements the interfaces of ObjectConvertor and
37 | // ObjectTransformer to support the cross references cases such as
38 | // PersistenceVolume and PersistenceVolumeClaim.
39 | type CrossReferenceConvertor struct {
40 | defaultConverter common.ObjectConvertor
41 | objectTransformer ObjectTransformer
42 | }
43 |
44 | var _ common.ObjectConvertor = &CrossReferenceConvertor{}
45 |
46 | // convert spec.volumeName field
47 | func NewCrossReferenceConverter(c common.ObjectConvertor, objectTransformer ObjectTransformer) common.ObjectConvertor {
48 | return &CrossReferenceConvertor{defaultConverter: c, objectTransformer: objectTransformer}
49 | }
50 |
51 | // ConvertTenantObjectToUpstreamObject convert the tenant object to
52 | // upstream object.
53 | func (c *CrossReferenceConvertor) ConvertTenantObjectToUpstreamObject(obj runtime.Object, tenantID string, isNamespaceScoped bool) error {
54 | err := c.defaultConverter.ConvertTenantObjectToUpstreamObject(obj, tenantID, isNamespaceScoped)
55 | if err != nil {
56 | klog.Errorf("fail to convert tenant object to upstream object: %v", err)
57 | return err
58 | }
59 |
60 | // convert logic
61 | obj, err = c.objectTransformer.Forward(obj, tenantID)
62 | if err != nil {
63 | klog.Errorf("fail to convert tenant object to upstream object: %v", err)
64 | return err
65 | }
66 |
67 | return nil
68 | }
69 |
70 | // ConvertUpstreamObjectToTenantObject convert the upstream object to
71 | // tenant object.
72 | func (c *CrossReferenceConvertor) ConvertUpstreamObjectToTenantObject(obj runtime.Object, tenantID string, isNamespaceScoped bool) error {
73 | err := c.defaultConverter.ConvertUpstreamObjectToTenantObject(obj, tenantID, isNamespaceScoped)
74 | if err != nil {
75 | klog.Errorf("fail to convert upstream object to upstream object: %v", err)
76 | return err
77 | }
78 |
79 | // convert logic
80 | obj, err = c.objectTransformer.Backward(obj, tenantID)
81 | if err != nil {
82 | klog.Errorf("fail to convert upstream object to upstream object: %v", err)
83 | return err
84 | }
85 |
86 | return nil
87 | }
88 |
--------------------------------------------------------------------------------
/pkg/convert/customresource.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 convert
18 |
19 | import (
20 | "strings"
21 |
22 | "github.com/pkg/errors"
23 | "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
24 | "k8s.io/apimachinery/pkg/runtime"
25 |
26 | "github.com/kubewharf/kubezoo/pkg/util"
27 | )
28 |
29 | // CustomResourceTransformer implements the transformation between
30 | // client and upstream server for custom resource.
31 | type CustomResourceTransformer struct{}
32 |
33 | var _ ObjectTransformer = &CustomResourceTransformer{}
34 |
35 | // NewCustomResourceTransformer initiates a CustomResourceTransformer
36 | // which implements the ObjectTransformer interfaces.
37 | func NewCustomResourceTransformer() ObjectTransformer {
38 | return &CustomResourceTransformer{}
39 | }
40 |
41 | // Forward transforms tenant object reference to upstream object reference.
42 | func (t *CustomResourceTransformer) Forward(obj runtime.Object, tenantID string) (runtime.Object, error) {
43 | u, ok := obj.(*unstructured.Unstructured)
44 | if !ok {
45 | return nil, errors.New("fail to assert runtime object to the unstructured object")
46 | }
47 | groupVersion := u.GetAPIVersion()
48 | u.SetAPIVersion(util.AddTenantIDPrefix(tenantID, groupVersion))
49 | return u, nil
50 | }
51 |
52 | // Backward transforms upstream object reference to tenant object reference.
53 | func (t *CustomResourceTransformer) Backward(obj runtime.Object, tenantID string) (runtime.Object, error) {
54 | u, ok := obj.(*unstructured.Unstructured)
55 | if !ok {
56 | return nil, errors.New("fail to assert runtime object to the unstructured object")
57 | }
58 | groupVersion := u.GetAPIVersion()
59 | if !strings.HasPrefix(groupVersion, tenantID) {
60 | return nil, errors.Errorf("invalid apiVersion %s in cr %s, tenant id is %s", groupVersion, u.GetName(), tenantID)
61 | }
62 | u.SetAPIVersion(util.TrimTenantIDPrefix(tenantID, groupVersion))
63 | return u, nil
64 | }
65 |
--------------------------------------------------------------------------------
/pkg/convert/customresource_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 convert
18 |
19 | import (
20 | "testing"
21 |
22 | "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
23 |
24 | "github.com/kubewharf/kubezoo/pkg/util"
25 | )
26 |
27 | // TestCustomResourceTransformerForward tests the forward method of the
28 | // CustomResourceTransformer.
29 | func TestCustomResourceTransformerForward(t *testing.T) {
30 | tenant := "111111"
31 | apiVersion := "mygroup/v1"
32 |
33 | un := unstructured.Unstructured{}
34 | un.SetAPIVersion(apiVersion)
35 | un.SetKind("Mykind")
36 | un.SetNamespace("mynamespace")
37 | un.SetName("myname")
38 |
39 | c := NewCustomResourceTransformer()
40 | obj, err := c.Forward(&un, tenant)
41 | if err != nil {
42 | t.Errorf("Failed to forward with err %s", err)
43 | }
44 | newUn, ok := obj.(*unstructured.Unstructured)
45 | if !ok {
46 | t.Errorf("Failed to convert to unstructred.")
47 | }
48 | if newUn.GetAPIVersion() != tenant+util.TenantIDSeparator+apiVersion {
49 | t.Errorf("Unexpected api version.")
50 | }
51 | }
52 |
53 | // TestCustomResourceTransformerBackward tests the backward method of the
54 | // CustomResourceTransformer.
55 | func TestCustomResourceTransformerBackward(t *testing.T) {
56 | tenant := "111111"
57 | apiVersion := tenant + util.TenantIDSeparator + "mygroup/v1"
58 |
59 | un := unstructured.Unstructured{}
60 | un.SetAPIVersion(apiVersion)
61 | un.SetKind("Mykind")
62 | un.SetNamespace("mynamespace")
63 | un.SetName("myname")
64 |
65 | c := NewCustomResourceTransformer()
66 | obj, err := c.Backward(&un, tenant)
67 | if err != nil {
68 | t.Errorf("Failed to forward with err %s", err)
69 | }
70 | newUn, ok := obj.(*unstructured.Unstructured)
71 | if !ok {
72 | t.Errorf("Failed to convert to unstructred.")
73 | }
74 | if tenant+util.TenantIDSeparator+newUn.GetAPIVersion() != apiVersion {
75 | t.Errorf("Unexpected api version.")
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/pkg/convert/customresourcedefinition.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 convert
18 |
19 | import (
20 | "strings"
21 |
22 | "github.com/pkg/errors"
23 | crdinternal "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
24 | "k8s.io/apimachinery/pkg/runtime"
25 |
26 | "github.com/kubewharf/kubezoo/pkg/common"
27 | "github.com/kubewharf/kubezoo/pkg/util"
28 | )
29 |
30 | // CRDConvertor implements the transformation between client and
31 | // upstream server for CustomResourceDefinition resource.
32 | type CRDConvertor struct {
33 | ownerRefTransformer OwnerReferenceTransformer
34 | }
35 |
36 | var _ common.ObjectConvertor = &CRDConvertor{}
37 |
38 | // NewCRDConvertor initiates a CRDConvertor which implements the
39 | // ObjectConvertor interfaces.
40 | func NewCRDConvertor(ort OwnerReferenceTransformer) common.ObjectConvertor {
41 | return &CRDConvertor{
42 | ownerRefTransformer: ort,
43 | }
44 | }
45 |
46 | // ConvertTenantObjectToUpstreamObject convert the tenant object to
47 | // upstream object.
48 | func (t *CRDConvertor) ConvertTenantObjectToUpstreamObject(obj runtime.Object, tenantID string, isNamespaceScoped bool) error {
49 | crd, ok := obj.(*crdinternal.CustomResourceDefinition)
50 | if !ok {
51 | return errors.Errorf("fail to assert the runtime object to the internal version of crd")
52 | }
53 |
54 | if crd.Name != crd.Spec.Names.Plural+"."+crd.Spec.Group {
55 | return errors.Errorf("The CustomResourceDefinition \"%s\" is invalid: metadata.name: Invalid value: \"%s\": must be spec.names.plural+\".\"+spec.group",
56 | crd.Name, crd.Name)
57 | }
58 | crd.Spec.Group = util.AddTenantIDPrefix(tenantID, crd.Spec.Group)
59 | crd.Name = crd.Spec.Names.Plural + "." + crd.Spec.Group
60 | for i := range crd.OwnerReferences {
61 | target, err := t.ownerRefTransformer.Forward(&crd.OwnerReferences[i], tenantID)
62 | if err != nil {
63 | return err
64 | }
65 | crd.OwnerReferences[i] = *target
66 | }
67 | return nil
68 | }
69 |
70 | // ConvertUpstreamObjectToTenantObject convert the upstream object to
71 | // tenant object.
72 | func (t *CRDConvertor) ConvertUpstreamObjectToTenantObject(obj runtime.Object, tenantID string, isNamespaceScoped bool) error {
73 | crd, ok := obj.(*crdinternal.CustomResourceDefinition)
74 | if !ok {
75 | return errors.Errorf("fail to assert the runtime object to the internal version of crd")
76 | }
77 |
78 | if !strings.HasPrefix(crd.Spec.Group, tenantID) {
79 | return errors.Errorf("invalid spec.group %s for crd %s, tenant id is %s", crd.Spec.Group, crd.Name, tenantID)
80 | }
81 | crd.Spec.Group = util.TrimTenantIDPrefix(tenantID, crd.Spec.Group)
82 | crd.Name = crd.Spec.Names.Plural + "." + crd.Spec.Group
83 | for i := range crd.OwnerReferences {
84 | target, err := t.ownerRefTransformer.Backward(&crd.OwnerReferences[i], tenantID)
85 | if err != nil {
86 | return err
87 | }
88 | crd.OwnerReferences[i] = *target
89 | }
90 | return nil
91 | }
92 |
--------------------------------------------------------------------------------
/pkg/convert/default.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 convert
18 |
19 | import (
20 | "k8s.io/apimachinery/pkg/api/meta"
21 | "k8s.io/apimachinery/pkg/runtime"
22 |
23 | "github.com/kubewharf/kubezoo/pkg/common"
24 | "github.com/kubewharf/kubezoo/pkg/util"
25 | )
26 |
27 | // DefaultConvertor implements the transformation between
28 | // client and upstream server for generic default resource.
29 | type DefaultConvertor struct {
30 | ownerRefTransformer OwnerReferenceTransformer
31 | }
32 |
33 | var _ common.ObjectConvertor = &DefaultConvertor{}
34 |
35 | // NewDefaultConvertor initiates a DefaultConvertor which implements the
36 | // ObjectConvertor interfaces.
37 | func NewDefaultConvertor(ort OwnerReferenceTransformer) common.ObjectConvertor {
38 | return &DefaultConvertor{
39 | ownerRefTransformer: ort,
40 | }
41 | }
42 |
43 | // ConvertTenantObjectToUpstreamObject convert the tenant object to
44 | // upstream object.
45 | func (c *DefaultConvertor) ConvertTenantObjectToUpstreamObject(obj runtime.Object, tenantID string, isNamespaceScoped bool) error {
46 | accessor, err := meta.Accessor(obj)
47 | if err != nil {
48 | return err
49 | }
50 | if isNamespaceScoped && accessor.GetNamespace() != "" {
51 | prefixed := util.AddTenantIDPrefix(tenantID, accessor.GetNamespace())
52 | accessor.SetNamespace(prefixed)
53 | } else if !isNamespaceScoped && accessor.GetName() != "" {
54 | prefixed := util.AddTenantIDPrefix(tenantID, accessor.GetName())
55 | accessor.SetName(prefixed)
56 | }
57 | ownerReferences := accessor.GetOwnerReferences()
58 | for i := range ownerReferences {
59 | target, err := c.ownerRefTransformer.Forward(&ownerReferences[i], tenantID)
60 | if err != nil {
61 | return err
62 | }
63 | ownerReferences[i] = *target
64 | }
65 | accessor.SetOwnerReferences(ownerReferences)
66 | return nil
67 | }
68 |
69 | // ConvertUpstreamObjectToTenantObject convert the upstream object to
70 | // tenant object.
71 | func (c *DefaultConvertor) ConvertUpstreamObjectToTenantObject(obj runtime.Object, tenantID string, isNamespaceScoped bool) error {
72 | accessor, err := meta.Accessor(obj)
73 | if err != nil {
74 | return err
75 | }
76 | // some object may be valid to have empty name and namespace, such as TokenReview
77 | if isNamespaceScoped {
78 | namespace := accessor.GetNamespace()
79 | trimmed := util.TrimTenantIDPrefix(tenantID, namespace)
80 | accessor.SetNamespace(trimmed)
81 | } else {
82 | name := accessor.GetName()
83 | trimmed := util.TrimTenantIDPrefix(tenantID, name)
84 | accessor.SetName(trimmed)
85 | }
86 | ownerReferences := accessor.GetOwnerReferences()
87 | for i := range ownerReferences {
88 | target, err := c.ownerRefTransformer.Backward(&ownerReferences[i], tenantID)
89 | if err != nil {
90 | return err
91 | }
92 | ownerReferences[i] = *target
93 | }
94 | accessor.SetOwnerReferences(ownerReferences)
95 | return nil
96 | }
97 |
--------------------------------------------------------------------------------
/pkg/convert/endpoints.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 convert
18 |
19 | import (
20 | "github.com/pkg/errors"
21 |
22 | "k8s.io/apimachinery/pkg/runtime"
23 | internal "k8s.io/kubernetes/pkg/apis/core"
24 | )
25 |
26 | // EndpointsTransformer implements the transformation between
27 | // client and upstream server for Endpoints resource.
28 | type EndpointsTransformer struct {
29 | objectRefTransformer ObjectReferenceTransformer
30 | }
31 |
32 | var _ ObjectTransformer = &EndpointsTransformer{}
33 |
34 | // NewEndpointsTransformer initiates a EndpointsTransformer which implements the
35 | // ObjectTransformer interfaces.
36 | func NewEndpointsTransformer(ort ObjectReferenceTransformer) ObjectTransformer {
37 | return &EndpointsTransformer{
38 | objectRefTransformer: ort,
39 | }
40 | }
41 |
42 | // Forward transforms tenant object reference to upstream object reference.
43 | func (t *EndpointsTransformer) Forward(obj runtime.Object, tenantID string) (runtime.Object, error) {
44 | endpoints, ok := obj.(*internal.Endpoints)
45 | if !ok {
46 | return nil, errors.Errorf("failed to assert runtime object to internal version of endpoints")
47 | }
48 |
49 | for i := range endpoints.Subsets {
50 | for j := range endpoints.Subsets[i].Addresses {
51 | target, err := t.objectRefTransformer.Forward(endpoints.Subsets[i].Addresses[j].TargetRef, tenantID)
52 | if err != nil {
53 | return nil, err
54 | }
55 | endpoints.Subsets[i].Addresses[j].TargetRef = target
56 | }
57 | for j := range endpoints.Subsets[i].NotReadyAddresses {
58 | target, err := t.objectRefTransformer.Forward(endpoints.Subsets[i].NotReadyAddresses[j].TargetRef, tenantID)
59 | if err != nil {
60 | return nil, err
61 | }
62 | endpoints.Subsets[i].NotReadyAddresses[j].TargetRef = target
63 | }
64 | }
65 | return endpoints, nil
66 | }
67 |
68 | // Backward transforms upstream object reference to tenant object reference.
69 | func (t *EndpointsTransformer) Backward(obj runtime.Object, tenantID string) (runtime.Object, error) {
70 | endpoints, ok := obj.(*internal.Endpoints)
71 | if !ok {
72 | return nil, errors.Errorf("failed to assert runtime object to internal version of endpoints")
73 | }
74 | for i := range endpoints.Subsets {
75 | for j := range endpoints.Subsets[i].Addresses {
76 | target, err := t.objectRefTransformer.Backward(endpoints.Subsets[i].Addresses[j].TargetRef, tenantID)
77 | if err != nil {
78 | return nil, err
79 | }
80 | endpoints.Subsets[i].Addresses[j].TargetRef = target
81 | }
82 | for j := range endpoints.Subsets[i].NotReadyAddresses {
83 | target, err := t.objectRefTransformer.Backward(endpoints.Subsets[i].NotReadyAddresses[j].TargetRef, tenantID)
84 | if err != nil {
85 | return nil, err
86 | }
87 | endpoints.Subsets[i].NotReadyAddresses[j].TargetRef = target
88 | }
89 | }
90 | return endpoints, nil
91 | }
92 |
--------------------------------------------------------------------------------
/pkg/convert/endpointslice.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 convert
18 |
19 | import (
20 | "github.com/pkg/errors"
21 |
22 | "k8s.io/apimachinery/pkg/runtime"
23 | disinternal "k8s.io/kubernetes/pkg/apis/discovery"
24 | )
25 |
26 | // EndpointSliceTransformer implements the transformation between
27 | // client and upstream server for EndpointSlice resource.
28 | type EndpointSliceTransformer struct {
29 | objectRefTransformer ObjectReferenceTransformer
30 | }
31 |
32 | var _ ObjectTransformer = &EventTransformer{}
33 |
34 | // NewEndpointSliceTransformer initiates a EndpointSliceTransformer which
35 | // implements the ObjectTransformer interfaces.
36 | func NewEndpointSliceTransformer(ort ObjectReferenceTransformer) ObjectTransformer {
37 | return &EndpointSliceTransformer{
38 | objectRefTransformer: ort,
39 | }
40 | }
41 |
42 | // Forward transforms tenant object reference to upstream object reference.
43 | func (t *EndpointSliceTransformer) Forward(obj runtime.Object, tenantID string) (runtime.Object, error) {
44 | endpointSlice, ok := obj.(*disinternal.EndpointSlice)
45 | if !ok {
46 | return nil, errors.Errorf("fail to assert the runtime object to the internal version of endpointslice")
47 | }
48 |
49 | for i := range endpointSlice.Endpoints {
50 | target, err := t.objectRefTransformer.Forward(endpointSlice.Endpoints[i].TargetRef, tenantID)
51 | if err != nil {
52 | return nil, err
53 | }
54 | endpointSlice.Endpoints[i].TargetRef = target
55 | }
56 | return endpointSlice, nil
57 | }
58 |
59 | // Backward transforms upstream object reference to tenant object reference.
60 | func (t *EndpointSliceTransformer) Backward(obj runtime.Object, tenantID string) (runtime.Object, error) {
61 | endpointSlice, ok := obj.(*disinternal.EndpointSlice)
62 | if !ok {
63 | return nil, errors.Errorf("fail to assert the runtime object to the internal version of endpointslice")
64 | }
65 |
66 | for i := range endpointSlice.Endpoints {
67 | target, err := t.objectRefTransformer.Backward(endpointSlice.Endpoints[i].TargetRef, tenantID)
68 | if err != nil {
69 | return nil, err
70 | }
71 | endpointSlice.Endpoints[i].TargetRef = target
72 | }
73 | return endpointSlice, nil
74 | }
75 |
--------------------------------------------------------------------------------
/pkg/convert/event.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 convert
18 |
19 | import (
20 | "strings"
21 |
22 | "github.com/pkg/errors"
23 | "k8s.io/apimachinery/pkg/runtime"
24 | internal "k8s.io/kubernetes/pkg/apis/core"
25 | )
26 |
27 | // EventTransformer implements the transformation between
28 | // client and upstream server for Event resource.
29 | type EventTransformer struct {
30 | objectRefTransformer ObjectReferenceTransformer
31 | }
32 |
33 | var _ ObjectTransformer = &EventTransformer{}
34 |
35 | // NewEventTransformer initiates a EventTransformer which implements
36 | // the ObjectTransformer interfaces.
37 | func NewEventTransformer(ort ObjectReferenceTransformer) ObjectTransformer {
38 | return &EventTransformer{
39 | objectRefTransformer: ort,
40 | }
41 | }
42 |
43 | // Forward transforms tenant object reference to upstream object reference.
44 | func (t *EventTransformer) Forward(obj runtime.Object, tenantID string) (runtime.Object, error) {
45 | event, ok := obj.(*internal.Event)
46 | if !ok {
47 | return nil, errors.Errorf("fail to assert the runtime object to the internal version of event")
48 | }
49 |
50 | target, err := t.objectRefTransformer.Forward(&event.InvolvedObject, tenantID)
51 | if err != nil {
52 | return nil, err
53 | }
54 | event.InvolvedObject = *target
55 | return event, nil
56 | }
57 |
58 | // Backward transforms upstream object reference to tenant object reference.
59 | func (t *EventTransformer) Backward(obj runtime.Object, tenantID string) (runtime.Object, error) {
60 | event, ok := obj.(*internal.Event)
61 | if !ok {
62 | return nil, errors.Errorf("fail to assert the runtime object to the internal version of event")
63 | }
64 |
65 | target, err := t.objectRefTransformer.Backward(&event.InvolvedObject, tenantID)
66 | if err != nil {
67 | return nil, err
68 | }
69 | event.InvolvedObject = *target
70 | event.Message = strings.ReplaceAll(event.Message, tenantID+"-", "")
71 | return event, nil
72 | }
73 |
--------------------------------------------------------------------------------
/pkg/convert/init.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 convert
18 |
19 | import (
20 | "k8s.io/apimachinery/pkg/runtime/schema"
21 |
22 | "github.com/kubewharf/kubezoo/pkg/common"
23 | "github.com/kubewharf/kubezoo/pkg/util"
24 | )
25 |
26 | // InitConvertors initialize native convertor and custom convertor
27 | func InitConvertors(checkGroupKind util.CheckGroupKindFunc, listTenantCRDs ListTenantCRDsFunc) (nativeConvertor, customConvertor common.ObjectConvertor) {
28 | ownerReferenceTransformer := NewOwnerReferenceTransformer(checkGroupKind)
29 | objectReferenceTransformer := NewObjectReferenceTransformer(checkGroupKind)
30 | defaultConvertor := NewDefaultConvertor(ownerReferenceTransformer)
31 | nopeConvertor := NewNopeConvertor()
32 |
33 | nativeKindToConvertors := map[schema.GroupKind]common.ObjectConvertor{
34 | {
35 | Group: "",
36 | Kind: "Namespace",
37 | }: NewCrossReferenceConverter(defaultConvertor, NewNamespaceTransformer()),
38 | {
39 | Group: "",
40 | Kind: "Endpoints",
41 | }: NewCrossReferenceConverter(defaultConvertor, NewEndpointsTransformer(objectReferenceTransformer)),
42 | {
43 | Group: "discovery.k8s.io",
44 | Kind: "EndpointSlice",
45 | }: NewCrossReferenceConverter(defaultConvertor, NewEndpointSliceTransformer(objectReferenceTransformer)),
46 | {
47 | Group: "",
48 | Kind: "Event",
49 | }: NewCrossReferenceConverter(defaultConvertor, NewEventTransformer(objectReferenceTransformer)),
50 | {
51 | Group: "apiextensions.k8s.io",
52 | Kind: "CustomResourceDefinition",
53 | }: NewCRDConvertor(ownerReferenceTransformer),
54 | {
55 | Group: "",
56 | Kind: "PersistentVolumeClaim",
57 | }: defaultConvertor,
58 | {
59 | Group: "",
60 | Kind: "PersistentVolume",
61 | }: nopeConvertor,
62 | {
63 | Group: "storage.k8s.io",
64 | Kind: "VolumeAttachment",
65 | }: NewCrossReferenceConverter(defaultConvertor, NewVolumeAttachmentTransformer()),
66 | {
67 | Group: "rbac.authorization.k8s.io",
68 | Kind: "ClusterRole",
69 | }: NewCrossReferenceConverter(defaultConvertor, NewClusterRoleTransformer(listTenantCRDs)),
70 | {
71 | Group: "rbac.authorization.k8s.io",
72 | Kind: "ClusterRoleBinding",
73 | }: NewCrossReferenceConverter(defaultConvertor, NewClusterRoleBindingTransformer()),
74 | {
75 | Group: "rbac.authorization.k8s.io",
76 | Kind: "Role",
77 | }: NewCrossReferenceConverter(defaultConvertor, NewRoleTransformer(listTenantCRDs)),
78 | {
79 | Group: "rbac.authorization.k8s.io",
80 | Kind: "RoleBinding",
81 | }: NewCrossReferenceConverter(defaultConvertor, NewRoleBindingTransformer()),
82 | {
83 | Group: "authentication.k8s.io",
84 | Kind: "TokenReview",
85 | }: NewCrossReferenceConverter(defaultConvertor, NewTokenReviewTransformer()),
86 |
87 | // resources with nope convertor:
88 | {
89 | Group: "scheduling.k8s.io",
90 | Kind: "PriorityClass",
91 | }: nopeConvertor,
92 | {
93 | Group: "policy",
94 | Kind: "PodSecurityPolicy",
95 | }: nopeConvertor,
96 | {
97 | Group: "",
98 | Kind: "Node",
99 | }: nopeConvertor,
100 | }
101 | nativeConvertor = NewNativeObjectConvertor(defaultConvertor, nativeKindToConvertors)
102 | customConvertor = NewCrossReferenceConverter(defaultConvertor, NewCustomResourceTransformer())
103 | return nativeConvertor, customConvertor
104 | }
105 |
--------------------------------------------------------------------------------
/pkg/convert/init_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 convert
18 |
19 | import (
20 | "testing"
21 |
22 | v1 "k8s.io/api/core/v1"
23 | apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
24 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25 |
26 | "github.com/kubewharf/kubezoo/pkg/util"
27 | )
28 |
29 | // TestNativeObjectConvertorConvertTenantObjectToUpstreamObject tests the
30 | // ConvertTenantObjectToUpstreamObject methods of NativeObjectConvertor.
31 | func TestNativeObjectConvertorConvertTenantObjectToUpstreamObject(t *testing.T) {
32 | tenant := "111111"
33 | originName := "good"
34 | originNamespace := "luck"
35 |
36 | pod := v1.Pod{
37 | TypeMeta: metav1.TypeMeta{
38 | Kind: "Pod",
39 | APIVersion: "v1",
40 | },
41 | ObjectMeta: metav1.ObjectMeta{
42 | Name: originName,
43 | Namespace: originNamespace,
44 | },
45 | }
46 |
47 | c, _ := InitConvertors(checkGroupKind, FakeListEmptyTenantCRDsFunc)
48 | err := c.ConvertTenantObjectToUpstreamObject(&pod, tenant, true)
49 | if err != nil {
50 | t.Errorf("Failed to convert tenant object to upstream object")
51 | }
52 | if pod.GetNamespace() != tenant+util.TenantIDSeparator+originNamespace {
53 | t.Errorf("Unexpected namespace")
54 | }
55 | }
56 |
57 | // TestNativeObjectConvertorConvertUpstreamObjectToTenantObject tests the
58 | // ConvertUpstreamObjectToTenantObject methods of NativeObjectConvertor.
59 | func TestNativeObjectConvertorConvertUpstreamObjectToTenantObject(t *testing.T) {
60 | tenant := "111111"
61 | originName := "good"
62 | originNamespace := tenant + util.TenantIDSeparator + "luck"
63 |
64 | pod := v1.Pod{
65 | TypeMeta: metav1.TypeMeta{
66 | Kind: "Pod",
67 | APIVersion: "v1",
68 | },
69 | ObjectMeta: metav1.ObjectMeta{
70 | Name: originName,
71 | Namespace: originNamespace,
72 | },
73 | }
74 |
75 | c, _ := InitConvertors(checkGroupKind, FakeListEmptyTenantCRDsFunc)
76 | err := c.ConvertUpstreamObjectToTenantObject(&pod, tenant, true)
77 | if err != nil {
78 | t.Errorf("Failed to convert tenant object to upstream object")
79 | }
80 | if tenant+util.TenantIDSeparator+pod.GetNamespace() != originNamespace {
81 | t.Errorf("Unexpected namespace")
82 | }
83 | }
84 |
85 | func FakeListEmptyTenantCRDsFunc(tenantID string) ([]*apiextensionsv1.CustomResourceDefinition, error) {
86 | return []*apiextensionsv1.CustomResourceDefinition{}, nil
87 | }
88 |
--------------------------------------------------------------------------------
/pkg/convert/namespace.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 | package convert
17 |
18 | import (
19 | "github.com/kubewharf/kubezoo/pkg/common"
20 | "github.com/pkg/errors"
21 | "k8s.io/apimachinery/pkg/runtime"
22 | internal "k8s.io/kubernetes/pkg/apis/core"
23 | )
24 |
25 | type NamespaceTransformer struct {
26 | }
27 |
28 | var _ ObjectTransformer = &NamespaceTransformer{}
29 |
30 | func NewNamespaceTransformer() *NamespaceTransformer {
31 | return &NamespaceTransformer{}
32 | }
33 |
34 | func (t *NamespaceTransformer) Forward(obj runtime.Object, tenantID string) (runtime.Object, error) {
35 | ns, ok := obj.(*internal.Namespace)
36 | if !ok {
37 | return nil, errors.Errorf("fail to assert the runtime object to the internal version of namesapce")
38 | }
39 | if ns.Labels == nil {
40 | ns.Labels = map[string]string{}
41 | }
42 | if v, ok := ns.Labels[common.TenantNamespaceLabelKey]; ok && v != tenantID {
43 | return nil, errors.Errorf("namespace label %s is protected by kubezoo, can not be modified", common.TenantNamespaceLabelKey)
44 | } else {
45 | ns.Labels[common.TenantNamespaceLabelKey] = tenantID
46 | }
47 | return ns, nil
48 | }
49 |
50 | func (t *NamespaceTransformer) Backward(obj runtime.Object, tenantID string) (runtime.Object, error) {
51 | return obj, nil
52 | }
53 |
--------------------------------------------------------------------------------
/pkg/convert/nativeresource.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 convert
18 |
19 | import (
20 | "k8s.io/apimachinery/pkg/runtime"
21 | "k8s.io/apimachinery/pkg/runtime/schema"
22 |
23 | "github.com/kubewharf/kubezoo/pkg/common"
24 | )
25 |
26 | // nativeObjectConvertor implements the transformation between
27 | // client and upstream server for native resource.
28 | type nativeObjectConvertor struct {
29 | defaultConvertor common.ObjectConvertor
30 | nativeKindToConvertors map[schema.GroupKind]common.ObjectConvertor
31 | }
32 |
33 | // NewNativeObjectConvertor initiates a nativeObjectConvertor which implements
34 | // the ObjectConvertor interfaces.
35 | func NewNativeObjectConvertor(defaultConvertor common.ObjectConvertor,
36 | kindToConvertors map[schema.GroupKind]common.ObjectConvertor) common.ObjectConvertor {
37 | return &nativeObjectConvertor{
38 | defaultConvertor: defaultConvertor,
39 | nativeKindToConvertors: kindToConvertors,
40 | }
41 | }
42 |
43 | // ConvertTenantObjectToUpstreamObject convert the tenant object to
44 | // upstream object.
45 | func (c *nativeObjectConvertor) ConvertTenantObjectToUpstreamObject(obj runtime.Object, tenantID string, isNamespaceScoped bool) error {
46 | convertor := c.nativeKindToConvertors[obj.GetObjectKind().GroupVersionKind().GroupKind()]
47 | if convertor == nil {
48 | convertor = c.defaultConvertor
49 | }
50 | return convertor.ConvertTenantObjectToUpstreamObject(obj, tenantID, isNamespaceScoped)
51 | }
52 |
53 | // ConvertUpstreamObjectToTenantObject convert the upstream object to
54 | // tenant object.
55 | func (c *nativeObjectConvertor) ConvertUpstreamObjectToTenantObject(obj runtime.Object, tenantID string, isNamespaceScoped bool) error {
56 | convertor := c.nativeKindToConvertors[obj.GetObjectKind().GroupVersionKind().GroupKind()]
57 | if convertor == nil {
58 | convertor = c.defaultConvertor
59 | }
60 | return convertor.ConvertUpstreamObjectToTenantObject(obj, tenantID, isNamespaceScoped)
61 | }
62 |
--------------------------------------------------------------------------------
/pkg/convert/nope.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 convert
18 |
19 | import (
20 | "k8s.io/apimachinery/pkg/runtime"
21 |
22 | "github.com/kubewharf/kubezoo/pkg/common"
23 | )
24 |
25 | // NopeConvertor converts nothing
26 | type NopeConvertor struct{}
27 |
28 | var _ common.ObjectConvertor = &NopeConvertor{}
29 |
30 | // NewNopeConvertor returns a NopeConvertor to convert nothing.
31 | func NewNopeConvertor() common.ObjectConvertor {
32 | return &NopeConvertor{}
33 | }
34 |
35 | // ConvertTenantObjectToUpstreamObject of NopeConvertor does nothing.
36 | func (c *NopeConvertor) ConvertTenantObjectToUpstreamObject(obj runtime.Object, tenantID string, isNamespaceScoped bool) error {
37 | return nil
38 | }
39 |
40 | // ConvertUpstreamObjectToTenantObject of NopeConvertor does nothing.
41 | func (c *NopeConvertor) ConvertUpstreamObjectToTenantObject(obj runtime.Object, tenantID string, isNamespaceScoped bool) error {
42 | return nil
43 | }
44 |
--------------------------------------------------------------------------------
/pkg/convert/objectreference_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 convert
18 |
19 | import (
20 | "testing"
21 |
22 | "github.com/go-test/deep"
23 | internal "k8s.io/kubernetes/pkg/apis/core"
24 | )
25 |
26 | var (
27 | tenantObjectReferences = []*internal.ObjectReference{
28 | &internal.ObjectReference{
29 | APIVersion: "apps/v1",
30 | Kind: "Deployment",
31 | Namespace: "default",
32 | Name: "dp-92a152bd69",
33 | UID: "bd081382-4015-11eb-9d00-b8599fe021ac",
34 | ResourceVersion: "sdfefef",
35 | },
36 | &internal.ObjectReference{
37 | APIVersion: "v1",
38 | Kind: "Namespace",
39 | Name: "default",
40 | UID: "da0f337b-98ca-446d-96d6-25dc3ff1ddcc",
41 | ResourceVersion: "sdfdefef",
42 | },
43 | }
44 | upstreamObjectReferences = []*internal.ObjectReference{
45 | &internal.ObjectReference{
46 | APIVersion: "apps/v1",
47 | Kind: "Deployment",
48 | Namespace: "test01-default",
49 | Name: "dp-92a152bd69",
50 | UID: "bd081382-4015-11eb-9d00-b8599fe021ac",
51 | ResourceVersion: "sdfefef",
52 | },
53 | &internal.ObjectReference{
54 | APIVersion: "v1",
55 | Kind: "Namespace",
56 | Name: "test01-default",
57 | UID: "da0f337b-98ca-446d-96d6-25dc3ff1ddcc",
58 | ResourceVersion: "sdfdefef",
59 | },
60 | }
61 | )
62 |
63 | // TestObjectReferenceTransformer_Forward tests the forward method of the
64 | // ObjectReferenceTransformer.
65 | func TestObjectReferenceTransformer_Forward(t *testing.T) {
66 | transformer := NewObjectReferenceTransformer(checkGroupKind)
67 | for i := range tenantObjectReferences {
68 | got, err := transformer.Forward(tenantObjectReferences[i].DeepCopy(), tenantID)
69 | if err != nil {
70 | t.Errorf("failed to transform tenant object reference: %+v, err: %v", *tenantObjectReferences[i], err)
71 | }
72 | if diff := deep.Equal(got, upstreamObjectReferences[i]); diff != nil {
73 | t.Error(diff)
74 | }
75 | }
76 | }
77 |
78 | // TestObjectReferenceTransformer_Backward tests the backward method of the
79 | // ObjectReferenceTransformer.
80 | func TestObjectReferenceTransformer_Backward(t *testing.T) {
81 | transformer := NewObjectReferenceTransformer(checkGroupKind)
82 | for i := range upstreamObjectReferences {
83 | got, err := transformer.Backward(upstreamObjectReferences[i].DeepCopy(), tenantID)
84 | if err != nil {
85 | t.Errorf("failed to transform upstream object reference: %+v, err: %v", *upstreamObjectReferences[i], err)
86 | }
87 | if diff := deep.Equal(got, tenantObjectReferences[i]); diff != nil {
88 | t.Error(diff)
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/pkg/convert/ownerreference.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 convert
18 |
19 | import (
20 | "fmt"
21 | "strings"
22 |
23 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24 | "k8s.io/apimachinery/pkg/runtime/schema"
25 |
26 | "github.com/kubewharf/kubezoo/pkg/util"
27 | )
28 |
29 | // OwnerReferenceTransformer transforms tenant owner reference to/from upstream owner reference
30 | type OwnerReferenceTransformer interface {
31 | // Forward transforms tenant owner reference to upstream owner reference
32 | Forward(or *metav1.OwnerReference, tenantID string) (*metav1.OwnerReference, error)
33 | // Backward transforms upstream owner reference to tenant owner reference
34 | Backward(or *metav1.OwnerReference, tenantID string) (*metav1.OwnerReference, error)
35 | }
36 |
37 | type ownerReferenceTransformer struct {
38 | checkGroupKind util.CheckGroupKindFunc
39 | }
40 |
41 | // NewOwnerReferenceTransformer returns a new OwnerReferenceTransformer
42 | func NewOwnerReferenceTransformer(checkGroupKind util.CheckGroupKindFunc) OwnerReferenceTransformer {
43 | return &ownerReferenceTransformer{checkGroupKind: checkGroupKind}
44 | }
45 |
46 | // Forward transforms tenant owner reference to upstream owner reference.
47 | func (t *ownerReferenceTransformer) Forward(or *metav1.OwnerReference, tenantID string) (*metav1.OwnerReference, error) {
48 | if or == nil {
49 | return nil, nil
50 | }
51 | gv, err := schema.ParseGroupVersion(or.APIVersion)
52 | if err != nil {
53 | return nil, err
54 | }
55 |
56 | namespaced, customResourceGroup, err := t.checkGroupKind(gv.Group, or.Kind, tenantID, true)
57 | if err != nil {
58 | return nil, err
59 | }
60 | if !namespaced && len(or.Name) != 0 {
61 | or.Name = util.AddTenantIDPrefix(tenantID, or.Name)
62 | }
63 | if customResourceGroup && len(or.APIVersion) != 0 {
64 | or.APIVersion = util.AddTenantIDPrefix(tenantID, or.APIVersion)
65 | }
66 | return or, nil
67 | }
68 |
69 | // Backward transforms upstream owner reference to tenant owner reference
70 | func (t *ownerReferenceTransformer) Backward(or *metav1.OwnerReference, tenantID string) (*metav1.OwnerReference, error) {
71 | if or == nil {
72 | return nil, nil
73 | }
74 | gv, err := schema.ParseGroupVersion(or.APIVersion)
75 | if err != nil {
76 | return nil, err
77 | }
78 |
79 | namespaced, customResourceGroup, err := t.checkGroupKind(gv.Group, or.Kind, tenantID, true)
80 | if err != nil {
81 | return nil, err
82 | }
83 | if !namespaced {
84 | // if !strings.HasPrefix(or.Name, tenantID) {
85 | // return nil, fmt.Errorf("ownerReference: %+v, name: %s must have tenantID prefix: %s", or, or.Name, tenantID)
86 | // }
87 | or.Name = util.TrimTenantIDPrefix(tenantID, or.Name)
88 | }
89 | if customResourceGroup {
90 | if !strings.HasPrefix(or.APIVersion, tenantID) {
91 | return nil, fmt.Errorf("ownerReference: %+v, apiVersion: %s must have tenantID prefix: %s", or, or.Name, tenantID)
92 | }
93 | or.APIVersion = util.TrimTenantIDPrefix(tenantID, or.APIVersion)
94 | }
95 | return or, nil
96 | }
97 |
--------------------------------------------------------------------------------
/pkg/convert/ownerreference_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 convert
18 |
19 | import (
20 | "github.com/go-test/deep"
21 | "github.com/kubewharf/kubezoo/pkg/util"
22 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
23 | "testing"
24 | )
25 |
26 | // checkGroupKind checks whether NATIVE group/kind is namespaced, which means customResourceGroup is always false.
27 | // It is only used for build unit tests
28 | func checkGroupKind(group, kind, tenantID string, isTenantObject bool) (namespaced, customResourceGroup bool, err error) {
29 | namespaced, err = util.IsGroupKindNamespaced(metav1.GroupKind{Group: group, Kind: kind})
30 | return
31 | }
32 |
33 | var (
34 | tenantID = "test01"
35 | tenantOwnerReferences = []*metav1.OwnerReference{
36 | &metav1.OwnerReference{
37 | APIVersion: "apps/v1",
38 | Kind: "Deployment",
39 | Name: "dp-92a152bd69",
40 | UID: "bd081382-4015-11eb-9d00-b8599fe021ac",
41 | },
42 | &metav1.OwnerReference{
43 | APIVersion: "v1",
44 | Kind: "Namespace",
45 | Name: "default",
46 | UID: "da0f337b-98ca-446d-96d6-25dc3ff1ddcc",
47 | },
48 | }
49 | upstreamOwnerReferences = []*metav1.OwnerReference{
50 | &metav1.OwnerReference{
51 | APIVersion: "apps/v1",
52 | Kind: "Deployment",
53 | Name: "dp-92a152bd69",
54 | UID: "bd081382-4015-11eb-9d00-b8599fe021ac",
55 | },
56 | &metav1.OwnerReference{
57 | APIVersion: "v1",
58 | Kind: "Namespace",
59 | Name: "test01-default",
60 | UID: "da0f337b-98ca-446d-96d6-25dc3ff1ddcc",
61 | },
62 | }
63 | )
64 |
65 | // TestOwnerReferenceTransformer_Forward tests the forward method of the
66 | // OwnerReferenceTransformer.
67 | func TestOwnerReferenceTransformer_Forward(t *testing.T) {
68 | transformer := NewOwnerReferenceTransformer(checkGroupKind)
69 | for i := range tenantOwnerReferences {
70 | got, err := transformer.Forward(tenantOwnerReferences[i].DeepCopy(), tenantID)
71 | if err != nil {
72 | t.Errorf("failed to transform tenant owner reference: %+v, err: %v", *tenantOwnerReferences[i], err)
73 | }
74 | if diff := deep.Equal(got, upstreamOwnerReferences[i]); diff != nil {
75 | t.Error(diff)
76 | }
77 | }
78 | }
79 |
80 | // TestOwnerReferenceTransformer_Backward tests the backward method of the
81 | // OwnerReferenceTransformer.
82 | func TestOwnerReferenceTransformer_Backward(t *testing.T) {
83 | transformer := NewOwnerReferenceTransformer(checkGroupKind)
84 | for i := range upstreamOwnerReferences {
85 | got, err := transformer.Backward(upstreamOwnerReferences[i].DeepCopy(), tenantID)
86 | if err != nil {
87 | t.Errorf("failed to transform upstream owner reference: %+v, err: %v", *upstreamOwnerReferences[i], err)
88 | }
89 | if diff := deep.Equal(got, tenantOwnerReferences[i]); diff != nil {
90 | t.Error(diff)
91 | }
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/pkg/convert/pv.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 convert
18 |
19 | import (
20 | "strings"
21 |
22 | "github.com/pkg/errors"
23 | "k8s.io/apimachinery/pkg/runtime"
24 | internal "k8s.io/kubernetes/pkg/apis/core"
25 |
26 | "github.com/kubewharf/kubezoo/pkg/util"
27 | )
28 |
29 | // PVTranformer implements the transformation between client and
30 | // upstream server for PersistenceVolume resource.
31 | type PVTranformer struct{}
32 |
33 | var _ ObjectTransformer = &PVTranformer{}
34 |
35 | // NewPVTransformer initiates a PVTranformer which implements
36 | // the ObjectTransformer interfaces.
37 | func NewPVTransformer() ObjectTransformer {
38 | return &PVTranformer{}
39 | }
40 |
41 | // Forward transforms tenant object reference to upstream object reference.
42 | func (v *PVTranformer) Forward(obj runtime.Object, tenantID string) (runtime.Object, error) {
43 | // convert logic
44 | pv, ok := obj.(*internal.PersistentVolume)
45 | if !ok {
46 | return nil, errors.Errorf("fail to assert the runtime object to the internal version of persistentvolume")
47 | }
48 |
49 | if pv.Spec.ClaimRef != nil && len(pv.Spec.ClaimRef.Namespace) > 0 {
50 | pv.Spec.ClaimRef.Namespace = util.AddTenantIDPrefix(tenantID, pv.Spec.ClaimRef.Namespace)
51 | }
52 | return pv, nil
53 | }
54 |
55 | // Backward transforms upstream object reference to tenant object reference.
56 | func (v *PVTranformer) Backward(obj runtime.Object, tenantID string) (runtime.Object, error) {
57 | pv, ok := obj.(*internal.PersistentVolume)
58 | if !ok {
59 | return nil, errors.Errorf("fail to assert the runtime object to the internal version of persistentvolume")
60 | }
61 |
62 | if pv.Spec.ClaimRef != nil && len(pv.Spec.ClaimRef.Namespace) > 0 {
63 | if !strings.HasPrefix(pv.Spec.ClaimRef.Namespace, tenantID) {
64 | return nil, errors.Errorf("invalid namespace %s in pv %s claim ref, tenant id is %s", pv.Spec.ClaimRef.Namespace, pv.Name, tenantID)
65 | }
66 | pv.Spec.ClaimRef.Namespace = util.TrimTenantIDPrefix(tenantID, pv.Spec.ClaimRef.Namespace)
67 | }
68 |
69 | return pv, nil
70 | }
71 |
--------------------------------------------------------------------------------
/pkg/convert/pvc.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 convert
18 |
19 | import (
20 | "strings"
21 |
22 | "github.com/kubewharf/kubezoo/pkg/util"
23 |
24 | "github.com/pkg/errors"
25 |
26 | "k8s.io/apimachinery/pkg/runtime"
27 | internal "k8s.io/kubernetes/pkg/apis/core"
28 | )
29 |
30 | // PVCTranformer implements the transformation between client and
31 | // upstream server for PersistenceVolumeClaim resource.
32 | type PVCTranformer struct{}
33 |
34 | var _ ObjectTransformer = &PVCTranformer{}
35 |
36 | // NewPVCTransformer initiates a PVCTranformer which implements
37 | // the ObjectTransformer interfaces.
38 | func NewPVCTransformer() ObjectTransformer {
39 | return &PVCTranformer{}
40 | }
41 |
42 | // Forward transforms tenant object reference to upstream object reference.
43 | func (v *PVCTranformer) Forward(obj runtime.Object, tenantID string) (runtime.Object, error) {
44 | pvc, ok := obj.(*internal.PersistentVolumeClaim)
45 | if !ok {
46 | return nil, errors.Errorf("fail to assert the runtime object to the internal version of persistentvolumeclaim")
47 | }
48 | if len(pvc.Spec.VolumeName) > 0 {
49 | pvc.Spec.VolumeName = util.AddTenantIDPrefix(tenantID, pvc.Spec.VolumeName)
50 | }
51 |
52 | return pvc, nil
53 | }
54 |
55 | // Backward transforms upstream object reference to tenant object reference.
56 | func (v *PVCTranformer) Backward(obj runtime.Object, tenantID string) (runtime.Object, error) {
57 | pvc, ok := obj.(*internal.PersistentVolumeClaim)
58 | if !ok {
59 | return nil, errors.Errorf("fail to assert the runtime object to the internal version of persistentvolumeclaim")
60 | }
61 | if len(pvc.Spec.VolumeName) > 0 {
62 | if !strings.HasPrefix(pvc.Spec.VolumeName, tenantID) {
63 | return nil, errors.Errorf("invalid pv name %s in pvc %s, tenant id is %s", pvc.Spec.VolumeName, pvc.Spec.VolumeName, tenantID)
64 | }
65 | pvc.Spec.VolumeName = util.TrimTenantIDPrefix(tenantID, pvc.Spec.VolumeName)
66 | }
67 |
68 | return pvc, nil
69 | }
70 |
--------------------------------------------------------------------------------
/pkg/convert/tokenreview.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 convert
18 |
19 | import (
20 | "github.com/pkg/errors"
21 | "k8s.io/apimachinery/pkg/runtime"
22 | sa "k8s.io/apiserver/pkg/authentication/serviceaccount"
23 | authinternal "k8s.io/kubernetes/pkg/apis/authentication"
24 |
25 | "github.com/kubewharf/kubezoo/pkg/util"
26 | )
27 |
28 | // TokenReviewTransformer implements the transformation between client
29 | // and upstream server for TokenReview resource.
30 | type TokenReviewTransformer struct{}
31 |
32 | var _ ObjectTransformer = &TokenReviewTransformer{}
33 |
34 | // NewTokenReviewTransformer initiates a TokenReviewTransformer which
35 | // implements the ObjectTransformer interfaces.
36 | func NewTokenReviewTransformer() ObjectTransformer {
37 | return &TokenReviewTransformer{}
38 | }
39 |
40 | // Forward transforms tenant object reference to upstream object reference.
41 | func (t *TokenReviewTransformer) Forward(obj runtime.Object, tenantID string) (runtime.Object, error) {
42 | return obj, nil
43 | }
44 |
45 | // Backward transforms upstream object reference to tenant object reference.
46 | func (t *TokenReviewTransformer) Backward(obj runtime.Object, tenantID string) (runtime.Object, error) {
47 | tokenReview, ok := obj.(*authinternal.TokenReview)
48 | if !ok {
49 | return nil, errors.Errorf("fail to assert the runtime object to the internal version of tokenreview")
50 | }
51 |
52 | prefixedNamespace, name, err := sa.SplitUsername(tokenReview.Status.User.Username)
53 | if err != nil {
54 | // not a service account token
55 | return tokenReview, nil
56 | }
57 | namespace := util.TrimTenantIDPrefix(tenantID, prefixedNamespace)
58 | tokenReview.Status.User.Username = sa.MakeUsername(namespace, name)
59 |
60 | prefixedGroup := sa.MakeNamespaceGroupName(prefixedNamespace)
61 | for i := range tokenReview.Status.User.Groups {
62 | if tokenReview.Status.User.Groups[i] == prefixedGroup {
63 | tokenReview.Status.User.Groups[i] = sa.MakeNamespaceGroupName(namespace)
64 | }
65 | }
66 | return tokenReview, nil
67 | }
68 |
--------------------------------------------------------------------------------
/pkg/convert/volumeattachment.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 convert
18 |
19 | import (
20 | "strings"
21 |
22 | "github.com/pkg/errors"
23 | "k8s.io/apimachinery/pkg/runtime"
24 | storageinternal "k8s.io/kubernetes/pkg/apis/storage"
25 |
26 | "github.com/kubewharf/kubezoo/pkg/util"
27 | )
28 |
29 | // VolumeAttachmentTransformer implements the transformation between client
30 | // and upstream server for VolumeAttachment resource.
31 | type VolumeAttachmentTransformer struct{}
32 |
33 | var _ ObjectTransformer = &VolumeAttachmentTransformer{}
34 |
35 | // NewVolumeAttachmentTransformer initiates a VolumeAttachmentTransformer
36 | // which implements the ObjectTransformer interfaces.
37 | func NewVolumeAttachmentTransformer() ObjectTransformer {
38 | return &VolumeAttachmentTransformer{}
39 | }
40 |
41 | // Forward transforms tenant object reference to upstream object reference.
42 | func (v *VolumeAttachmentTransformer) Forward(obj runtime.Object, tenantID string) (runtime.Object, error) {
43 | volumeAttachment, ok := obj.(*storageinternal.VolumeAttachment)
44 | if !ok {
45 | return nil, errors.Errorf("fail to assert the runtime object to the internal version of volumeattachment")
46 | }
47 |
48 | if volumeAttachment.Spec.Source.PersistentVolumeName != nil && len(*volumeAttachment.Spec.Source.PersistentVolumeName) > 0 {
49 | *volumeAttachment.Spec.Source.PersistentVolumeName = util.AddTenantIDPrefix(tenantID, *volumeAttachment.Spec.Source.PersistentVolumeName)
50 | }
51 | return volumeAttachment, nil
52 | }
53 |
54 | // Backward transforms upstream object reference to tenant object reference.
55 | func (v *VolumeAttachmentTransformer) Backward(obj runtime.Object, tenantID string) (runtime.Object, error) {
56 | volumeAttachment, ok := obj.(*storageinternal.VolumeAttachment)
57 | if !ok {
58 | return nil, errors.Errorf("fail to assert the runtime object to the internal version of volumeattachment")
59 | }
60 |
61 | if volumeAttachment.Spec.Source.PersistentVolumeName != nil && len(*volumeAttachment.Spec.Source.PersistentVolumeName) > 0 {
62 | if !strings.HasPrefix(*volumeAttachment.Spec.Source.PersistentVolumeName, tenantID) {
63 | return nil, errors.Errorf("invalid pv name %s in volume attachment %s, tenant id is %s", *volumeAttachment.Spec.Source.PersistentVolumeName, volumeAttachment.Name, tenantID)
64 | }
65 | *volumeAttachment.Spec.Source.PersistentVolumeName = util.TrimTenantIDPrefix(tenantID, *volumeAttachment.Spec.Source.PersistentVolumeName)
66 | }
67 | return volumeAttachment, nil
68 | }
69 |
--------------------------------------------------------------------------------
/pkg/dynamic/interface.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 dynamic
18 |
19 | import (
20 | "context"
21 |
22 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
23 | "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
24 | "k8s.io/apimachinery/pkg/runtime/schema"
25 | "k8s.io/apimachinery/pkg/types"
26 | "k8s.io/apimachinery/pkg/watch"
27 | )
28 |
29 | // this dynimic client interface is inspired by k8s.io/client-go/dynamic.Interface
30 | type Interface interface {
31 | Resource(resource schema.GroupVersionResource) NamespaceableResourceInterface
32 | }
33 |
34 | type ResourceInterface interface {
35 | Create(ctx context.Context, obj *unstructured.Unstructured, options metav1.CreateOptions, subresources ...string) (*unstructured.Unstructured, error)
36 | Update(ctx context.Context, obj *unstructured.Unstructured, options metav1.UpdateOptions, subresources ...string) (*unstructured.Unstructured, bool, error)
37 | UpdateStatus(ctx context.Context, obj *unstructured.Unstructured, options metav1.UpdateOptions) (*unstructured.Unstructured, error)
38 | Delete(ctx context.Context, name string, options metav1.DeleteOptions, subresources ...string) (*unstructured.Unstructured, bool, error)
39 | DeleteCollection(ctx context.Context, options metav1.DeleteOptions, listOptions metav1.ListOptions) (*unstructured.UnstructuredList, error)
40 | Get(ctx context.Context, name string, options metav1.GetOptions, subresources ...string) (*unstructured.Unstructured, error)
41 | List(ctx context.Context, opts metav1.ListOptions) (*unstructured.UnstructuredList, error)
42 | Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error)
43 | Patch(ctx context.Context, name string, pt types.PatchType, data []byte, options metav1.PatchOptions, subresources ...string) (*unstructured.Unstructured, bool, error)
44 | }
45 |
46 | type NamespaceableResourceInterface interface {
47 | Namespace(string) ResourceInterface
48 | ResourceInterface
49 | }
50 |
51 | // APIPathResolverFunc knows how to convert a groupVersion to its API path. The Kind field is optional.
52 | type APIPathResolverFunc func(kind schema.GroupVersionKind) string
53 |
54 | // LegacyAPIPathResolverFunc can resolve paths properly with the legacy API.
55 | func LegacyAPIPathResolverFunc(kind schema.GroupVersionKind) string {
56 | if len(kind.Group) == 0 {
57 | return "/api"
58 | }
59 | return "/apis"
60 | }
61 |
--------------------------------------------------------------------------------
/pkg/filters/tenant.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 filters
18 |
19 | import (
20 | "net/http"
21 |
22 | "k8s.io/apiserver/pkg/authentication/serviceaccount"
23 | "k8s.io/apiserver/pkg/endpoints/request"
24 | "k8s.io/klog"
25 |
26 | "github.com/kubewharf/kubezoo/pkg/util"
27 | )
28 |
29 | // WithTenantInfo creates an http handler that tries to add tenant info to user info generated by authentication filter
30 | func WithTenantInfo(handler http.Handler) http.Handler {
31 | return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
32 | user, ok := request.UserFrom(req.Context())
33 | if !ok {
34 | klog.Warningf("no user info found after authentication filter")
35 | handler.ServeHTTP(w, req)
36 | return
37 | }
38 |
39 | namespace, _, err := serviceaccount.SplitUsername(user.GetName())
40 | if err != nil {
41 | // this user info is not generated by service account authentication filter
42 | handler.ServeHTTP(w, req)
43 | return
44 | }
45 | tenantID, err := util.GetTenantIDFromNamespace(namespace)
46 | if err != nil {
47 | klog.Warningf("failed to get tenant id from service account namespace: %s, err: %v", namespace, err)
48 | handler.ServeHTTP(w, req)
49 | return
50 | }
51 |
52 | req = req.WithContext(request.WithUser(req.Context(), util.AddTenantIDToUserInfo(tenantID, user)))
53 | handler.ServeHTTP(w, req)
54 | })
55 | }
56 |
--------------------------------------------------------------------------------
/pkg/filters/tenant_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 filters
18 |
19 | import (
20 | "net/http"
21 | "net/http/httptest"
22 | "testing"
23 |
24 | "k8s.io/apiserver/pkg/endpoints/request"
25 | "k8s.io/kubernetes/pkg/serviceaccount"
26 |
27 | "github.com/kubewharf/kubezoo/pkg/util"
28 | )
29 |
30 | // TestWithTenantInfo tests the method WithTenantInfo.
31 | func TestWithTenantInfo(t *testing.T) {
32 | tenantID := "demo01"
33 | serviceAccountInfo := serviceaccount.ServiceAccountInfo{
34 | Name: "foo",
35 | Namespace: util.AddTenantIDPrefix(tenantID, "foo"),
36 | UID: "aa458e95-3a0d-11e7-a8bf-0cc47a944282",
37 | PodName: "bar",
38 | PodUID: "aa458e95-3a0d-11e7-a8bf-0cc47a944141",
39 | }
40 | req := &http.Request{}
41 | req = req.WithContext(request.WithUser(req.Context(), serviceAccountInfo.UserInfo()))
42 |
43 | success := make(chan struct{})
44 | tenant := WithTenantInfo(
45 | http.HandlerFunc(func(_ http.ResponseWriter, req *http.Request) {
46 | user, ok := request.UserFrom(req.Context())
47 | if !ok {
48 | t.Fatalf("no user info found")
49 | }
50 | tenantIDs := user.GetExtra()[util.TenantIDKey]
51 | if len(tenantIDs) != 1 || tenantIDs[0] != tenantID {
52 | t.Fatalf("tenantID slice should be [%s], but got: %v", tenantID, tenantIDs)
53 | }
54 | close(success)
55 | }))
56 |
57 | tenant.ServeHTTP(httptest.NewRecorder(), req)
58 | <-success
59 | }
60 |
--------------------------------------------------------------------------------
/pkg/generated/clientset/versioned/doc.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 clientset.
20 | package versioned
21 |
--------------------------------------------------------------------------------
/pkg/generated/clientset/versioned/fake/clientset_generated.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 | clientset "github.com/kubewharf/kubezoo/pkg/generated/clientset/versioned"
23 | quotav1alpha1 "github.com/kubewharf/kubezoo/pkg/generated/clientset/versioned/typed/quota/v1alpha1"
24 | fakequotav1alpha1 "github.com/kubewharf/kubezoo/pkg/generated/clientset/versioned/typed/quota/v1alpha1/fake"
25 | tenantv1alpha1 "github.com/kubewharf/kubezoo/pkg/generated/clientset/versioned/typed/tenant/v1alpha1"
26 | faketenantv1alpha1 "github.com/kubewharf/kubezoo/pkg/generated/clientset/versioned/typed/tenant/v1alpha1/fake"
27 | "k8s.io/apimachinery/pkg/runtime"
28 | "k8s.io/apimachinery/pkg/watch"
29 | "k8s.io/client-go/discovery"
30 | fakediscovery "k8s.io/client-go/discovery/fake"
31 | "k8s.io/client-go/testing"
32 | )
33 |
34 | // NewSimpleClientset returns a clientset that will respond with the provided objects.
35 | // It's backed by a very simple object tracker that processes creates, updates and deletions as-is,
36 | // without applying any validations and/or defaults. It shouldn't be considered a replacement
37 | // for a real clientset and is mostly useful in simple unit tests.
38 | func NewSimpleClientset(objects ...runtime.Object) *Clientset {
39 | o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder())
40 | for _, obj := range objects {
41 | if err := o.Add(obj); err != nil {
42 | panic(err)
43 | }
44 | }
45 |
46 | cs := &Clientset{tracker: o}
47 | cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake}
48 | cs.AddReactor("*", "*", testing.ObjectReaction(o))
49 | cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) {
50 | gvr := action.GetResource()
51 | ns := action.GetNamespace()
52 | watch, err := o.Watch(gvr, ns)
53 | if err != nil {
54 | return false, nil, err
55 | }
56 | return true, watch, nil
57 | })
58 |
59 | return cs
60 | }
61 |
62 | // Clientset implements clientset.Interface. Meant to be embedded into a
63 | // struct to get a default implementation. This makes faking out just the method
64 | // you want to test easier.
65 | type Clientset struct {
66 | testing.Fake
67 | discovery *fakediscovery.FakeDiscovery
68 | tracker testing.ObjectTracker
69 | }
70 |
71 | func (c *Clientset) Discovery() discovery.DiscoveryInterface {
72 | return c.discovery
73 | }
74 |
75 | func (c *Clientset) Tracker() testing.ObjectTracker {
76 | return c.tracker
77 | }
78 |
79 | var (
80 | _ clientset.Interface = &Clientset{}
81 | _ testing.FakeClient = &Clientset{}
82 | )
83 |
84 | // QuotaV1alpha1 retrieves the QuotaV1alpha1Client
85 | func (c *Clientset) QuotaV1alpha1() quotav1alpha1.QuotaV1alpha1Interface {
86 | return &fakequotav1alpha1.FakeQuotaV1alpha1{Fake: &c.Fake}
87 | }
88 |
89 | // TenantV1alpha1 retrieves the TenantV1alpha1Client
90 | func (c *Clientset) TenantV1alpha1() tenantv1alpha1.TenantV1alpha1Interface {
91 | return &faketenantv1alpha1.FakeTenantV1alpha1{Fake: &c.Fake}
92 | }
93 |
--------------------------------------------------------------------------------
/pkg/generated/clientset/versioned/fake/doc.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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/generated/clientset/versioned/fake/register.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 | quotav1alpha1 "github.com/kubewharf/kubezoo/pkg/apis/quota/v1alpha1"
23 | tenantv1alpha1 "github.com/kubewharf/kubezoo/pkg/apis/tenant/v1alpha1"
24 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25 | runtime "k8s.io/apimachinery/pkg/runtime"
26 | schema "k8s.io/apimachinery/pkg/runtime/schema"
27 | serializer "k8s.io/apimachinery/pkg/runtime/serializer"
28 | utilruntime "k8s.io/apimachinery/pkg/util/runtime"
29 | )
30 |
31 | var scheme = runtime.NewScheme()
32 | var codecs = serializer.NewCodecFactory(scheme)
33 |
34 | var localSchemeBuilder = runtime.SchemeBuilder{
35 | quotav1alpha1.AddToScheme,
36 | tenantv1alpha1.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/generated/clientset/versioned/scheme/doc.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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/generated/clientset/versioned/scheme/register.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 | quotav1alpha1 "github.com/kubewharf/kubezoo/pkg/apis/quota/v1alpha1"
23 | tenantv1alpha1 "github.com/kubewharf/kubezoo/pkg/apis/tenant/v1alpha1"
24 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25 | runtime "k8s.io/apimachinery/pkg/runtime"
26 | schema "k8s.io/apimachinery/pkg/runtime/schema"
27 | serializer "k8s.io/apimachinery/pkg/runtime/serializer"
28 | utilruntime "k8s.io/apimachinery/pkg/util/runtime"
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 | quotav1alpha1.AddToScheme,
36 | tenantv1alpha1.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/generated/clientset/versioned/typed/quota/v1alpha1/doc.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 v1alpha1
21 |
--------------------------------------------------------------------------------
/pkg/generated/clientset/versioned/typed/quota/v1alpha1/fake/doc.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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/generated/clientset/versioned/typed/quota/v1alpha1/fake/fake_quota_client.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 | v1alpha1 "github.com/kubewharf/kubezoo/pkg/generated/clientset/versioned/typed/quota/v1alpha1"
23 | rest "k8s.io/client-go/rest"
24 | testing "k8s.io/client-go/testing"
25 | )
26 |
27 | type FakeQuotaV1alpha1 struct {
28 | *testing.Fake
29 | }
30 |
31 | func (c *FakeQuotaV1alpha1) ClusterResourceQuotas() v1alpha1.ClusterResourceQuotaInterface {
32 | return &FakeClusterResourceQuotas{c}
33 | }
34 |
35 | // RESTClient returns a RESTClient that is used to communicate
36 | // with API server by this client implementation.
37 | func (c *FakeQuotaV1alpha1) RESTClient() rest.Interface {
38 | var ret *rest.RESTClient
39 | return ret
40 | }
41 |
--------------------------------------------------------------------------------
/pkg/generated/clientset/versioned/typed/quota/v1alpha1/generated_expansion.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 v1alpha1
20 |
21 | type ClusterResourceQuotaExpansion interface{}
22 |
--------------------------------------------------------------------------------
/pkg/generated/clientset/versioned/typed/quota/v1alpha1/quota_client.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 v1alpha1
20 |
21 | import (
22 | "net/http"
23 |
24 | v1alpha1 "github.com/kubewharf/kubezoo/pkg/apis/quota/v1alpha1"
25 | "github.com/kubewharf/kubezoo/pkg/generated/clientset/versioned/scheme"
26 | rest "k8s.io/client-go/rest"
27 | )
28 |
29 | type QuotaV1alpha1Interface interface {
30 | RESTClient() rest.Interface
31 | ClusterResourceQuotasGetter
32 | }
33 |
34 | // QuotaV1alpha1Client is used to interact with features provided by the quota.kubezoo.io group.
35 | type QuotaV1alpha1Client struct {
36 | restClient rest.Interface
37 | }
38 |
39 | func (c *QuotaV1alpha1Client) ClusterResourceQuotas() ClusterResourceQuotaInterface {
40 | return newClusterResourceQuotas(c)
41 | }
42 |
43 | // NewForConfig creates a new QuotaV1alpha1Client 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) (*QuotaV1alpha1Client, error) {
47 | config := *c
48 | if err := setConfigDefaults(&config); err != nil {
49 | return nil, err
50 | }
51 | httpClient, err := rest.HTTPClientFor(&config)
52 | if err != nil {
53 | return nil, err
54 | }
55 | return NewForConfigAndClient(&config, httpClient)
56 | }
57 |
58 | // NewForConfigAndClient creates a new QuotaV1alpha1Client for the given config and http client.
59 | // Note the http client provided takes precedence over the configured transport values.
60 | func NewForConfigAndClient(c *rest.Config, h *http.Client) (*QuotaV1alpha1Client, error) {
61 | config := *c
62 | if err := setConfigDefaults(&config); err != nil {
63 | return nil, err
64 | }
65 | client, err := rest.RESTClientForConfigAndClient(&config, h)
66 | if err != nil {
67 | return nil, err
68 | }
69 | return &QuotaV1alpha1Client{client}, nil
70 | }
71 |
72 | // NewForConfigOrDie creates a new QuotaV1alpha1Client for the given config and
73 | // panics if there is an error in the config.
74 | func NewForConfigOrDie(c *rest.Config) *QuotaV1alpha1Client {
75 | client, err := NewForConfig(c)
76 | if err != nil {
77 | panic(err)
78 | }
79 | return client
80 | }
81 |
82 | // New creates a new QuotaV1alpha1Client for the given RESTClient.
83 | func New(c rest.Interface) *QuotaV1alpha1Client {
84 | return &QuotaV1alpha1Client{c}
85 | }
86 |
87 | func setConfigDefaults(config *rest.Config) error {
88 | gv := v1alpha1.SchemeGroupVersion
89 | config.GroupVersion = &gv
90 | config.APIPath = "/apis"
91 | config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
92 |
93 | if config.UserAgent == "" {
94 | config.UserAgent = rest.DefaultKubernetesUserAgent()
95 | }
96 |
97 | return nil
98 | }
99 |
100 | // RESTClient returns a RESTClient that is used to communicate
101 | // with API server by this client implementation.
102 | func (c *QuotaV1alpha1Client) RESTClient() rest.Interface {
103 | if c == nil {
104 | return nil
105 | }
106 | return c.restClient
107 | }
108 |
--------------------------------------------------------------------------------
/pkg/generated/clientset/versioned/typed/tenant/v1alpha1/doc.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 v1alpha1
21 |
--------------------------------------------------------------------------------
/pkg/generated/clientset/versioned/typed/tenant/v1alpha1/fake/doc.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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/generated/clientset/versioned/typed/tenant/v1alpha1/fake/fake_tenant_client.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 | v1alpha1 "github.com/kubewharf/kubezoo/pkg/generated/clientset/versioned/typed/tenant/v1alpha1"
23 | rest "k8s.io/client-go/rest"
24 | testing "k8s.io/client-go/testing"
25 | )
26 |
27 | type FakeTenantV1alpha1 struct {
28 | *testing.Fake
29 | }
30 |
31 | func (c *FakeTenantV1alpha1) Tenants() v1alpha1.TenantInterface {
32 | return &FakeTenants{c}
33 | }
34 |
35 | // RESTClient returns a RESTClient that is used to communicate
36 | // with API server by this client implementation.
37 | func (c *FakeTenantV1alpha1) RESTClient() rest.Interface {
38 | var ret *rest.RESTClient
39 | return ret
40 | }
41 |
--------------------------------------------------------------------------------
/pkg/generated/clientset/versioned/typed/tenant/v1alpha1/generated_expansion.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 v1alpha1
20 |
21 | type TenantExpansion interface{}
22 |
--------------------------------------------------------------------------------
/pkg/generated/clientset/versioned/typed/tenant/v1alpha1/tenant_client.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 v1alpha1
20 |
21 | import (
22 | "net/http"
23 |
24 | v1alpha1 "github.com/kubewharf/kubezoo/pkg/apis/tenant/v1alpha1"
25 | "github.com/kubewharf/kubezoo/pkg/generated/clientset/versioned/scheme"
26 | rest "k8s.io/client-go/rest"
27 | )
28 |
29 | type TenantV1alpha1Interface interface {
30 | RESTClient() rest.Interface
31 | TenantsGetter
32 | }
33 |
34 | // TenantV1alpha1Client is used to interact with features provided by the tenant.kubezoo.io group.
35 | type TenantV1alpha1Client struct {
36 | restClient rest.Interface
37 | }
38 |
39 | func (c *TenantV1alpha1Client) Tenants() TenantInterface {
40 | return newTenants(c)
41 | }
42 |
43 | // NewForConfig creates a new TenantV1alpha1Client 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) (*TenantV1alpha1Client, error) {
47 | config := *c
48 | if err := setConfigDefaults(&config); err != nil {
49 | return nil, err
50 | }
51 | httpClient, err := rest.HTTPClientFor(&config)
52 | if err != nil {
53 | return nil, err
54 | }
55 | return NewForConfigAndClient(&config, httpClient)
56 | }
57 |
58 | // NewForConfigAndClient creates a new TenantV1alpha1Client for the given config and http client.
59 | // Note the http client provided takes precedence over the configured transport values.
60 | func NewForConfigAndClient(c *rest.Config, h *http.Client) (*TenantV1alpha1Client, error) {
61 | config := *c
62 | if err := setConfigDefaults(&config); err != nil {
63 | return nil, err
64 | }
65 | client, err := rest.RESTClientForConfigAndClient(&config, h)
66 | if err != nil {
67 | return nil, err
68 | }
69 | return &TenantV1alpha1Client{client}, nil
70 | }
71 |
72 | // NewForConfigOrDie creates a new TenantV1alpha1Client for the given config and
73 | // panics if there is an error in the config.
74 | func NewForConfigOrDie(c *rest.Config) *TenantV1alpha1Client {
75 | client, err := NewForConfig(c)
76 | if err != nil {
77 | panic(err)
78 | }
79 | return client
80 | }
81 |
82 | // New creates a new TenantV1alpha1Client for the given RESTClient.
83 | func New(c rest.Interface) *TenantV1alpha1Client {
84 | return &TenantV1alpha1Client{c}
85 | }
86 |
87 | func setConfigDefaults(config *rest.Config) error {
88 | gv := v1alpha1.SchemeGroupVersion
89 | config.GroupVersion = &gv
90 | config.APIPath = "/apis"
91 | config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
92 |
93 | if config.UserAgent == "" {
94 | config.UserAgent = rest.DefaultKubernetesUserAgent()
95 | }
96 |
97 | return nil
98 | }
99 |
100 | // RESTClient returns a RESTClient that is used to communicate
101 | // with API server by this client implementation.
102 | func (c *TenantV1alpha1Client) RESTClient() rest.Interface {
103 | if c == nil {
104 | return nil
105 | }
106 | return c.restClient
107 | }
108 |
--------------------------------------------------------------------------------
/pkg/generated/informers/externalversions/generic.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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"
23 |
24 | v1alpha1 "github.com/kubewharf/kubezoo/pkg/apis/quota/v1alpha1"
25 | tenantv1alpha1 "github.com/kubewharf/kubezoo/pkg/apis/tenant/v1alpha1"
26 | schema "k8s.io/apimachinery/pkg/runtime/schema"
27 | cache "k8s.io/client-go/tools/cache"
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=quota.kubezoo.io, Version=v1alpha1
57 | case v1alpha1.SchemeGroupVersion.WithResource("clusterresourcequotas"):
58 | return &genericInformer{resource: resource.GroupResource(), informer: f.Quota().V1alpha1().ClusterResourceQuotas().Informer()}, nil
59 |
60 | // Group=tenant.kubezoo.io, Version=v1alpha1
61 | case tenantv1alpha1.SchemeGroupVersion.WithResource("tenants"):
62 | return &genericInformer{resource: resource.GroupResource(), informer: f.Tenant().V1alpha1().Tenants().Informer()}, nil
63 |
64 | }
65 |
66 | return nil, fmt.Errorf("no informer found for %v", resource)
67 | }
68 |
--------------------------------------------------------------------------------
/pkg/generated/informers/externalversions/internalinterfaces/factory_interfaces.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 | versioned "github.com/kubewharf/kubezoo/pkg/generated/clientset/versioned"
25 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26 | runtime "k8s.io/apimachinery/pkg/runtime"
27 | cache "k8s.io/client-go/tools/cache"
28 | )
29 |
30 | // NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer.
31 | type NewInformerFunc func(versioned.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 |
--------------------------------------------------------------------------------
/pkg/generated/informers/externalversions/quota/interface.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 quota
20 |
21 | import (
22 | internalinterfaces "github.com/kubewharf/kubezoo/pkg/generated/informers/externalversions/internalinterfaces"
23 | v1alpha1 "github.com/kubewharf/kubezoo/pkg/generated/informers/externalversions/quota/v1alpha1"
24 | )
25 |
26 | // Interface provides access to each of this group's versions.
27 | type Interface interface {
28 | // V1alpha1 provides access to shared informers for resources in V1alpha1.
29 | V1alpha1() v1alpha1.Interface
30 | }
31 |
32 | type group struct {
33 | factory internalinterfaces.SharedInformerFactory
34 | namespace string
35 | tweakListOptions internalinterfaces.TweakListOptionsFunc
36 | }
37 |
38 | // New returns a new Interface.
39 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
40 | return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
41 | }
42 |
43 | // V1alpha1 returns a new v1alpha1.Interface.
44 | func (g *group) V1alpha1() v1alpha1.Interface {
45 | return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions)
46 | }
47 |
--------------------------------------------------------------------------------
/pkg/generated/informers/externalversions/quota/v1alpha1/interface.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 v1alpha1
20 |
21 | import (
22 | internalinterfaces "github.com/kubewharf/kubezoo/pkg/generated/informers/externalversions/internalinterfaces"
23 | )
24 |
25 | // Interface provides access to all the informers in this group version.
26 | type Interface interface {
27 | // ClusterResourceQuotas returns a ClusterResourceQuotaInformer.
28 | ClusterResourceQuotas() ClusterResourceQuotaInformer
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 | // ClusterResourceQuotas returns a ClusterResourceQuotaInformer.
43 | func (v *version) ClusterResourceQuotas() ClusterResourceQuotaInformer {
44 | return &clusterResourceQuotaInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
45 | }
46 |
--------------------------------------------------------------------------------
/pkg/generated/informers/externalversions/tenant/interface.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 tenant
20 |
21 | import (
22 | internalinterfaces "github.com/kubewharf/kubezoo/pkg/generated/informers/externalversions/internalinterfaces"
23 | v1alpha1 "github.com/kubewharf/kubezoo/pkg/generated/informers/externalversions/tenant/v1alpha1"
24 | )
25 |
26 | // Interface provides access to each of this group's versions.
27 | type Interface interface {
28 | // V1alpha1 provides access to shared informers for resources in V1alpha1.
29 | V1alpha1() v1alpha1.Interface
30 | }
31 |
32 | type group struct {
33 | factory internalinterfaces.SharedInformerFactory
34 | namespace string
35 | tweakListOptions internalinterfaces.TweakListOptionsFunc
36 | }
37 |
38 | // New returns a new Interface.
39 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
40 | return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
41 | }
42 |
43 | // V1alpha1 returns a new v1alpha1.Interface.
44 | func (g *group) V1alpha1() v1alpha1.Interface {
45 | return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions)
46 | }
47 |
--------------------------------------------------------------------------------
/pkg/generated/informers/externalversions/tenant/v1alpha1/interface.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 v1alpha1
20 |
21 | import (
22 | internalinterfaces "github.com/kubewharf/kubezoo/pkg/generated/informers/externalversions/internalinterfaces"
23 | )
24 |
25 | // Interface provides access to all the informers in this group version.
26 | type Interface interface {
27 | // Tenants returns a TenantInformer.
28 | Tenants() TenantInformer
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 | // Tenants returns a TenantInformer.
43 | func (v *version) Tenants() TenantInformer {
44 | return &tenantInformer{factory: v.factory, tweakListOptions: v.tweakListOptions}
45 | }
46 |
--------------------------------------------------------------------------------
/pkg/generated/informers/externalversions/tenant/v1alpha1/tenant.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 v1alpha1
20 |
21 | import (
22 | "context"
23 | time "time"
24 |
25 | tenantv1alpha1 "github.com/kubewharf/kubezoo/pkg/apis/tenant/v1alpha1"
26 | versioned "github.com/kubewharf/kubezoo/pkg/generated/clientset/versioned"
27 | internalinterfaces "github.com/kubewharf/kubezoo/pkg/generated/informers/externalversions/internalinterfaces"
28 | v1alpha1 "github.com/kubewharf/kubezoo/pkg/generated/listers/tenant/v1alpha1"
29 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
30 | runtime "k8s.io/apimachinery/pkg/runtime"
31 | watch "k8s.io/apimachinery/pkg/watch"
32 | cache "k8s.io/client-go/tools/cache"
33 | )
34 |
35 | // TenantInformer provides access to a shared informer and lister for
36 | // Tenants.
37 | type TenantInformer interface {
38 | Informer() cache.SharedIndexInformer
39 | Lister() v1alpha1.TenantLister
40 | }
41 |
42 | type tenantInformer struct {
43 | factory internalinterfaces.SharedInformerFactory
44 | tweakListOptions internalinterfaces.TweakListOptionsFunc
45 | }
46 |
47 | // NewTenantInformer constructs a new informer for Tenant 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 NewTenantInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
51 | return NewFilteredTenantInformer(client, resyncPeriod, indexers, nil)
52 | }
53 |
54 | // NewFilteredTenantInformer constructs a new informer for Tenant 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 NewFilteredTenantInformer(client versioned.Interface, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
58 | return cache.NewSharedIndexInformer(
59 | &cache.ListWatch{
60 | ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
61 | if tweakListOptions != nil {
62 | tweakListOptions(&options)
63 | }
64 | return client.TenantV1alpha1().Tenants().List(context.TODO(), options)
65 | },
66 | WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
67 | if tweakListOptions != nil {
68 | tweakListOptions(&options)
69 | }
70 | return client.TenantV1alpha1().Tenants().Watch(context.TODO(), options)
71 | },
72 | },
73 | &tenantv1alpha1.Tenant{},
74 | resyncPeriod,
75 | indexers,
76 | )
77 | }
78 |
79 | func (f *tenantInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
80 | return NewFilteredTenantInformer(client, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
81 | }
82 |
83 | func (f *tenantInformer) Informer() cache.SharedIndexInformer {
84 | return f.factory.InformerFor(&tenantv1alpha1.Tenant{}, f.defaultInformer)
85 | }
86 |
87 | func (f *tenantInformer) Lister() v1alpha1.TenantLister {
88 | return v1alpha1.NewTenantLister(f.Informer().GetIndexer())
89 | }
90 |
--------------------------------------------------------------------------------
/pkg/generated/listers/quota/v1alpha1/clusterresourcequota.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 v1alpha1
20 |
21 | import (
22 | v1alpha1 "github.com/kubewharf/kubezoo/pkg/apis/quota/v1alpha1"
23 | "k8s.io/apimachinery/pkg/api/errors"
24 | "k8s.io/apimachinery/pkg/labels"
25 | "k8s.io/client-go/tools/cache"
26 | )
27 |
28 | // ClusterResourceQuotaLister helps list ClusterResourceQuotas.
29 | // All objects returned here must be treated as read-only.
30 | type ClusterResourceQuotaLister interface {
31 | // List lists all ClusterResourceQuotas in the indexer.
32 | // Objects returned here must be treated as read-only.
33 | List(selector labels.Selector) (ret []*v1alpha1.ClusterResourceQuota, err error)
34 | // Get retrieves the ClusterResourceQuota from the index for a given name.
35 | // Objects returned here must be treated as read-only.
36 | Get(name string) (*v1alpha1.ClusterResourceQuota, error)
37 | ClusterResourceQuotaListerExpansion
38 | }
39 |
40 | // clusterResourceQuotaLister implements the ClusterResourceQuotaLister interface.
41 | type clusterResourceQuotaLister struct {
42 | indexer cache.Indexer
43 | }
44 |
45 | // NewClusterResourceQuotaLister returns a new ClusterResourceQuotaLister.
46 | func NewClusterResourceQuotaLister(indexer cache.Indexer) ClusterResourceQuotaLister {
47 | return &clusterResourceQuotaLister{indexer: indexer}
48 | }
49 |
50 | // List lists all ClusterResourceQuotas in the indexer.
51 | func (s *clusterResourceQuotaLister) List(selector labels.Selector) (ret []*v1alpha1.ClusterResourceQuota, err error) {
52 | err = cache.ListAll(s.indexer, selector, func(m interface{}) {
53 | ret = append(ret, m.(*v1alpha1.ClusterResourceQuota))
54 | })
55 | return ret, err
56 | }
57 |
58 | // Get retrieves the ClusterResourceQuota from the index for a given name.
59 | func (s *clusterResourceQuotaLister) Get(name string) (*v1alpha1.ClusterResourceQuota, error) {
60 | obj, exists, err := s.indexer.GetByKey(name)
61 | if err != nil {
62 | return nil, err
63 | }
64 | if !exists {
65 | return nil, errors.NewNotFound(v1alpha1.Resource("clusterresourcequota"), name)
66 | }
67 | return obj.(*v1alpha1.ClusterResourceQuota), nil
68 | }
69 |
--------------------------------------------------------------------------------
/pkg/generated/listers/quota/v1alpha1/expansion_generated.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 v1alpha1
20 |
21 | // ClusterResourceQuotaListerExpansion allows custom methods to be added to
22 | // ClusterResourceQuotaLister.
23 | type ClusterResourceQuotaListerExpansion interface{}
24 |
--------------------------------------------------------------------------------
/pkg/generated/listers/tenant/v1alpha1/expansion_generated.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 v1alpha1
20 |
21 | // TenantListerExpansion allows custom methods to be added to
22 | // TenantLister.
23 | type TenantListerExpansion interface{}
24 |
--------------------------------------------------------------------------------
/pkg/generated/listers/tenant/v1alpha1/tenant.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 v1alpha1
20 |
21 | import (
22 | v1alpha1 "github.com/kubewharf/kubezoo/pkg/apis/tenant/v1alpha1"
23 | "k8s.io/apimachinery/pkg/api/errors"
24 | "k8s.io/apimachinery/pkg/labels"
25 | "k8s.io/client-go/tools/cache"
26 | )
27 |
28 | // TenantLister helps list Tenants.
29 | // All objects returned here must be treated as read-only.
30 | type TenantLister interface {
31 | // List lists all Tenants in the indexer.
32 | // Objects returned here must be treated as read-only.
33 | List(selector labels.Selector) (ret []*v1alpha1.Tenant, err error)
34 | // Get retrieves the Tenant from the index for a given name.
35 | // Objects returned here must be treated as read-only.
36 | Get(name string) (*v1alpha1.Tenant, error)
37 | TenantListerExpansion
38 | }
39 |
40 | // tenantLister implements the TenantLister interface.
41 | type tenantLister struct {
42 | indexer cache.Indexer
43 | }
44 |
45 | // NewTenantLister returns a new TenantLister.
46 | func NewTenantLister(indexer cache.Indexer) TenantLister {
47 | return &tenantLister{indexer: indexer}
48 | }
49 |
50 | // List lists all Tenants in the indexer.
51 | func (s *tenantLister) List(selector labels.Selector) (ret []*v1alpha1.Tenant, err error) {
52 | err = cache.ListAll(s.indexer, selector, func(m interface{}) {
53 | ret = append(ret, m.(*v1alpha1.Tenant))
54 | })
55 | return ret, err
56 | }
57 |
58 | // Get retrieves the Tenant from the index for a given name.
59 | func (s *tenantLister) Get(name string) (*v1alpha1.Tenant, error) {
60 | obj, exists, err := s.indexer.GetByKey(name)
61 | if err != nil {
62 | return nil, err
63 | }
64 | if !exists {
65 | return nil, errors.NewNotFound(v1alpha1.Resource("tenant"), name)
66 | }
67 | return obj.(*v1alpha1.Tenant), nil
68 | }
69 |
--------------------------------------------------------------------------------
/pkg/proxy/init.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 proxy
18 |
19 | import (
20 | "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
21 | "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
22 | utilruntime "k8s.io/apimachinery/pkg/util/runtime"
23 | "k8s.io/kubernetes/pkg/api/legacyscheme"
24 | )
25 |
26 | var nativeScheme = legacyscheme.Scheme
27 |
28 | func init() {
29 | utilruntime.Must(v1.AddToScheme(nativeScheme))
30 | utilruntime.Must(v1beta1.AddToScheme(nativeScheme))
31 | }
32 |
--------------------------------------------------------------------------------
/pkg/rest/etcd.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 test_rest
18 |
19 | import (
20 | "k8s.io/apimachinery/pkg/runtime"
21 | "k8s.io/apiserver/pkg/registry/generic"
22 | genericregistry "k8s.io/apiserver/pkg/registry/generic/registry"
23 | "k8s.io/apiserver/pkg/registry/rest"
24 |
25 | "github.com/kubewharf/kubezoo/pkg/apis/tenant/v1alpha1"
26 | )
27 |
28 | // REST implements a RESTStorage for audit sink against etcd
29 | type REST struct {
30 | *genericregistry.Store
31 | }
32 |
33 | // NewREST returns a RESTStorage object that will work against API services.
34 | func NewREST(scheme *runtime.Scheme, optsGetter generic.RESTOptionsGetter) (*REST, error) {
35 | strategy := NewStrategy(scheme)
36 |
37 | store := &genericregistry.Store{
38 | NewFunc: func() runtime.Object { return &v1alpha1.Tenant{} },
39 | // E0111 12:55:20.698099 49243 cacher.go:428] unexpected ListAndWatch error: storage/cacher.go:/xuchens: Failed to list *v1alpha1.Xuchen: *v1alpha1.Xuchen is not a list: no Items field in this object
40 | NewListFunc: func() runtime.Object { return &v1alpha1.TenantList{} },
41 | PredicateFunc: MatchTenant,
42 | DefaultQualifiedResource: Resource("tenants"),
43 |
44 | CreateStrategy: strategy,
45 | UpdateStrategy: strategy,
46 | DeleteStrategy: strategy,
47 |
48 | // TODO: define table converter that exposes more than name/creation timestamp
49 | TableConvertor: rest.NewDefaultTableConvertor(Resource("tenants")),
50 | }
51 | options := &generic.StoreOptions{RESTOptions: optsGetter, AttrFunc: GetAttrs}
52 | if err := store.CompleteWithOptions(options); err != nil {
53 | return nil, err
54 | }
55 | return &REST{store}, nil
56 | }
57 |
--------------------------------------------------------------------------------
/pkg/rest/storage_rest.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 test_rest
18 |
19 | import (
20 | "k8s.io/apimachinery/pkg/runtime/schema"
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 | "k8s.io/kubernetes/pkg/api/legacyscheme"
26 | )
27 |
28 | type RESTStorageProvider struct{}
29 |
30 | var SchemeGroupVersion = schema.GroupVersion{Group: "tenant.kubezoo.io", Version: "v1alpha1"}
31 |
32 | func Resource(resource string) schema.GroupResource {
33 | return SchemeGroupVersion.WithResource(resource).GroupResource()
34 | }
35 |
36 | // NewRESTStorage provide the rest storage for tenant.
37 | func (p RESTStorageProvider) NewRESTStorage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) (genericapiserver.APIGroupInfo, error) {
38 | apiGroupInfo := genericapiserver.NewDefaultAPIGroupInfo("tenant.kubezoo.io", legacyscheme.Scheme, legacyscheme.ParameterCodec, legacyscheme.Codecs)
39 | // If you add a version here, be sure to add an entry in `k8s.io/kubernetes/cmd/kube-apiserver/app/aggregator.go with specific priorities.
40 | // TODO refactor the plumbing to provide the information in the APIGroupInfo
41 |
42 | if apiResourceConfigSource.ResourceEnabled(SchemeGroupVersion.WithResource("tenants")) {
43 | apiGroupInfo.VersionedResourcesStorageMap[SchemeGroupVersion.Version] = p.v1alpha1Storage(apiResourceConfigSource, restOptionsGetter)
44 | }
45 |
46 | return apiGroupInfo, nil
47 | }
48 |
49 | func (p RESTStorageProvider) v1alpha1Storage(apiResourceConfigSource serverstorage.APIResourceConfigSource, restOptionsGetter generic.RESTOptionsGetter) map[string]rest.Storage {
50 | storage := map[string]rest.Storage{}
51 |
52 | tenantStorage, _ := NewREST(legacyscheme.Scheme, restOptionsGetter)
53 | storage["tenants"] = tenantStorage
54 | return storage
55 |
56 | }
57 |
58 | // GroupName returns the group name.
59 | func (p RESTStorageProvider) GroupName() string {
60 | return SchemeGroupVersion.Group
61 | }
62 |
--------------------------------------------------------------------------------
/pkg/util/crd.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 util
18 |
19 | import v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
20 |
21 | // CustomGroupResourcesMap records the existence of all custom api group and resources for a tenant
22 | // the first key is api group and the second key is resource name
23 | type CustomGroupResourcesMap map[string]map[string]*v1.CustomResourceDefinition
24 |
25 | // NewCustomGroupResourcesMap return a CRD map.
26 | func NewCustomGroupResourcesMap(crdList []*v1.CustomResourceDefinition) CustomGroupResourcesMap {
27 | grm := make(map[string]map[string]*v1.CustomResourceDefinition)
28 | for _, crd := range crdList {
29 | _, ok := grm[crd.Spec.Group]
30 | if !ok {
31 | grm[crd.Spec.Group] = make(map[string]*v1.CustomResourceDefinition)
32 | }
33 | grm[crd.Spec.Group][crd.Spec.Names.Plural] = crd
34 | }
35 | return grm
36 | }
37 |
38 | // HasGroup checks the map contains the api group or not.
39 | func (grm CustomGroupResourcesMap) HasGroup(apiGroup string) bool {
40 | return grm[apiGroup] != nil
41 | }
42 |
43 | // HasResource checks the map contains the resource or not.
44 | func (grm CustomGroupResourcesMap) HasResource(resourceName string) bool {
45 | for _, resources := range grm {
46 | if resources[resourceName] != nil {
47 | return true
48 | }
49 | }
50 | return false
51 | }
52 |
53 | // HasGroupResource checks the map contains the group resource or not.
54 | func (grm CustomGroupResourcesMap) HasGroupResource(apiGroup, resourceName string) bool {
55 | return grm[apiGroup][resourceName] != nil
56 | }
57 |
58 | // HasGroupVersion checks the map contains the group version or not.
59 | func (grm CustomGroupResourcesMap) HasGroupVersion(apiGroup, version string) bool {
60 | for _, crd := range grm[apiGroup] {
61 | if crd == nil {
62 | continue
63 | }
64 | for i := range crd.Spec.Versions {
65 | if crd.Spec.Versions[i].Name == version {
66 | return true
67 | }
68 | }
69 | }
70 | return false
71 | }
72 |
73 | // HasGroupVersionResource checks the map contains the group version resource or not.
74 | func (grm CustomGroupResourcesMap) HasGroupVersionResource(apiGroup, version, resourceName string) bool {
75 | crd := grm.GetCRD(apiGroup, resourceName)
76 | if crd == nil {
77 | return false
78 | }
79 | for i := range crd.Spec.Versions {
80 | if crd.Spec.Versions[i].Name == version {
81 | return true
82 | }
83 | }
84 | return false
85 | }
86 |
87 | // GetCRD return the CRD by APIGroup and resource name.
88 | func (grm CustomGroupResourcesMap) GetCRD(apiGroup, resourceName string) *v1.CustomResourceDefinition {
89 | return grm[apiGroup][resourceName]
90 | }
91 |
--------------------------------------------------------------------------------
/pkg/util/crd_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 util
18 |
19 | import (
20 | "testing"
21 |
22 | apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
23 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
24 | )
25 |
26 | // TestCRD mainly tests the methods of CustomGroupResourcesMap.
27 | func TestCRD(t *testing.T) {
28 |
29 | tenant := "111111"
30 | CRDPlural := "foos"
31 | CRDGroup := tenant + "-" + "a.com"
32 | CRDVersion := "v1"
33 | FullCRDName := CRDPlural + "." + CRDGroup
34 |
35 | crdList := []*apiextensionsv1.CustomResourceDefinition{
36 | {
37 | TypeMeta: metav1.TypeMeta{
38 | Kind: "CustomResourceDefinition",
39 | APIVersion: "apiextensions/v1",
40 | },
41 | ObjectMeta: metav1.ObjectMeta{
42 | Name: FullCRDName,
43 | },
44 | Spec: apiextensionsv1.CustomResourceDefinitionSpec{
45 | Group: CRDGroup,
46 | Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
47 | {
48 | Name: CRDVersion,
49 | },
50 | },
51 | Scope: apiextensionsv1.NamespaceScoped,
52 | Names: apiextensionsv1.CustomResourceDefinitionNames{
53 | Plural: CRDPlural,
54 | Kind: "Foo",
55 | },
56 | },
57 | },
58 | }
59 |
60 | m := NewCustomGroupResourcesMap(crdList)
61 |
62 | if !m.HasGroup(CRDGroup) {
63 | t.Errorf("group %s not found, expected found", CRDGroup)
64 | }
65 |
66 | if !m.HasResource(CRDPlural) {
67 | t.Errorf("group %s not found, expected found", CRDPlural)
68 | }
69 |
70 | if !m.HasGroupResource(CRDGroup, CRDPlural) {
71 | t.Errorf("group resource %s/%s not found, expected found", CRDGroup, CRDPlural)
72 | }
73 |
74 | if !m.HasGroupVersion(CRDGroup, CRDVersion) {
75 | t.Errorf("group version %s/%s not found, expected found", CRDGroup, CRDVersion)
76 | }
77 |
78 | if !m.HasGroupVersionResource(CRDGroup, CRDVersion, CRDPlural) {
79 | t.Errorf("group version %s/%s/%s not found, expected found", CRDGroup, CRDVersion, CRDVersion)
80 | }
81 |
82 | crd := m.GetCRD(CRDGroup, CRDPlural)
83 | if crd == nil {
84 | t.Errorf("crd should not be nil.")
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/pkg/util/errors.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 util
18 |
19 | import (
20 | "errors"
21 | "fmt"
22 | "strings"
23 |
24 | apierrors "k8s.io/apimachinery/pkg/api/errors"
25 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26 | "k8s.io/apimachinery/pkg/util/runtime"
27 | )
28 |
29 | // TrimTenantIDFromError trims tenantID from error message and returns the new error.
30 | func TrimTenantIDFromError(err error, tenantID string) error {
31 | switch t := err.(type) {
32 | case *apierrors.StatusError:
33 | return &apierrors.StatusError{
34 | ErrStatus: TrimTenantIDFromStatus(t.Status(), tenantID),
35 | }
36 | default:
37 | runtime.HandleError(fmt.Errorf("kubezoo received an error that is not an metav1.Status: %#+v", err))
38 | return errors.New(strings.ReplaceAll(err.Error(), tenantID+"-", ""))
39 | }
40 | }
41 |
42 | // TrimTenantIDFromStatus trims tenantID from status and returns the new status.
43 | func TrimTenantIDFromStatus(status metav1.Status, tenantID string) metav1.Status {
44 | status.Message = strings.ReplaceAll(status.Message, tenantID+"-", "")
45 | if status.Details == nil {
46 | return status
47 | }
48 | status.Details.Name = strings.Replace(status.Details.Name, tenantID+"-", "", 1)
49 | status.Details.Group = TrimTenantIDPrefix(tenantID, status.Details.Group)
50 | for i := range status.Details.Causes {
51 | status.Details.Causes[i].Message = strings.ReplaceAll(status.Details.Causes[i].Message, tenantID+"-", "")
52 | }
53 | return status
54 | }
55 |
--------------------------------------------------------------------------------
/pkg/util/errors_test.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 util
18 |
19 | import (
20 | "fmt"
21 | "testing"
22 |
23 | apierrors "k8s.io/apimachinery/pkg/api/errors"
24 | )
25 |
26 | // TestTrimTenantIDFromErrorWithStatusError tests with status error.
27 | func TestTrimTenantIDFromErrorWithStatusError(t *testing.T) {
28 | tenantId := "111111"
29 | msg := "unauthorized"
30 | statusErr := apierrors.NewUnauthorized(tenantId + "-" + msg)
31 | err := TrimTenantIDFromError(statusErr, tenantId)
32 | if err.Error() != msg {
33 | fmt.Printf("error message: %s", err)
34 | t.Errorf("unexpected trim tenant id from error")
35 | }
36 | }
37 |
38 | // TestTrimTenantIDFromErrorWithStatusError tests with non status error.
39 | func TestTrimTenantIDFromErrorWithNonStatusError(t *testing.T) {
40 | tenantId := "111111"
41 | msg := "unauthorized"
42 | errIn := fmt.Errorf("%s-%s", tenantId, msg)
43 | err := TrimTenantIDFromError(errIn, tenantId)
44 | if err.Error() != msg {
45 | fmt.Printf("error message: %s", err)
46 | t.Errorf("unexpected trim tenant id from error")
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/pkg/util/kubeconfig.go:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright 2022 The KubeZoo 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 util
18 |
19 | import (
20 | "k8s.io/apimachinery/pkg/runtime"
21 | clientcmdlatest "k8s.io/client-go/tools/clientcmd/api/latest"
22 | kbcfg "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
23 | )
24 |
25 | // GenKubeconfig signed a kubeconfig for the tenant.
26 | func GenKubeconfig(kubeZooServerAddress, tenantId string, caCert, clientKey, clientCert []byte) ([]byte, error) {
27 | config := kbcfg.CreateWithCerts(kubeZooServerAddress, KubeZooClusterName, tenantId, caCert, clientKey, clientCert)
28 | return runtime.Encode(clientcmdlatest.Codec, config)
29 | }
30 |
--------------------------------------------------------------------------------