Skip to content

Commit ba82b00

Browse files
committed
create v1alpha1 aggregated api server
The aggregated API server serves the Hive v1alpha1 API as a proxy to the Hive v1 API. This code is based upon github.com/openshift/[email protected].
1 parent c4f0d79 commit ba82b00

File tree

104 files changed

+18127
-2
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+18127
-2
lines changed

Makefile

+12-2
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ test-e2e-postinstall:
6262

6363
# Builds all of hive's binaries (including utils).
6464
.PHONY: build
65-
build: manager hiveutil hiveadmission operator
65+
build: manager hiveutil hiveadmission operator hive-apiserver
6666

6767

6868
# Build manager binary
@@ -84,6 +84,11 @@ hiveutil: generate
8484
hiveadmission:
8585
go build -o bin/hiveadmission github.com/openshift/hive/cmd/hiveadmission
8686

87+
# Build v1alpha1 aggregated API server
88+
.PHONY: hive-apiserver
89+
hive-apiserver:
90+
go build -o bin/hive-apiserver github.com/openshift/hive/cmd/hive-apiserver
91+
8792
# Run against the configured Kubernetes cluster in ~/.kube/config
8893
.PHONY: run
8994
run: generate fmt vet
@@ -117,7 +122,8 @@ manifests: crd
117122
# Generate CRD yaml from our api types:
118123
.PHONY: crd
119124
crd:
120-
go run vendor/sigs.k8s.io/controller-tools/cmd/controller-gen/main.go crd
125+
# The apis-path is explicitly specified so that CRDs are not created for v1alpha1
126+
go run tools/vendor/sigs.k8s.io/controller-tools/cmd/controller-gen/main.go crd --apis-path=pkg/apis/hive/v1
121127

122128
# Run go fmt against code
123129
.PHONY: fmt
@@ -148,6 +154,10 @@ verify-lint:
148154
@echo Verifying golint
149155
@sh -c \
150156
'for file in $(GOFILES) ; do \
157+
if [[ $$file == "pkg/api/validation"* ]]; then continue; fi; \
158+
if [[ $$file == "pkg/hive/apis/hive/hiveconfig_types.go" ]]; then continue; fi; \
159+
if [[ $$file == "pkg/hive/apis/hive/hiveconversion/"* ]]; then continue; fi; \
160+
if [[ $$file == "pkg/hive/apiserver/registry/"* ]]; then continue; fi; \
151161
golint --set_exit_status $$file || exit 1 ; \
152162
done'
153163

cmd/hive-apiserver/main.go

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
package main
2+
3+
import (
4+
goflag "flag"
5+
"fmt"
6+
"math/rand"
7+
"os"
8+
"runtime"
9+
"time"
10+
11+
"github.com/spf13/cobra"
12+
"github.com/spf13/pflag"
13+
14+
genericapiserver "k8s.io/apiserver/pkg/server"
15+
utilflag "k8s.io/component-base/cli/flag"
16+
"k8s.io/component-base/logs"
17+
18+
"github.com/openshift/hive/pkg/cmd/hive-apiserver"
19+
)
20+
21+
func main() {
22+
stopCh := genericapiserver.SetupSignalHandler()
23+
24+
rand.Seed(time.Now().UTC().UnixNano())
25+
26+
pflag.CommandLine.SetNormalizeFunc(utilflag.WordSepNormalizeFunc)
27+
pflag.CommandLine.AddGoFlagSet(goflag.CommandLine)
28+
29+
logs.InitLogs()
30+
defer logs.FlushLogs()
31+
32+
if len(os.Getenv("GOMAXPROCS")) == 0 {
33+
runtime.GOMAXPROCS(runtime.NumCPU())
34+
}
35+
36+
command := NewHiveAPIServerCommand(stopCh)
37+
if err := command.Execute(); err != nil {
38+
fmt.Fprintf(os.Stderr, "%v\n", err)
39+
os.Exit(1)
40+
}
41+
}
42+
43+
func NewHiveAPIServerCommand(stopCh <-chan struct{}) *cobra.Command {
44+
cmd := &cobra.Command{
45+
Use: "hive-apiserver",
46+
Short: "Command for the Hive v1alpha1 API Server",
47+
Run: func(cmd *cobra.Command, args []string) {
48+
cmd.Help()
49+
os.Exit(1)
50+
},
51+
}
52+
start := hiveapiserver.NewHiveAPIServerCommand("start", os.Stdout, os.Stderr, stopCh)
53+
cmd.AddCommand(start)
54+
55+
return cmd
56+
}
+146
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
apiVersion: v1
2+
kind: Template
3+
metadata:
4+
name: apiserver-template
5+
6+
parameters:
7+
- name: SVC_NAME
8+
displayName: Service Name
9+
description: The name of the hive v1alpha1 aggregated API server service.
10+
value: hiveapi
11+
- name: SVC_NAMESPACE
12+
displayName: Service Namespace
13+
description: The namespace in which the hivev1alpha1 aggregated API server runs.
14+
value: hive
15+
- name: HIVEAPI_IMAGE
16+
displayName: Hive v1alpha1 API Server Image
17+
description: Image of the Hive v1alpha1 aggregated API Server
18+
value: 172.17.0.1:5000/hive:latest
19+
- name: CA_CRT
20+
displayName: Hive v1alpha1 CA CRT
21+
description: base64-encoded CA CRT for the hive v1alpha1 aggregated API Server
22+
required: true
23+
- name: TLS_CRT
24+
displayName: Hive v1alpha1 TLS CRT
25+
description: base-64 encoded TLS CRT for the hive v1alpha1 aggregated API Server
26+
required: true
27+
- name: TLS_KEY
28+
displayName: Hive v1alpha1 TLS KEY
29+
description: base-64 encoded TLS key for the hive v1alpha1 aggregated API Server
30+
required: true
31+
32+
objects:
33+
- apiVersion: v1
34+
kind: Namespace
35+
metadata:
36+
name: ${SVC_NAMESPACE}
37+
38+
- apiVersion: apiregistration.k8s.io/v1
39+
kind: APIService
40+
metadata:
41+
name: v1alpha1.hive.openshift.io
42+
labels:
43+
api: hiveapi
44+
apiserver: "true"
45+
spec:
46+
version: v1alpha1
47+
group: hive.openshift.io
48+
groupPriorityMinimum: 2000
49+
service:
50+
name: ${SVC_NAME}
51+
namespace: ${SVC_NAMESPACE}
52+
versionPriority: 10
53+
caBundle: ${CA_CRT}
54+
55+
- apiVersion: v1
56+
kind: Service
57+
metadata:
58+
name: ${SVC_NAME}
59+
namespace: ${SVC_NAMESPACE}
60+
labels:
61+
api: ${SVC_NAME}
62+
apiserver: "true"
63+
spec:
64+
ports:
65+
- port: 443
66+
protocol: TCP
67+
targetPort: 443
68+
selector:
69+
api: ${SVC_NAME}
70+
apiserver: "true"
71+
72+
- apiVersion: apps/v1beta1
73+
kind: Deployment
74+
metadata:
75+
name: ${SVC_NAME}
76+
namespace: ${SVC_NAMESPACE}
77+
labels:
78+
api: ${SVC_NAME}
79+
apiserver: "true"
80+
spec:
81+
replicas: 1
82+
template:
83+
metadata:
84+
labels:
85+
api: ${SVC_NAME}
86+
apiserver: "true"
87+
etcd: ${SVC_NAME}
88+
spec:
89+
containers:
90+
- name: apiserver
91+
image: ${HIVEAPI_IMAGE}
92+
volumeMounts:
93+
- name: apiserver-certs
94+
mountPath: /apiserver.local.config/certificates
95+
readOnly: true
96+
command:
97+
- "hive-apiserver"
98+
args:
99+
- "start"
100+
- "--tls-cert-file=/apiserver.local.config/certificates/tls.crt"
101+
- "--tls-private-key-file=/apiserver.local.config/certificates/tls.key"
102+
resources:
103+
requests:
104+
cpu: 100m
105+
memory: 20Mi
106+
limits:
107+
cpu: 100m
108+
memory: 30Mi
109+
serviceAccountName: ${SVC_NAME}-sa
110+
volumes:
111+
- name: apiserver-certs
112+
secret:
113+
secretName: ${SVC_NAME}
114+
115+
- apiVersion: v1
116+
kind: Secret
117+
type: kubernetes.io/tls
118+
metadata:
119+
name: ${SVC_NAME}
120+
namespace: ${SVC_NAMESPACE}
121+
labels:
122+
api: ${SVC_NAME}
123+
apiserver: "true"
124+
data:
125+
tls.crt: ${TLS_CRT}
126+
tls.key: ${TLS_KEY}
127+
128+
- apiVersion: v1
129+
kind: ServiceAccount
130+
metadata:
131+
name: ${SVC_NAME}-sa
132+
namespace: ${SVC_NAMESPACE}
133+
134+
- apiVersion: rbac.authorization.k8s.io/v1
135+
kind: ClusterRoleBinding
136+
metadata:
137+
name: ${SVC_NAME}-cluster-admin
138+
namespace: ${SVC_NAMESPACE}
139+
subjects:
140+
- kind: ServiceAccount
141+
name: ${SVC_NAME}-sa
142+
namespace: ${SVC_NAMESPACE}
143+
roleRef:
144+
kind: ClusterRole
145+
name: cluster-admin
146+
apiGroup: rbac.authorization.k8s.io

golangci.yml

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
run:
22
deadline: 30m
3+
skip-files:
4+
- pkg/hive/apis/hive/hiveconfig_types.go
5+
- pkg/hive/apis/hive/hiveconversion/conversion.go
36

47
linters:
58
disable-all: true

pkg/api/doc.go

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// Package api should not be used.
2+
package api

pkg/api/install/install.go

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package install
2+
3+
import (
4+
"k8s.io/apimachinery/pkg/runtime"
5+
6+
hivev1alpha1 "github.com/openshift/hive/pkg/hive/apis/hive/install"
7+
)
8+
9+
// InternalHive install the Hive API for internal consumption
10+
func InternalHive(scheme *runtime.Scheme) {
11+
hivev1alpha1.Install(scheme)
12+
}

pkg/api/serialization_test.go

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package api_test
2+
3+
import (
4+
_ "k8s.io/kubernetes/pkg/apis/core/install"
5+
// install all APIs
6+
_ "github.com/openshift/hive/pkg/api/install"
7+
)
8+
9+
// TODO (staebler): Determine if these round-trip serialization tests offer value for Hive's use-case.
10+
/*
11+
func v1alpha1Fuzzer(t *testing.T, seed int64) *fuzz.Fuzzer {
12+
f := fuzzer.FuzzerFor(kapitesting.FuzzerFuncs, rand.NewSource(seed), legacyscheme.Codecs)
13+
f.Funcs(
14+
func(j *hiveapi.ClusterImageSet, c fuzz.Continue) {
15+
c.FuzzNoCustom(j)
16+
},
17+
18+
func(j *runtime.Object, c fuzz.Continue) {
19+
// runtime.EmbeddedObject causes a panic inside of fuzz because runtime.Object isn't handled.
20+
},
21+
func(t *time.Time, c fuzz.Continue) {
22+
// This is necessary because the standard fuzzed time.Time object is
23+
// completely nil, but when JSON unmarshals dates it fills in the
24+
// unexported loc field with the time.UTC object, resulting in
25+
// reflect.DeepEqual returning false in the round trip tests. We solve it
26+
// by using a date that will be identical to the one JSON unmarshals.
27+
*t = time.Date(2000, 1, 1, 1, 1, 1, 0, time.UTC)
28+
},
29+
func(u64 *uint64, c fuzz.Continue) {
30+
// TODO: uint64's are NOT handled right.
31+
*u64 = c.RandUint64() >> 8
32+
},
33+
)
34+
return f
35+
}
36+
37+
const fuzzIters = 20
38+
39+
// For debugging problems
40+
func TestSpecificKind(t *testing.T) {
41+
seed := int64(2703387474910584091)
42+
fuzzer := v1alpha1Fuzzer(t, seed)
43+
44+
legacyscheme.Scheme.Log(t)
45+
defer legacyscheme.Scheme.Log(nil)
46+
47+
gvk := hiveapi.SchemeGroupVersion.WithKind("ClusterImageSet")
48+
// TODO: make upstream CodecFactory customizable
49+
codecs := serializer.NewCodecFactory(legacyscheme.Scheme)
50+
for i := 0; i < fuzzIters; i++ {
51+
roundtrip.RoundTripSpecificKindWithoutProtobuf(t, gvk, legacyscheme.Scheme, codecs, fuzzer, nil)
52+
}
53+
}
54+
55+
// TestRoundTripTypes applies the round-trip test to all round-trippable Kinds
56+
// in all of the API groups registered for test in the testapi package.
57+
func TestRoundTripTypes(t *testing.T) {
58+
seed := rand.Int63()
59+
fuzzer := v1alpha1Fuzzer(t, seed)
60+
61+
roundtrip.RoundTripTypes(t, legacyscheme.Scheme, legacyscheme.Codecs, fuzzer, nil)
62+
}
63+
*/

pkg/api/validation/register.go

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package validation
2+
3+
import (
4+
hivevalidation "github.com/openshift/hive/pkg/hive/apis/hive/validation"
5+
// required to be loaded before we register
6+
_ "github.com/openshift/hive/pkg/api/install"
7+
hiveapi "github.com/openshift/hive/pkg/hive/apis/hive"
8+
)
9+
10+
func init() {
11+
registerAll()
12+
}
13+
14+
func registerAll() {
15+
Validator.MustRegister(&hiveapi.ClusterImageSet{}, false, hivevalidation.ValidateClusterImageSet, hivevalidation.ValidateClusterImageSetUpdate)
16+
}

0 commit comments

Comments
 (0)