1 package binding
2
3 import (
4 "fmt"
5 "os"
6 "path/filepath"
7
8 "github.com/devfile/library/v2/pkg/devfile/parser"
9 "gopkg.in/yaml.v2"
10 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
11 "k8s.io/apimachinery/pkg/runtime/schema"
12
13 sboApi "github.com/redhat-developer/service-binding-operator/apis/binding/v1alpha1"
14
15 "github.com/redhat-developer/odo/pkg/binding/asker"
16 backendpkg "github.com/redhat-developer/odo/pkg/binding/backend"
17 "github.com/redhat-developer/odo/pkg/kclient"
18 "github.com/redhat-developer/odo/pkg/libdevfile"
19 )
20
21 func (o *BindingClient) SelectNamespace(flags map[string]string) (string, error) {
22 var backend backendpkg.AddBindingBackend
23 if len(flags) == 0 {
24 backend = o.interactiveBackend
25 } else {
26 backend = o.flagsBackend
27 }
28 return backend.SelectNamespace(flags)
29 }
30
31
32 func (o *BindingClient) ValidateAddBinding(flags map[string]string, withDevfile bool) error {
33 var backend backendpkg.AddBindingBackend
34 if len(flags) == 0 {
35 backend = o.interactiveBackend
36 } else {
37 backend = o.flagsBackend
38 }
39 err := backend.Validate(flags, withDevfile)
40 if err != nil {
41 return err
42 }
43
44 return o.checkServiceBindingOperatorInstalled()
45 }
46
47 func (o *BindingClient) SelectServiceInstance(flags map[string]string, serviceMap map[string]unstructured.Unstructured) (string, error) {
48 var backend backendpkg.AddBindingBackend
49 if len(flags) == 0 {
50 backend = o.interactiveBackend
51 } else {
52 backend = o.flagsBackend
53 }
54 return backend.SelectServiceInstance(flags[backendpkg.FLAG_SERVICE], serviceMap)
55 }
56
57 func (o *BindingClient) SelectWorkloadInstance(flags map[string]string) (string, schema.GroupVersionKind, error) {
58 var backend backendpkg.AddBindingBackend
59 if len(flags) == 0 {
60 backend = o.interactiveBackend
61 } else {
62 backend = o.flagsBackend
63 }
64 resource, gvk, err := backend.SelectWorkloadInstance(flags[backendpkg.FLAG_WORKLOAD])
65 if err != nil {
66 return "", schema.GroupVersionKind{}, err
67 }
68 return resource, gvk, nil
69 }
70
71 func (o *BindingClient) AskBindingName(serviceName, componentName string, flags map[string]string) (string, error) {
72 var backend backendpkg.AddBindingBackend
73 if len(flags) == 0 {
74 backend = o.interactiveBackend
75 } else {
76 backend = o.flagsBackend
77 }
78 defaultBindingName := fmt.Sprintf("%v-%v", componentName, serviceName)
79 return backend.AskBindingName(defaultBindingName, flags)
80 }
81
82 func (o *BindingClient) AskBindAsFiles(flags map[string]string) (bool, error) {
83 var backend backendpkg.AddBindingBackend
84 if len(flags) == 0 {
85 backend = o.interactiveBackend
86 } else {
87 backend = o.flagsBackend
88 }
89 return backend.AskBindAsFiles(flags)
90 }
91
92 func (o *BindingClient) AskNamingStrategy(flags map[string]string) (string, error) {
93 var backend backendpkg.AddBindingBackend
94 if len(flags) == 0 {
95 backend = o.interactiveBackend
96 } else {
97 backend = o.flagsBackend
98 }
99 return backend.AskNamingStrategy(flags)
100 }
101
102 func (o *BindingClient) AddBindingToDevfile(
103 componentName string,
104 bindingName string,
105 bindAsFiles bool,
106 serviceNs string,
107 namingStrategy string,
108 unstructuredService unstructured.Unstructured,
109 obj parser.DevfileObj,
110 ) (parser.DevfileObj, error) {
111 service, err := o.kubernetesClient.NewServiceBindingServiceObject(serviceNs, unstructuredService, bindingName)
112 if err != nil {
113 return obj, err
114 }
115
116 deploymentName := fmt.Sprintf("%s-app", componentName)
117 deploymentGVK, err := o.kubernetesClient.GetDeploymentAPIVersion()
118 if err != nil {
119 return obj, err
120 }
121
122 serviceBinding := kclient.NewServiceBindingObject(
123 bindingName, bindAsFiles, deploymentName, namingStrategy, deploymentGVK, []sboApi.Mapping{}, []sboApi.Service{service}, sboApi.ServiceBindingStatus{})
124
125
126 serviceBindingUnstructured, err := kclient.ConvertK8sResourceToUnstructured(serviceBinding)
127 if err != nil {
128 return obj, err
129 }
130 yamlDesc, err := yaml.Marshal(serviceBindingUnstructured.UnstructuredContent())
131 if err != nil {
132 return obj, err
133 }
134
135 return libdevfile.AddKubernetesComponentToDevfile(string(yamlDesc), serviceBinding.Name, obj)
136 }
137
138 func (o *BindingClient) AddBinding(
139 flags map[string]string,
140 bindingName string,
141 bindAsFiles bool,
142 serviceNs string,
143 namingStrategy string,
144 unstructuredService unstructured.Unstructured,
145 workloadName string,
146 workloadGVK schema.GroupVersionKind,
147 ) ([]asker.CreationOption, string, string, error) {
148 service, err := o.kubernetesClient.NewServiceBindingServiceObject(serviceNs, unstructuredService, bindingName)
149 if err != nil {
150 return nil, "", "", err
151 }
152
153 serviceBinding := kclient.NewServiceBindingObject(
154 bindingName, bindAsFiles, workloadName, namingStrategy, workloadGVK, []sboApi.Mapping{}, []sboApi.Service{service}, sboApi.ServiceBindingStatus{})
155
156 var backend backendpkg.AddBindingBackend
157 if len(flags) == 0 {
158 backend = o.interactiveBackend
159 } else {
160 backend = o.flagsBackend
161 }
162
163 var options []asker.CreationOption
164 for len(options) == 0 {
165 options, err = backend.SelectCreationOptions(flags)
166 if err != nil {
167 return nil, "", "", err
168 }
169 }
170
171
172 serviceBindingUnstructured, err := kclient.ConvertK8sResourceToUnstructured(serviceBinding)
173 if err != nil {
174 return nil, "", "", err
175 }
176 yamlDesc, err := yaml.Marshal(serviceBindingUnstructured.UnstructuredContent())
177 if err != nil {
178 return nil, "", "", err
179 }
180
181 var filename string
182 for _, option := range options {
183 if option == asker.OutputToFile {
184 filename, err = backend.AskOutputFilePath(flags, filepath.Join("kubernetes", serviceBinding.GetName()+".yaml"))
185 if err != nil {
186 return nil, "", "", err
187 }
188 break
189 }
190 }
191
192 var output string
193 for _, option := range options {
194 switch option {
195 case asker.OutputToFile:
196 err = os.MkdirAll(filepath.Dir(filename), 0750)
197 if err != nil {
198 return nil, "", "", err
199 }
200 err = os.WriteFile(filename, yamlDesc, 0600)
201 if err != nil {
202 return nil, "", "", err
203 }
204
205 case asker.OutputToStdout:
206 output = string(yamlDesc)
207
208 case asker.CreateOnCluster:
209 _, err = o.kubernetesClient.PatchDynamicResource(serviceBindingUnstructured)
210 if err != nil {
211 return nil, "", "", err
212 }
213 }
214 }
215
216 return options, output, filename, nil
217 }
218
View as plain text