Skip to content

Commit

Permalink
Add aggregated apiserver skeleton and toolchain
Browse files Browse the repository at this point in the history
Signed-off-by: Aylei <rayingecho@gmail.com>
  • Loading branch information
aylei committed Oct 28, 2019
1 parent f0cfe98 commit 0fa2977
Show file tree
Hide file tree
Showing 11 changed files with 726 additions and 0 deletions.
30 changes: 30 additions & 0 deletions cmd/apiserver/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
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 main

import (
_ "github.com/go-openapi/loads"
_ "github.com/ugorji/go/codec"

"github.com/pingcap/tidb-operator/pkg/apiserver/cmd"
"github.com/pingcap/tidb-operator/pkg/version"
_ "k8s.io/client-go/plugin/pkg/client/auth" // Enable cloud provider auth
)

func main() {
cmd.StartApiServer(nil, nil, "Api", version.Get().GitVersion)
}
90 changes: 90 additions & 0 deletions docs/adding-resource-in-aa.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# Adding New Resources in TiDB Aggregated Apiserver

> This guide shows an example about how to add new resources in TiDB Aggregated Apiserver (AA)
## Project Structure

```shell
pkg/apiserver # package root of AA
pkg/apiserver/apis # all apis of AA
pkg/apiserver/apis/{group}/ # un-versioned apis of a group
pkg/apiserver/apis/{group}/{version} # versiond apis of a group
pkg/apiserver/apis/{group}/{version}/{kind}_types.go # type definition of a certain kind
pkg/apiserver/client # generated go client
pkg/apiserver/cmd # AA entrypoint
pkg/apiserver/openapi # generated openapi definition
pkg/apiserver/storage # kube-apiserver based storage implementation
```

We will create the type definition of a versioned resource in `pkg/apiserver/apis/{group}/{version}/{kind}_types.go`.

The defaults function, conversion from un-versioned to versioned, OpenAPI definition and client of the versioned resource will be generated automatically.

The type definition, REST storage, defaults function, conversion from versioned to un-versioned and client of the un-versioned resources will also be generated automatically.

## Foo Example

Let's add a new resource `foos.v1alpha1.tidb.pingcap.com`:

- `kind`: foos
- `version`: v1alpha1
- `group`: tidb.pingcap.com

1. Create packages:

```shell
$ mkdir -p pkg/apiserver/apis/tidb/v1alpha1
```

**By convention, we take the sub domain of the group name as the package name.**

2. Write group name and code-generation markers for all resources under `v1alpha.tidb.pingcap.com`:

`pkg/apiserver/apis/tidb/v1alpha1/doc.go`

```
// +k8s:openapi-gen=true
// +k8s:deepcopy-gen=package,register
// +k8s:conversion-gen=github.com/pingcap/tidb-operator/pkg/apiserver/apis/tidb
// +k8s:defaulter-gen=TypeMeta

// +groupName=tidb.pingcap.com
package v1alpha1 // import "github.com/pingcap/tidb-operator/pkg/apiserver/apis/tidb/v1alpha1"
```

3. Write the type definition and code generation markers for Foo:

`pkg/apiserver/apis/tidb/v1alpha1/foo_types.go`:

```go
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// Foo
// +k8s:openapi-gen=true
// +resource:path=foos
type Foo struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec FooSpec `json:"spec,omitempty"`
Status FooStatus `json:"status,omitempty"`
}
// FooSpec defines the desired state of Foo
type FooSpec struct {
Replicas int `json:"replicas,omitempty"`
}
// FooStatus defines the observed state of Foo
type FooStatus struct {
CurrentReplicas int `json:"currentReplicas,omitempty"`
}
```

4. Run code generation:

```
./hack/code-gen.sh
```

29 changes: 29 additions & 0 deletions hack/aa-codegen.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/bin/bash -e

# Copyright 2017 PingCAP, Inc.
#
# 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,
# See the License for the specific language governing permissions and
# limitations under the License.

set -o errexit
set -o nounset
set -o pipefail

scriptdir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

${scriptdir}/generate-internal-groups.sh \
all \
github.com/pingcap/tidb-operator/pkg/apiserver \
github.com/pingcap/tidb-operator/pkg/apiserver/apis \
github.com/pingcap/tidb-operator/pkg/apiserver/apis \
"tidb.pingcap.com:v1alpha1" \
--go-header-file=${scriptdir}/boilerplate.go.txt

141 changes: 141 additions & 0 deletions hack/generate-internal-groups.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
#!/usr/bin/env bash

# Copyright 2017 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.

set -o errexit
set -o nounset
set -o pipefail

# generate-internal-groups generates everything for a project with internal types, e.g. an
# user-provided API server based on k8s.io/apiserver.

if [ "$#" -lt 5 ] || [ "${1}" == "--help" ]; then
cat <<EOF
Usage: $(basename "$0") <generators> <output-package> <internal-apis-package> <extensiona-apis-package> <groups-versions> ...
<generators> the generators comma separated to run (deepcopy,defaulter,conversion,client,lister,informer,openapi) or "all".
<output-package> the output package name (e.g. github.com/example/project/pkg/generated).
<int-apis-package> the internal types dir (e.g. github.com/example/project/pkg/apis).
<ext-apis-package> the external types dir (e.g. github.com/example/project/pkg/apis or githubcom/example/apis).
<groups-versions> the groups and their versions in the format "groupA:v1,v2 groupB:v1 groupC:v2", relative
to <api-package>.
... arbitrary flags passed to all generator binaries.
Examples:
$(basename "$0") all github.com/example/project/pkg/client github.com/example/project/pkg/apis github.com/example/project/pkg/apis "foo:v1 bar:v1alpha1,v1beta1"
$(basename "$0") deepcopy,defaulter,conversion github.com/example/project/pkg/client github.com/example/project/pkg/apis github.com/example/project/apis "foo:v1 bar:v1alpha1,v1beta1"
EOF
exit 0
fi

GENS="$1"
OUTPUT_PKG="$2"
INT_APIS_PKG="$3"
EXT_APIS_PKG="$4"
GROUPS_WITH_VERSIONS="$5"
shift 5

export GO111MODULE=on

go install k8s.io/code-generator/cmd/defaulter-gen \
k8s.io/code-generator/cmd/client-gen \
k8s.io/code-generator/cmd/lister-gen \
k8s.io/code-generator/cmd/informer-gen \
k8s.io/code-generator/cmd/deepcopy-gen \
k8s.io/code-generator/cmd/openapi-gen \
k8s.io/code-generator/cmd/conversion-gen \
k8s.io/code-generator/cmd/defaulter-gen \
github.com/kubernetes-incubator/apiserver-builder-alpha/cmd/apiregister-gen

function codegen::join() { local IFS="$1"; shift; echo "$*"; }

APIS_DIR=("${INT_APIS_PKG}/...")
CLIENT_OUTPUT_PKG=("${OUTPUT_PKG}/client")

# enumerate group versions
ALL_FQ_APIS=() # e.g. k8s.io/kubernetes/pkg/apis/apps k8s.io/api/apps/v1
INT_FQ_APIS=() # e.g. k8s.io/kubernetes/pkg/apis/apps
EXT_FQ_APIS=() # e.g. k8s.io/api/apps/v1
for GVs in ${GROUPS_WITH_VERSIONS}; do
IFS=: read -r G Vs <<<"${GVs}"
IFS=. read -r GROUP_PATH SUFFIX <<<"${G}"

if [ -n "${INT_APIS_PKG}" ]; then
ALL_FQ_APIS+=("${INT_APIS_PKG}/${GROUP_PATH}")
INT_FQ_APIS+=("${INT_APIS_PKG}/${GROUP_PATH}")
fi

# enumerate versions
for V in ${Vs//,/ }; do
ALL_FQ_APIS+=("${EXT_APIS_PKG}/${GROUP_PATH}/${V}")
EXT_FQ_APIS+=("${EXT_APIS_PKG}/${GROUP_PATH}/${V}")
done
done

# apiregister-gen generate the REST boilerplate of resources and their internal version
if [ "${GENS}" = "all" ] || grep -qw "registry" <<<"${GENS}"; then
echo "Generating api registries"
"${GOPATH}/bin/apiregister-gen" --input-dirs "$(codegen::join , "${APIS_DIR[@]}")" "$@"
fi

if [ "${GENS}" = "all" ] || grep -qw "deepcopy" <<<"${GENS}"; then
echo "Generating deepcopy funcs"
"${GOPATH}/bin/deepcopy-gen" --input-dirs "$(codegen::join , "${ALL_FQ_APIS[@]}")" -O zz_generated.deepcopy --bounding-dirs "${INT_APIS_PKG},${EXT_APIS_PKG}" "$@"
fi

if [ "${GENS}" = "all" ] || grep -qw "defaulter" <<<"${GENS}"; then
echo "Generating defaulters"
"${GOPATH}/bin/defaulter-gen" --input-dirs "$(codegen::join , "${ALL_FQ_APIS[@]}")" -O zz_generated.defaults "$@"
fi

if [ "${GENS}" = "all" ] || grep -qw "conversion" <<<"${GENS}"; then
echo "Generating conversions"
"${GOPATH}/bin/conversion-gen" --input-dirs "$(codegen::join , "${ALL_FQ_APIS[@]}")" -O zz_generated.conversion "$@"
fi

if [ "${GENS}" = "all" ] || grep -qw "client" <<<"${GENS}"; then
echo "Generating clientset for ${GROUPS_WITH_VERSIONS} at ${CLIENT_OUTPUT_PKG}/${CLIENTSET_PKG_NAME:-clientset}"
if [ -n "${INT_APIS_PKG}" ]; then
IFS=" " read -r -a APIS <<< "$(printf '%s/ ' "${INT_FQ_APIS[@]}")"
"${GOPATH}/bin/client-gen" --clientset-name "${CLIENTSET_NAME_INTERNAL:-internalversion}" --input-base "" --input "$(codegen::join , "${APIS[@]}")" --output-package "${CLIENT_OUTPUT_PKG}/${CLIENTSET_PKG_NAME:-clientset}" "$@"
fi
"${GOPATH}/bin/client-gen" --clientset-name "${CLIENTSET_NAME_VERSIONED:-versioned}" --input-base "" --input "$(codegen::join , "${EXT_FQ_APIS[@]}")" --output-package "${CLIENT_OUTPUT_PKG}/${CLIENTSET_PKG_NAME:-clientset}" "$@"
fi

if [ "${GENS}" = "all" ] || grep -qw "lister" <<<"${GENS}"; then
echo "Generating listers for ${GROUPS_WITH_VERSIONS} at ${CLIENT_OUTPUT_PKG}/listers"
"${GOPATH}/bin/lister-gen" --input-dirs "$(codegen::join , "${ALL_FQ_APIS[@]}")" --output-package "${CLIENT_OUTPUT_PKG}/listers" "$@"
fi

if [ "${GENS}" = "all" ] || grep -qw "informer" <<<"${GENS}"; then
echo "Generating informers for ${GROUPS_WITH_VERSIONS} at ${CLIENT_OUTPUT_PKG}/informers"
"${GOPATH}/bin/informer-gen" \
--input-dirs "$(codegen::join , "${ALL_FQ_APIS[@]}")" \
--versioned-clientset-package "${CLIENT_OUTPUT_PKG}/${CLIENTSET_PKG_NAME:-clientset}/${CLIENTSET_NAME_VERSIONED:-versioned}" \
--internal-clientset-package "${CLIENT_OUTPUT_PKG}/${CLIENTSET_PKG_NAME:-clientset}/${CLIENTSET_NAME_INTERNAL:-internalversion}" \
--listers-package "${CLIENT_OUTPUT_PKG}/listers" \
--output-package "${CLIENT_OUTPUT_PKG}/informers" \
"$@"
fi

if [ "${GENS}" = "all" ] || grep -qw "openapi" <<<"${GENS}"; then
echo "Generating OpenAPI definitions for ${GROUPS_WITH_VERSIONS} at ${OUTPUT_PKG}/openapi"
"${GOPATH}/bin/openapi-gen" \
--input-dirs "$(codegen::join , "${EXT_FQ_APIS[@]}")" \
--input-dirs "k8s.io/apimachinery/pkg/apis/meta/v1,k8s.io/api/core/v1" \
--output-package "${OUTPUT_PKG}/openapi" \
-O zz_generated.openapi \
"$@"
fi
16 changes: 16 additions & 0 deletions pkg/apiserver/apis/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2019. PingCAP, Inc.
//
// 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,
// See the License for the specific language governing permissions and
// limitations under the License.

// Package apis hosts all apis of aa
// +domain=pingcap.com
package apis
17 changes: 17 additions & 0 deletions pkg/apiserver/apis/tidb/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2019. PingCAP, Inc.
//
// 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,
// See the License for the specific language governing permissions and
// limitations under the License.

// Package tidb is the internal version of the tidb.pingcap.com api group.
// +k8s:deepcopy-gen=package,register
// +groupName=tidb.pingcap.com
package tidb // import "github.com/pingcap/tidb-operator/pkg/apiserver/apis/tidb"
14 changes: 14 additions & 0 deletions pkg/apiserver/apis/tidb/install/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright 2019 PingCAP, Inc.
//
// 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,
// See the License for the specific language governing permissions and
// limitations under the License.

package install
21 changes: 21 additions & 0 deletions pkg/apiserver/apis/tidb/v1alpha1/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2019. PingCAP, Inc.
//
// 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,
// See the License for the specific language governing permissions and
// limitations under the License.

// +k8s:openapi-gen=true
// +k8s:deepcopy-gen=package,register
// +k8s:conversion-gen=github.com/pingcap/tidb-operator/pkg/apiserver/apis/tidb
// +k8s:defaulter-gen=TypeMeta

// Package v1alpha1 the v1alpha1 version of the tidb.pingcap.com api group.
// +groupName=tidb.pingcap.com
package v1alpha1 // import "github.com/pingcap/tidb-operator/pkg/apiserver/apis/tidb/v1alpha1"
Loading

0 comments on commit 0fa2977

Please sign in to comment.