-
Notifications
You must be signed in to change notification settings - Fork 4.7k
/
runtimeobject_nodebuilder.go
160 lines (137 loc) · 4.92 KB
/
runtimeobject_nodebuilder.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package test
import (
"fmt"
"path/filepath"
"reflect"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
kapi "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/apis/autoscaling"
"k8s.io/kubernetes/pkg/kubectl/resource"
osgraph "github.com/openshift/origin/pkg/api/graph"
_ "github.com/openshift/origin/pkg/api/install"
kubegraph "github.com/openshift/origin/pkg/api/kubegraph/nodes"
buildapi "github.com/openshift/origin/pkg/build/apis/build"
buildgraph "github.com/openshift/origin/pkg/build/graph/nodes"
deployapi "github.com/openshift/origin/pkg/deploy/apis/apps"
deploygraph "github.com/openshift/origin/pkg/deploy/graph/nodes"
imageapi "github.com/openshift/origin/pkg/image/apis/image"
imagegraph "github.com/openshift/origin/pkg/image/graph/nodes"
routeapi "github.com/openshift/origin/pkg/route/apis/route"
routegraph "github.com/openshift/origin/pkg/route/graph/nodes"
)
// typeToEnsureMethod stores types to Ensure*Node methods
var typeToEnsureMethod = map[reflect.Type]reflect.Value{}
func init() {
if err := RegisterEnsureNode(&imageapi.Image{}, imagegraph.EnsureImageNode); err != nil {
panic(err)
}
if err := RegisterEnsureNode(&imageapi.ImageStream{}, imagegraph.EnsureImageStreamNode); err != nil {
panic(err)
}
if err := RegisterEnsureNode(&deployapi.DeploymentConfig{}, deploygraph.EnsureDeploymentConfigNode); err != nil {
panic(err)
}
if err := RegisterEnsureNode(&buildapi.BuildConfig{}, buildgraph.EnsureBuildConfigNode); err != nil {
panic(err)
}
if err := RegisterEnsureNode(&buildapi.Build{}, buildgraph.EnsureBuildNode); err != nil {
panic(err)
}
if err := RegisterEnsureNode(&routeapi.Route{}, routegraph.EnsureRouteNode); err != nil {
panic(err)
}
if err := RegisterEnsureNode(&kapi.Pod{}, kubegraph.EnsurePodNode); err != nil {
panic(err)
}
if err := RegisterEnsureNode(&kapi.Service{}, kubegraph.EnsureServiceNode); err != nil {
panic(err)
}
if err := RegisterEnsureNode(&kapi.ServiceAccount{}, kubegraph.EnsureServiceAccountNode); err != nil {
panic(err)
}
if err := RegisterEnsureNode(&kapi.Secret{}, kubegraph.EnsureSecretNode); err != nil {
panic(err)
}
if err := RegisterEnsureNode(&kapi.ReplicationController{}, kubegraph.EnsureReplicationControllerNode); err != nil {
panic(err)
}
if err := RegisterEnsureNode(&kapi.PersistentVolumeClaim{}, kubegraph.EnsurePersistentVolumeClaimNode); err != nil {
panic(err)
}
if err := RegisterEnsureNode(&autoscaling.HorizontalPodAutoscaler{}, kubegraph.EnsureHorizontalPodAutoscalerNode); err != nil {
}
}
func RegisterEnsureNode(containedType, ensureFunction interface{}) error {
ensureFunctionValue := reflect.ValueOf(ensureFunction)
ensureType := ensureFunctionValue.Type()
if err := verifyEnsureFunctionSignature(ensureType); err != nil {
return err
}
reflectedContainedType := reflect.TypeOf(containedType)
if _, exists := typeToEnsureMethod[reflectedContainedType]; exists {
return fmt.Errorf("%v is already registered", reflectedContainedType)
}
typeToEnsureMethod[reflectedContainedType] = reflect.ValueOf(ensureFunction)
return nil
}
func EnsureNode(g osgraph.Graph, obj interface{}) error {
reflectedContainedType := reflect.TypeOf(obj)
ensureMethod, exists := typeToEnsureMethod[reflectedContainedType]
if !exists {
return fmt.Errorf("%v is not registered", reflectedContainedType)
}
callEnsureNode(g, reflect.ValueOf(obj), ensureMethod)
return nil
}
func verifyEnsureFunctionSignature(ft reflect.Type) error {
if ft.Kind() != reflect.Func {
return fmt.Errorf("expected func, got: %v", ft)
}
if ft.NumIn() != 2 {
return fmt.Errorf("expected two 'in' param, got: %v", ft)
}
if ft.NumOut() != 1 {
return fmt.Errorf("expected one 'out' param, got: %v", ft)
}
if ft.In(1).Kind() != reflect.Ptr {
return fmt.Errorf("expected pointer arg for 'in' param 1, got: %v", ft)
}
return nil
}
// callEnsureNode calls 'custom' with sv & dv. custom must be a conversion function.
func callEnsureNode(g osgraph.Graph, obj, ensureMethod reflect.Value) {
args := []reflect.Value{reflect.ValueOf(g), obj}
ensureMethod.Call(args)[0].Interface()
}
func BuildGraph(path string) (osgraph.Graph, []runtime.Object, error) {
g := osgraph.New()
objs := []runtime.Object{}
abspath, err := filepath.Abs(path)
if err != nil {
return g, objs, err
}
mapper := kapi.Registry.RESTMapper()
typer := kapi.Scheme
clientMapper := resource.ClientMapperFunc(func(mapping *meta.RESTMapping) (resource.RESTClient, error) {
return nil, nil
})
r := resource.NewBuilder(mapper, typer, clientMapper, kapi.Codecs.UniversalDecoder()).
FilenameParam(false, &resource.FilenameOptions{Recursive: false, Filenames: []string{abspath}}).
Flatten().
Do()
if r.Err() != nil {
return g, objs, r.Err()
}
infos, err := r.Infos()
if err != nil {
return g, objs, err
}
for _, info := range infos {
objs = append(objs, info.Object)
if err := EnsureNode(g, info.Object); err != nil {
return g, objs, err
}
}
return g, objs, nil
}