-
Notifications
You must be signed in to change notification settings - Fork 0
/
describer.go
executable file
·172 lines (137 loc) · 5.24 KB
/
describer.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
161
162
163
164
165
166
167
168
169
170
171
172
/*
Copyright (c) 2019 VMware, Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package describer
import (
"context"
"sort"
"github.com/pkg/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
kLabels "k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"github.com/kubenext/lissio/internal/config"
"github.com/kubenext/lissio/internal/link"
"github.com/kubenext/lissio/internal/printer"
"github.com/kubenext/lissio/internal/queryer"
"github.com/kubenext/lissio/pkg/store"
"github.com/kubenext/lissio/pkg/view/component"
)
type ObjectLoaderFactory struct {
dashConfig config.Dash
}
func NewObjectLoaderFactory(dashConfig config.Dash) *ObjectLoaderFactory {
return &ObjectLoaderFactory{
dashConfig: dashConfig,
}
}
func (f *ObjectLoaderFactory) LoadObject(ctx context.Context, namespace string, fields map[string]string, objectStoreKey store.Key) (*unstructured.Unstructured, error) {
return LoadObject(ctx, f.dashConfig.ObjectStore(), namespace, fields, objectStoreKey)
}
func (f *ObjectLoaderFactory) LoadObjects(ctx context.Context, namespace string, fields map[string]string, objectStoreKeys []store.Key) (*unstructured.UnstructuredList, error) {
return LoadObjects(ctx, f.dashConfig.ObjectStore(), namespace, fields, objectStoreKeys)
}
// loadObject loads a single object from the object store.
func LoadObject(ctx context.Context, objectStore store.Store, namespace string, fields map[string]string, objectStoreKey store.Key) (*unstructured.Unstructured, error) {
objectStoreKey.Namespace = namespace
if name, ok := fields["name"]; ok && name != "" {
objectStoreKey.Name = name
}
object, found, err := objectStore.Get(ctx, objectStoreKey)
if err != nil {
return nil, err
}
if !found {
return nil, errors.Errorf("object was not found")
}
return object, nil
}
// loadObjects loads objects from the object store sorted by their name.
func LoadObjects(ctx context.Context, objectStore store.Store, namespace string, fields map[string]string, objectStoreKeys []store.Key) (*unstructured.UnstructuredList, error) {
list := &unstructured.UnstructuredList{}
for _, objectStoreKey := range objectStoreKeys {
objectStoreKey.Namespace = namespace
if name, ok := fields["name"]; ok && name != "" {
objectStoreKey.Name = name
}
storedObjects, _, err := objectStore.List(ctx, objectStoreKey)
if err != nil {
return nil, err
}
list.Items = append(list.Items, storedObjects.Items...)
}
sort.SliceStable(list.Items, func(i, j int) bool {
a, b := list.Items[i], list.Items[j]
return a.GetName() < b.GetName()
})
return list, nil
}
// LoaderFunc loads an object from the object store.
type LoaderFunc func(ctx context.Context, o store.Store, namespace string, fields map[string]string) (*unstructured.Unstructured, error)
// Options provides options to describers
type Options struct {
config.Dash
Queryer queryer.Queryer
Fields map[string]string
Printer printer.Printer
LabelSet *kLabels.Set
Link link.Interface
LoadObjects func(ctx context.Context, namespace string, fields map[string]string, objectStoreKeys []store.Key) (*unstructured.UnstructuredList, error)
LoadObject func(ctx context.Context, namespace string, fields map[string]string, objectStoreKey store.Key) (*unstructured.Unstructured, error)
}
// Describer creates content.
type Describer interface {
Describe(ctx context.Context, namespace string, options Options) (component.ContentResponse, error)
PathFilters() []PathFilter
Reset(ctx context.Context) error
}
type base struct{}
func (b base) Describe(ctx context.Context, namespace string, options Options) (component.ContentResponse, error) {
return component.EmptyContentResponse, nil
}
func (b base) PathFilters() []PathFilter {
return nil
}
func (b base) Reset(ctx context.Context) error {
return nil
}
var _ Describer = (*base)(nil)
func newBaseDescriber() *base {
return &base{}
}
func copyObjectMeta(to interface{}, from *unstructured.Unstructured) error {
object, ok := to.(metav1.Object)
if !ok {
return errors.Errorf("%T is not an object", to)
}
t, err := meta.TypeAccessor(object)
if err != nil {
return errors.Wrapf(err, "accessing type meta")
}
t.SetAPIVersion(from.GetAPIVersion())
t.SetKind(from.GetObjectKind().GroupVersionKind().Kind)
object.SetNamespace(from.GetNamespace())
object.SetName(from.GetName())
object.SetGenerateName(from.GetGenerateName())
object.SetUID(from.GetUID())
object.SetResourceVersion(from.GetResourceVersion())
object.SetGeneration(from.GetGeneration())
object.SetSelfLink(from.GetSelfLink())
object.SetCreationTimestamp(from.GetCreationTimestamp())
object.SetDeletionTimestamp(from.GetDeletionTimestamp())
object.SetDeletionGracePeriodSeconds(from.GetDeletionGracePeriodSeconds())
object.SetLabels(from.GetLabels())
object.SetAnnotations(from.GetAnnotations())
object.SetInitializers(from.GetInitializers())
object.SetOwnerReferences(from.GetOwnerReferences())
object.SetClusterName(from.GetClusterName())
object.SetFinalizers(from.GetFinalizers())
return nil
}
func isPod(object runtime.Object) bool {
gvk := object.GetObjectKind().GroupVersionKind()
apiVersion, kind := gvk.ToAPIVersionAndKind()
return apiVersion == "v1" && kind == "Pod"
}