1 package service
2
3 import (
4 "fmt"
5
6 "github.com/devfile/library/v2/pkg/devfile/generator"
7 appsv1 "k8s.io/api/apps/v1"
8 kerrors "k8s.io/apimachinery/pkg/api/errors"
9 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
11 "k8s.io/apimachinery/pkg/runtime"
12 authv1 "k8s.io/client-go/kubernetes/typed/authorization/v1"
13 "k8s.io/klog"
14 ctrl "sigs.k8s.io/controller-runtime"
15
16 "github.com/redhat-developer/odo/pkg/kclient"
17 odolabels "github.com/redhat-developer/odo/pkg/labels"
18
19 sboApi "github.com/redhat-developer/service-binding-operator/apis/binding/v1alpha1"
20 sboKubernetes "github.com/redhat-developer/service-binding-operator/pkg/client/kubernetes"
21 sboPipeline "github.com/redhat-developer/service-binding-operator/pkg/reconcile/pipeline"
22 sboContext "github.com/redhat-developer/service-binding-operator/pkg/reconcile/pipeline/context"
23 )
24
25
26 func pushLinksWithoutOperator(client kclient.ClientInterface, u unstructured.Unstructured, labels map[string]string) error {
27
28
29 csvSupport, err := client.IsCSVSupported()
30 if err != nil {
31 return err
32 }
33
34 var serviceCompMap map[string]string
35
36
37
38 services, e := client.ListServices("")
39 if e != nil {
40 return e
41 }
42
43
44 serviceCompMap = make(map[string]string)
45 for _, service := range services {
46 serviceCompMap[service.Name] = odolabels.GetComponentName(service.Labels)
47 }
48
49
50 var serviceBinding sboApi.ServiceBinding
51 err = runtime.DefaultUnstructuredConverter.FromUnstructured(u.UnstructuredContent(), &serviceBinding)
52 if err != nil {
53 return err
54 }
55
56 if len(serviceBinding.Spec.Services) != 1 {
57 klog.V(4).Infof("cannot create the link; serviceBinding.Spec.Services != 1; ServiceBinding: %v", serviceBinding)
58 return nil
59 }
60
61 if !csvSupport && !isLinkResource(serviceBinding.Spec.Services[0].Kind) {
62
63 klog.V(4).Infof("cannot create the link; CSV is not supported")
64 return nil
65 }
66
67
68 serviceBinding.SetLabels(labels)
69 serviceBinding.Namespace = client.GetCurrentNamespace()
70 ns := client.GetCurrentNamespace()
71 serviceBinding.Spec.Services[0].Namespace = &ns
72
73 var processingPipeline sboPipeline.Pipeline
74 processingPipeline, err = getPipeline(client)
75 if err != nil {
76 return err
77 }
78
79 _, err = processingPipeline.Process(&serviceBinding)
80 if err != nil {
81 if kerrors.IsForbidden(err) {
82
83 return fmt.Errorf("please install the service binding operator")
84 }
85 return err
86 }
87
88 if len(serviceBinding.Status.Secret) == 0 {
89 return fmt.Errorf("no secret was provided by service binding's pipleine")
90 }
91
92
93 sbSecret, err := client.GetSecret(serviceBinding.Status.Secret, client.GetCurrentNamespace())
94 if err != nil {
95 return err
96 }
97 sbSecret.Labels = labels
98 sbSecret.Labels[LinkLabel] = serviceBinding.Name
99 if _, ok := serviceCompMap[serviceBinding.Spec.Services[0].Name]; ok {
100 sbSecret.Labels[ServiceLabel] = serviceCompMap[serviceBinding.Spec.Services[0].Name]
101 } else {
102 sbSecret.Labels[ServiceLabel] = serviceBinding.Spec.Services[0].Name
103 }
104 sbSecret.Labels[ServiceKind] = serviceBinding.Spec.Services[0].Kind
105
106 if serviceBinding.Spec.Services[0].Kind != "Service" {
107
108 sbSecret.Labels[ServiceLabel] = fmt.Sprintf("%v-%v", serviceBinding.Spec.Services[0].Kind, serviceBinding.Spec.Services[0].Name)
109 }
110
111
112 deployment, err := client.GetOneDeploymentFromSelector(odolabels.GetSelector(odolabels.GetComponentName(labels), odolabels.GetAppName(labels), odolabels.ComponentAnyMode, true))
113 if err != nil {
114 return err
115 }
116 ownerReferences := generator.GetOwnerReference(deployment)
117 sbSecret.SetOwnerReferences([]metav1.OwnerReference{ownerReferences})
118
119 _, err = client.UpdateSecret(sbSecret, client.GetCurrentNamespace())
120 if err != nil {
121 return err
122 }
123
124 return nil
125 }
126
127
128 func UnbindWithLibrary(kubeClient kclient.ClientInterface, secretToUnbind unstructured.Unstructured, deployment *appsv1.Deployment) error {
129 var processingPipeline sboPipeline.Pipeline
130 deploymentGVK, err := kubeClient.GetDeploymentAPIVersion()
131 if err != nil {
132 return fmt.Errorf("failed to get deployment GVK: %w", err)
133 }
134
135 var newServiceBinding sboApi.ServiceBinding
136 newServiceBinding.Name = secretToUnbind.GetLabels()[LinkLabel]
137 newServiceBinding.Namespace = kubeClient.GetCurrentNamespace()
138 newServiceBinding.Spec.Application = sboApi.Application{
139 Ref: sboApi.Ref{
140 Name: deployment.Name,
141 Group: deploymentGVK.Group,
142 Version: deploymentGVK.Version,
143 Kind: deploymentGVK.Kind,
144 },
145 }
146 newServiceBinding.Status.Secret = secretToUnbind.GetName()
147
148 timeNow := metav1.Now()
149 newServiceBinding.DeletionTimestamp = &timeNow
150
151 if processingPipeline == nil {
152 processingPipeline, err = getPipeline(kubeClient)
153 if err != nil {
154 return err
155 }
156 }
157
158
159 _, err = processingPipeline.Process(&newServiceBinding)
160 return err
161 }
162
163
164 func getPipeline(client kclient.ClientInterface) (sboPipeline.Pipeline, error) {
165 mgr, err := ctrl.NewManager(client.GetClientConfig(), ctrl.Options{
166 Scheme: runtime.NewScheme(),
167
168 HealthProbeBindAddress: "0",
169
170 MetricsBindAddress: "0",
171 })
172 if err != nil {
173 return nil, err
174 }
175
176 authClient, err := authv1.NewForConfig(client.GetClientConfig())
177 if err != nil {
178 return nil, err
179 }
180
181 return OdoDefaultBuilder.WithContextProvider(
182 sboContext.Provider(
183 client.GetDynamicClient(),
184 authClient.SubjectAccessReviews(),
185 sboKubernetes.ResourceLookup(mgr.GetRESTMapper()),
186 ),
187 ).Build(), nil
188 }
189
View as plain text