Skip to content

Commit 7dbb653

Browse files
bqniubinqiniu
and
binqiniu
authored
feat: create apiextensions-apiserver resource with file (#1776)
Co-authored-by: binqiniu <[email protected]>
1 parent 60d3d54 commit 7dbb653

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

Diff for: pkg/util/apiclient/idempotency.go

+14
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import (
3636
corev1 "k8s.io/api/core/v1"
3737
extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
3838
rbac "k8s.io/api/rbac/v1"
39+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
3940
apierrors "k8s.io/apimachinery/pkg/api/errors"
4041
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
4142
"k8s.io/apimachinery/pkg/fields"
@@ -47,6 +48,7 @@ import (
4748
kubeaggregatorclientset "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
4849
utilsnet "k8s.io/utils/net"
4950
controllerutils "tkestack.io/tke/pkg/controller"
51+
aaclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
5052
)
5153

5254
// PlatformLabel represents the type of platform.tkestack.io related label.
@@ -430,6 +432,18 @@ func CreateOrUpdateAPIService(ctx context.Context, client kubeaggregatorclientse
430432
return nil
431433
}
432434

435+
436+
// CreateOrUpdateCustomResourceDefinition creates a CustomResourceDefinition if the target resource doesn't exist. If the resource exists already, this function will update the resource instead.
437+
func CreateOrUpdateCustomResourceDefinition(ctx context.Context, client aaclientset.Interface, crd *apiextensionsv1.CustomResourceDefinition) error {
438+
if _, err := client.ApiextensionsV1().CustomResourceDefinitions().Create(ctx, crd, metav1.CreateOptions{}); err != nil {
439+
// Note: We don't run .Update here afterwards as that's probably not required
440+
if !apierrors.IsAlreadyExists(err) {
441+
return errors.Wrap(err, "unable to create apiservice")
442+
}
443+
}
444+
return nil
445+
}
446+
433447
// CreateOrUpdateConfigMapFromFile like kubectl apply configmap --from-file
434448
func CreateOrUpdateConfigMapFromFile(ctx context.Context, client clientset.Interface, cm *corev1.ConfigMap, pattern string) error {
435449
matches, err := filepath.Glob(pattern)

Diff for: pkg/util/apiclient/install.go

+69
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ import (
4040
apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
4141
kubeaggregator "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
4242
"tkestack.io/tke/pkg/util/template"
43+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
44+
aaclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
4345
)
4446

4547
type object struct {
@@ -49,11 +51,13 @@ type object struct {
4951
var (
5052
handlers map[string]func(context.Context, kubernetes.Interface, []byte) error
5153
kaHandlers map[string]func(context.Context, kubeaggregator.Interface, []byte) error
54+
aaHandlers map[string]func(context.Context, aaclientset.Interface, []byte) error
5255
)
5356

5457
func init() {
5558
handlers = make(map[string]func(context.Context, kubernetes.Interface, []byte) error)
5659
kaHandlers = make(map[string]func(context.Context, kubeaggregator.Interface, []byte) error)
60+
aaHandlers = make(map[string]func(context.Context, aaclientset.Interface, []byte) error)
5761

5862
// apiregistration
5963
kaHandlers["APIService"] = func(ctx context.Context, client kubeaggregator.Interface, data []byte) error {
@@ -68,6 +72,19 @@ func init() {
6872
return nil
6973
}
7074

75+
//add CustomResourceDefinition
76+
aaHandlers["CustomResourceDefinition"] = func(ctx context.Context, client aaclientset.Interface, data []byte) error {
77+
obj := new(apiextensionsv1.CustomResourceDefinition)
78+
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), data, obj); err != nil {
79+
return errors.Wrapf(err, "unable to decode %s", reflect.TypeOf(obj).String())
80+
}
81+
err := CreateOrUpdateCustomResourceDefinition(ctx, client, obj)
82+
if err != nil {
83+
return err
84+
}
85+
return nil
86+
}
87+
7188
// core
7289
handlers["ConfigMap"] = func(ctx context.Context, client kubernetes.Interface, data []byte) error {
7390
obj := new(corev1.ConfigMap)
@@ -406,3 +423,55 @@ func CreateKAResourceWithFile(ctx context.Context, client kubernetes.Interface,
406423

407424
return nil
408425
}
426+
427+
428+
429+
// CreateAsResourceWithFile create k8s and apiextensions-apiserver resource with file
430+
func CreateAsResourceWithFile(ctx context.Context, client kubernetes.Interface, aaClient aaclientset.Interface, filename string, option interface{}) error {
431+
var (
432+
data []byte
433+
err error
434+
)
435+
if option != nil {
436+
data, err = template.ParseFile(filename, option)
437+
} else {
438+
data, err = ioutil.ReadFile(filename)
439+
}
440+
if err != nil {
441+
return err
442+
}
443+
444+
items := strings.Split(string(data), "\n---")
445+
for _, item := range items {
446+
objBytes := []byte(item)
447+
obj := new(object)
448+
err := yaml.Unmarshal(objBytes, obj)
449+
if err != nil {
450+
return err
451+
}
452+
if obj.Kind == "" {
453+
continue
454+
}
455+
if obj.Kind == "CustomResourceDefinition" {
456+
f, ok := aaHandlers[obj.Kind]
457+
if !ok {
458+
return errors.Errorf("unsupport kind %q", obj.Kind)
459+
}
460+
err = f(ctx, aaClient, objBytes)
461+
if err != nil {
462+
return err
463+
}
464+
} else {
465+
f, ok := handlers[obj.Kind]
466+
if !ok {
467+
return errors.Errorf("unsupport kind %q", obj.Kind)
468+
}
469+
err = f(ctx, client, objBytes)
470+
if err != nil {
471+
return err
472+
}
473+
}
474+
}
475+
476+
return nil
477+
}

0 commit comments

Comments
 (0)