/
manifests.go
124 lines (104 loc) · 2.69 KB
/
manifests.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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package kubernetes
import (
"context"
"fmt"
apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/cli-runtime/pkg/resource"
"k8s.io/client-go/kubernetes/scheme"
"github.com/slimtoolkit/slim/pkg/app/master/config"
)
// TODO: Start supporting CRDs - currently the hardcoded client-go scheme usage
// will likely make the manifests containing CRDs fail.
type Manifests struct {
infos []*resource.Info
client *Client
resourceBuilderFn ResourceBuilderFunc
}
func ManifestsFromFiles(
opts config.KubernetesOptions,
client *Client,
resourceBuilderFn ResourceBuilderFunc,
) (*Manifests, error) {
namespace := opts.Target.Namespace
if namespace == "" {
namespace = namespaceDefault
}
infos, err := resourceBuilderFn().
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
NamespaceParam(namespace).
DefaultNamespace().
FilenameParam(
false,
&resource.FilenameOptions{
Filenames: opts.Manifests,
Recursive: true,
}).
Do().
Infos()
if err != nil {
return nil, err
}
return &Manifests{
infos: infos,
client: client,
resourceBuilderFn: resourceBuilderFn,
}, nil
}
func (ms *Manifests) Find(target config.KubernetesTarget) (*resource.Info, error) {
mapping, err := ms.resourceBuilderFn().
Local().
WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
NamespaceParam("not-really-used").
ResourceTypeOrNameArgs(true, target.Workload).
SingleResourceType().
Do().
ResourceMapping()
if err != nil {
return nil, err
}
name, err := target.WorkloadName()
if err != nil {
return nil, err
}
matches := []*resource.Info{}
for _, info := range ms.infos {
if info.Mapping.GroupVersionKind.GroupKind() != mapping.GroupVersionKind.GroupKind() {
continue
}
if info.Name != name {
continue
}
if target.Namespace != "" && target.Namespace != info.Namespace {
continue
}
matches = append(matches, info)
}
if len(matches) == 0 {
return nil, nil
}
if len(matches) > 1 {
return nil, fmt.Errorf("found more than 1 workload '%s/%s' match in the supplied manifests", target.Namespace, name)
}
return matches[0], nil
}
func (ms *Manifests) Apply(ctx context.Context, predicate func(info *resource.Info) bool) error {
for _, info := range ms.infos {
if !predicate(info) {
continue
}
if err := ms.client.CreateOrUpdate(ctx, info); err != nil {
// TODO: consider partial applying
return err
}
}
return nil
}
func (ms *Manifests) Delete(ctx context.Context) error {
for _, info := range ms.infos {
if err := ms.client.Delete(ctx, info); err != nil && !apierrors.IsNotFound(err) {
// TODO: consider partial deletion
return err
}
}
return nil
}