Doc API group suffix, add test to catch new groups

pull/6/head
Jordan Liggitt 2016-09-08 16:21:58 -04:00
parent cd30526b44
commit 620cc66ead
No known key found for this signature in database
GPG Key ID: 24E7ADF9A3B42012
5 changed files with 76 additions and 22 deletions

View File

@ -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

View File

@ -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"

View File

@ -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:

View File

@ -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

View File

@ -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)
}
}
}