mirror of https://github.com/k3s-io/k3s
Doc API group suffix, add test to catch new groups
parent
cd30526b44
commit
620cc66ead
|
@ -134,10 +134,10 @@ Currently there are two API groups in use:
|
||||||
This holds types which will probably move to another API group eventually.
|
This holds types which will probably move to another API group eventually.
|
||||||
1. the "componentconfig" and "metrics" API groups.
|
1. the "componentconfig" and "metrics" API groups.
|
||||||
|
|
||||||
|
In the future we expect that there will be more API groups, all at REST path `/apis/$API_GROUP` and using `apiVersion: $API_GROUP/$VERSION`.
|
||||||
In the future we expect that there will be more API groups, all at REST path `/apis/$API_GROUP` and
|
We expect that there will be a way for [third parties to create their own API groups](design/extending-api.md).
|
||||||
using `apiVersion: $API_GROUP/$VERSION`. We expect that there will be a way for [third parties to
|
To avoid naming collisions, third-party API groups must be a DNS name at least three segments long.
|
||||||
create their own API groups](design/extending-api.md), and to avoid naming collisions.
|
New Kubernetes API groups are suffixed with `.k8s.io` (e.g. `storage.k8s.io`, `rbac.authorization.k8s.io`).
|
||||||
|
|
||||||
## Enabling resources in the extensions group
|
## Enabling resources in the extensions group
|
||||||
|
|
||||||
|
|
|
@ -80,9 +80,9 @@ expected to be programmatically convertible to the name of the resource using
|
||||||
the following conversion. Kinds are expected to be of the form
|
the following conversion. Kinds are expected to be of the form
|
||||||
`<CamelCaseKind>`, and the `APIVersion` for the object is expected to be
|
`<CamelCaseKind>`, and the `APIVersion` for the object is expected to be
|
||||||
`<api-group>/<api-version>`. To prevent collisions, it's expected that you'll
|
`<api-group>/<api-version>`. To prevent collisions, it's expected that you'll
|
||||||
use a fully qualified domain name for the API group, e.g. `example.com`.
|
use a DNS name of at least three segments for the API group, e.g. `mygroup.example.com`.
|
||||||
|
|
||||||
For example `stable.example.com/v1`
|
For example `mygroup.example.com/v1`
|
||||||
|
|
||||||
'CamelCaseKind' is the specific type name.
|
'CamelCaseKind' is the specific type name.
|
||||||
|
|
||||||
|
@ -101,9 +101,9 @@ for ix := range kindName {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
As a concrete example, the resource named `camel-case-kind.example.com` defines
|
As a concrete example, the resource named `camel-case-kind.mygroup.example.com` defines
|
||||||
resources of Kind `CamelCaseKind`, in the APIGroup with the prefix
|
resources of Kind `CamelCaseKind`, in the APIGroup with the prefix
|
||||||
`example.com/...`.
|
`mygroup.example.com/...`.
|
||||||
|
|
||||||
The reason for this is to enable rapid lookup of a `ThirdPartyResource` object
|
The reason for this is to enable rapid lookup of a `ThirdPartyResource` object
|
||||||
given the kind information. This is also the reason why `ThirdPartyResource` is
|
given the kind information. This is also the reason why `ThirdPartyResource` is
|
||||||
|
@ -120,7 +120,7 @@ For example, if a user creates:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
metadata:
|
metadata:
|
||||||
name: cron-tab.stable.example.com
|
name: cron-tab.mygroup.example.com
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: extensions/v1beta1
|
||||||
kind: ThirdPartyResource
|
kind: ThirdPartyResource
|
||||||
description: "A specification of a Pod to run on a cron style schedule"
|
description: "A specification of a Pod to run on a cron style schedule"
|
||||||
|
@ -130,7 +130,7 @@ versions:
|
||||||
```
|
```
|
||||||
|
|
||||||
Then the API server will program in the new RESTful resource path:
|
Then the API server will program in the new RESTful resource path:
|
||||||
* `/apis/stable.example.com/v1/namespaces/<namespace>/crontabs/...`
|
* `/apis/mygroup.example.com/v1/namespaces/<namespace>/crontabs/...`
|
||||||
|
|
||||||
**Note: This may take a while before RESTful resource path registration happen, please
|
**Note: This may take a while before RESTful resource path registration happen, please
|
||||||
always check this before you create resource instances.**
|
always check this before you create resource instances.**
|
||||||
|
@ -142,20 +142,20 @@ Now that this schema has been created, a user can `POST`:
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"name": "my-new-cron-object"
|
"name": "my-new-cron-object"
|
||||||
},
|
},
|
||||||
"apiVersion": "stable.example.com/v1",
|
"apiVersion": "mygroup.example.com/v1",
|
||||||
"kind": "CronTab",
|
"kind": "CronTab",
|
||||||
"cronSpec": "* * * * /5",
|
"cronSpec": "* * * * /5",
|
||||||
"image": "my-awesome-cron-image"
|
"image": "my-awesome-cron-image"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
to: `/apis/stable.example.com/v1/namespaces/default/crontabs`
|
to: `/apis/mygroup.example.com/v1/namespaces/default/crontabs`
|
||||||
|
|
||||||
and the corresponding data will be stored into etcd by the APIServer, so that
|
and the corresponding data will be stored into etcd by the APIServer, so that
|
||||||
when the user issues:
|
when the user issues:
|
||||||
|
|
||||||
```
|
```
|
||||||
GET /apis/stable.example.com/v1/namespaces/default/crontabs/my-new-cron-object`
|
GET /apis/mygroup.example.com/v1/namespaces/default/crontabs/my-new-cron-object`
|
||||||
```
|
```
|
||||||
|
|
||||||
And when they do that, they will get back the same data, but with additional
|
And when they do that, they will get back the same data, but with additional
|
||||||
|
@ -164,21 +164,21 @@ Kubernetes metadata (e.g. `resourceVersion`, `createdTimestamp`) filled in.
|
||||||
Likewise, to list all resources, a user can issue:
|
Likewise, to list all resources, a user can issue:
|
||||||
|
|
||||||
```
|
```
|
||||||
GET /apis/stable.example.com/v1/namespaces/default/crontabs
|
GET /apis/mygroup.example.com/v1/namespaces/default/crontabs
|
||||||
```
|
```
|
||||||
|
|
||||||
and get back:
|
and get back:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"apiVersion": "stable.example.com/v1",
|
"apiVersion": "mygroup.example.com/v1",
|
||||||
"kind": "CronTabList",
|
"kind": "CronTabList",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"name": "my-new-cron-object"
|
"name": "my-new-cron-object"
|
||||||
},
|
},
|
||||||
"apiVersion": "stable.example.com/v1",
|
"apiVersion": "mygroup.example.com/v1",
|
||||||
"kind": "CronTab",
|
"kind": "CronTab",
|
||||||
"cronSpec": "* * * * /5",
|
"cronSpec": "* * * * /5",
|
||||||
"image": "my-awesome-cron-image"
|
"image": "my-awesome-cron-image"
|
||||||
|
|
|
@ -49,19 +49,19 @@ We plan on improving the way the types are factored in the future; see
|
||||||
[#16062](https://github.com/kubernetes/kubernetes/pull/16062) for the directions
|
[#16062](https://github.com/kubernetes/kubernetes/pull/16062) for the directions
|
||||||
in which this might evolve.
|
in which this might evolve.
|
||||||
|
|
||||||
1. Create a folder in pkg/apis to hold you group. Create types.go in
|
1. Create a folder in pkg/apis to hold your group. Create types.go in
|
||||||
pkg/apis/`<group>`/ and pkg/apis/`<group>`/`<version>`/ to define API objects
|
pkg/apis/`<group>`/ and pkg/apis/`<group>`/`<version>`/ to define API objects
|
||||||
in your group;
|
in your group;
|
||||||
|
|
||||||
2. Create pkg/apis/`<group>`/{register.go, `<version>`/register.go} to register
|
2. Create pkg/apis/`<group>`/{register.go, `<version>`/register.go} to register
|
||||||
this group's API objects to the encoding/decoding scheme (e.g.,
|
this group's API objects to the encoding/decoding scheme (e.g.,
|
||||||
[pkg/apis/extensions/register.go](../../pkg/apis/extensions/register.go) and
|
[pkg/apis/authentication/register.go](../../pkg/apis/authentication/register.go) and
|
||||||
[pkg/apis/extensions/v1beta1/register.go](../../pkg/apis/extensions/v1beta1/register.go);
|
[pkg/apis/authentication/v1beta1/register.go](../../pkg/apis/authentication/v1beta1/register.go);
|
||||||
|
|
||||||
3. Add a pkg/apis/`<group>`/install/install.go, which is responsible for adding
|
3. Add a pkg/apis/`<group>`/install/install.go, which is responsible for adding
|
||||||
the group to the `latest` package, so that other packages can access the group's
|
the group to the `latest` package, so that other packages can access the group's
|
||||||
meta through `latest.Group`. You probably only need to change the name of group
|
meta through `latest.Group`. You probably only need to change the name of group
|
||||||
and version in the [example](../../pkg/apis/extensions/install/install.go)). You
|
and version in the [example](../../pkg/apis/authentication/install/install.go)). You
|
||||||
need to import this `install` package in {pkg/master,
|
need to import this `install` package in {pkg/master,
|
||||||
pkg/client/unversioned}/import_known_versions.go, if you want to make your group
|
pkg/client/unversioned}/import_known_versions.go, if you want to make your group
|
||||||
accessible to other packages in the kube-apiserver binary, binaries that uses
|
accessible to other packages in the kube-apiserver binary, binaries that uses
|
||||||
|
@ -83,7 +83,10 @@ cmd/libs/go2idl/ tool.
|
||||||
with the comment `// +k8s:conversion-gen=<internal-pkg>`, to catch the
|
with the comment `// +k8s:conversion-gen=<internal-pkg>`, to catch the
|
||||||
attention of our generation tools. For most APIs the only target you
|
attention of our generation tools. For most APIs the only target you
|
||||||
need is `k8s.io/kubernetes/pkg/apis/<group>` (your internal API).
|
need is `k8s.io/kubernetes/pkg/apis/<group>` (your internal API).
|
||||||
4. Run hack/update-all.sh.
|
3. Make sure your `pkg/apis/<group>` and `pkg/apis/<group>/<version>` directories
|
||||||
|
have a doc.go file with the comment `+groupName=<group>.k8s.io`, to correctly
|
||||||
|
generate the DNS-suffixed group name.
|
||||||
|
5. Run hack/update-all.sh.
|
||||||
|
|
||||||
2. Generate files for Ugorji codec:
|
2. Generate files for Ugorji codec:
|
||||||
|
|
||||||
|
|
|
@ -519,7 +519,7 @@ hack/update-codecgen.sh
|
||||||
This section is under construction, as we make the tooling completely generic.
|
This section is under construction, as we make the tooling completely generic.
|
||||||
|
|
||||||
At the moment, you'll have to make a new directory under `pkg/apis/`; copy the
|
At the moment, you'll have to make a new directory under `pkg/apis/`; copy the
|
||||||
directory structure from `pkg/apis/extensions`. Add the new group/version to all
|
directory structure from `pkg/apis/authentication`. Add the new group/version to all
|
||||||
of the `hack/{verify,update}-generated-{deep-copy,conversions,swagger}.sh` files
|
of the `hack/{verify,update}-generated-{deep-copy,conversions,swagger}.sh` files
|
||||||
in the appropriate places--it should just require adding your new group/version
|
in the appropriate places--it should just require adding your new group/version
|
||||||
to a bash array. See [docs on adding an API group](adding-an-APIGroup.md) for
|
to a bash array. See [docs on adding an API group](adding-an-APIGroup.md) for
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
Copyright 2016 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package master
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/apimachinery/registered"
|
||||||
|
"k8s.io/kubernetes/pkg/util/sets"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGroupVersions(t *testing.T) {
|
||||||
|
// legacyUnsuffixedGroups contains the groups released prior to deciding that kubernetes API groups should be dns-suffixed
|
||||||
|
// new groups should be suffixed with ".k8s.io" (https://github.com/kubernetes/kubernetes/pull/31887#issuecomment-244462396)
|
||||||
|
legacyUnsuffixedGroups := sets.NewString(
|
||||||
|
"",
|
||||||
|
"apps",
|
||||||
|
"autoscaling",
|
||||||
|
"batch",
|
||||||
|
"componentconfig",
|
||||||
|
"extensions",
|
||||||
|
"federation",
|
||||||
|
"policy",
|
||||||
|
)
|
||||||
|
|
||||||
|
// No new groups should be added to the legacyUnsuffixedGroups exclusion list
|
||||||
|
if len(legacyUnsuffixedGroups) != 8 {
|
||||||
|
t.Errorf("No additional unnamespaced groups should be created")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, gv := range registered.RegisteredGroupVersions() {
|
||||||
|
if !strings.HasSuffix(gv.Group, ".k8s.io") && !legacyUnsuffixedGroups.Has(gv.Group) {
|
||||||
|
t.Errorf("Group %s does not have the standard kubernetes API group suffix of .k8s.io", gv.Group)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue