-
Notifications
You must be signed in to change notification settings - Fork 5
/
apply_f.go
69 lines (62 loc) · 2.21 KB
/
apply_f.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package k8s
import (
"bytes"
"context"
"io/ioutil"
"regexp"
utilerrors "github.com/forbearing/k8s/util/errors"
"github.com/sirupsen/logrus"
apierrors "k8s.io/apimachinery/pkg/api/errors"
)
// ApplyF work like "kubectl apply -f filename.yaml -n test",
// The namespace defined in yaml have higher precedence than namespace specified here.
func ApplyF(ctx context.Context, kubeconfig, filename string, namespace string, opts ...Options) error {
handler, err := New(ctx, kubeconfig, namespace)
if err != nil {
return err
}
yamlData, err := ioutil.ReadFile(filename)
if err != nil {
return err
}
// Remove all comments from yaml documents.
removeComments := regexp.MustCompile(`#.*`)
yamlData = removeComments.ReplaceAll(yamlData, []byte(""))
// Split yaml documents into multiple single yaml document base on the delimiter("---")
yamlList := bytes.Split(yamlData, []byte("---"))
for _, item := range yamlList {
// If the yaml document is empty, skip create it.
if len(bytes.TrimSpace(item)) == 0 {
continue
}
// If the k8s resource is cluster scope, the namespace specified in dynamic.New() will be ignored.
// If the k8s resource is namespace scope and no namespace is defined in yaml file, then
// dynaimc hanler will create the k8s resource is the namespace specified in dynamic.New().
// (namespace defined in yaml file have higher precedence than specified in dynamic.New())
_, err = handler.Apply(item)
for _, opt := range opts {
switch opt {
case IgnoreAlreadyExists:
err = utilerrors.IgnoreAlreadyExists(err)
case IgnoreNotFound:
err = utilerrors.IgnoreNotFound(err)
case IgnoreInvalid:
err = utilerrors.IgnoreInvalid(err)
}
}
// If the error returned by dynamic handler is "AlreadyExists" or "Invalid",
// just output the error message continue handle the next itmes.
// You can call ApplyF() with IgnoreInvalid or/and IgnoreInvalid options to
// ignore these errors.
// A "Invalid" error will occurrs when you update the pod/job/persistentvolume resource.
if err != nil && (apierrors.IsAlreadyExists(err) || apierrors.IsInvalid(err)) {
logrus.Error(err)
continue
}
// Unexpected error, return it.
if err != nil {
return err
}
}
return nil
}