forked from kubernetes-sigs/cluster-api
-
Notifications
You must be signed in to change notification settings - Fork 0
/
providercomponents.go
117 lines (102 loc) · 3.47 KB
/
providercomponents.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
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package providercomponents
import (
"io/ioutil"
"github.com/pkg/errors"
core "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
meta "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
v1 "k8s.io/client-go/kubernetes/typed/core/v1"
)
const (
configMapName = "clusterctl"
configMapProviderComponentsKey = "provider-components"
)
type Store struct {
// If present the provider components will be loaded from and saved to this file
ExplicitPath string
// If present and ExplicitPath is not present, provider components will be loaded and saved to this store
ConfigMap v1.ConfigMapInterface
}
func NewFromConfigMap(configMap v1.ConfigMapInterface) (*Store, error) {
store := Store{
ConfigMap: configMap,
}
return &store, nil
}
func NewFromClientset(clientset *kubernetes.Clientset) (*Store, error) {
return NewFromConfigMap(clientset.CoreV1().ConfigMaps(core.NamespaceDefault))
}
func (pc *Store) Save(providerComponents string) error {
if pc.ExplicitPath == "" {
return pc.saveToConfigMap(providerComponents)
}
return ioutil.WriteFile(pc.ExplicitPath, []byte(providerComponents), 0644)
}
func (pc *Store) Load() (string, error) {
if pc.ExplicitPath == "" {
return pc.loadFromConfigMap()
}
return pc.loadFromFile()
}
func (pc *Store) loadFromFile() (string, error) {
bytes, err := ioutil.ReadFile(pc.ExplicitPath)
if err != nil {
return "", errors.Wrapf(err, "error when loading provider components from %q", pc.ExplicitPath)
}
return string(bytes), nil
}
func (pc *Store) saveToConfigMap(providerComponents string) error {
configMap, err := pc.ConfigMap.Get(configMapName, meta.GetOptions{})
if apierrors.IsNotFound(err) {
configMap = &core.ConfigMap{
ObjectMeta: meta.ObjectMeta{
Name: configMapName,
},
}
} else if err != nil {
return errors.Wrapf(err, "unable to get configmap %q", configMapName)
}
if configMap.Data == nil {
configMap.Data = make(map[string]string)
}
configMap.Data[configMapProviderComponentsKey] = providerComponents
if err == nil {
_, err = pc.ConfigMap.Update(configMap)
if err != nil {
return errors.Wrapf(err, "error updating config map %q", configMapName)
}
} else {
_, err = pc.ConfigMap.Create(configMap)
if err != nil {
return errors.Wrapf(err, "error creating config map %q", configMapName)
}
}
return nil
}
func (pc *Store) loadFromConfigMap() (string, error) {
if pc.ConfigMap == nil {
return "", errors.New("unable to load config map: need a valid ConfigMapInterface")
}
configMap, err := pc.ConfigMap.Get(configMapName, meta.GetOptions{})
if err != nil {
return "", errors.Wrapf(err, "error getting configmap named %q", configMapName)
}
providerComponents, ok := configMap.Data[configMapProviderComponentsKey]
if !ok {
return "", errors.Errorf("configmap %q does not contain the provider components key %q", configMapName, configMapProviderComponentsKey)
}
return providerComponents, nil
}