| /* |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You 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 kameletbinding |
| |
| import ( |
| "context" |
| "strings" |
| |
| "github.com/apache/camel-k/pkg/apis/camel/v1alpha1" |
| "github.com/apache/camel-k/pkg/kamelet/repository" |
| "github.com/apache/camel-k/pkg/platform" |
| "github.com/apache/camel-k/pkg/util/kubernetes" |
| "github.com/apache/camel-k/pkg/util/patch" |
| "github.com/pkg/errors" |
| corev1 "k8s.io/api/core/v1" |
| "k8s.io/apimachinery/pkg/types" |
| "sigs.k8s.io/controller-runtime/pkg/client" |
| ) |
| |
| // NewInitializeAction returns a action that initializes the kamelet binding configuration when not provided by the user |
| func NewInitializeAction() Action { |
| return &initializeAction{} |
| } |
| |
| type initializeAction struct { |
| baseAction |
| } |
| |
| func (action *initializeAction) Name() string { |
| return "initialize" |
| } |
| |
| func (action *initializeAction) CanHandle(kameletbinding *v1alpha1.KameletBinding) bool { |
| return kameletbinding.Status.Phase == v1alpha1.KameletBindingPhaseNone |
| } |
| |
| func (action *initializeAction) Handle(ctx context.Context, kameletbinding *v1alpha1.KameletBinding) (*v1alpha1.KameletBinding, error) { |
| it, err := createIntegrationFor(ctx, action.client, kameletbinding) |
| if err != nil { |
| return nil, err |
| } |
| |
| if err := kubernetes.ReplaceResource(ctx, action.client, it); err != nil { |
| return nil, errors.Wrap(err, "could not create integration for kamelet binding") |
| } |
| |
| // propagate Kamelet icon (best effort) |
| action.propagateIcon(ctx, kameletbinding) |
| |
| target := kameletbinding.DeepCopy() |
| target.Status.Phase = v1alpha1.KameletBindingPhaseCreating |
| return target, nil |
| } |
| |
| func (action *initializeAction) propagateIcon(ctx context.Context, binding *v1alpha1.KameletBinding) { |
| icon, err := action.findIcon(ctx, binding) |
| if err != nil { |
| action.L.Errorf(err, "cannot find icon for kamelet binding %q", binding.Name) |
| return |
| } |
| if icon == "" { |
| return |
| } |
| // compute patch |
| clone := binding.DeepCopy() |
| clone.Annotations = make(map[string]string) |
| for k, v := range binding.Annotations { |
| clone.Annotations[k] = v |
| } |
| if _, ok := clone.Annotations[v1alpha1.AnnotationIcon]; !ok { |
| clone.Annotations[v1alpha1.AnnotationIcon] = icon |
| } |
| p, err := patch.PositiveMergePatch(binding, clone) |
| if err != nil { |
| action.L.Errorf(err, "cannot compute patch to update icon for kamelet binding %q", binding.Name) |
| return |
| } |
| if len(p) > 0 { |
| if err := action.client.Patch(ctx, clone, client.RawPatch(types.MergePatchType, p)); err != nil { |
| action.L.Errorf(err, "cannot apply merge patch to update icon for kamelet binding %q", binding.Name) |
| return |
| } |
| } |
| } |
| |
| func (action *initializeAction) findIcon(ctx context.Context, binding *v1alpha1.KameletBinding) (string, error) { |
| var kameletRef *corev1.ObjectReference |
| if binding.Spec.Source.Ref != nil && binding.Spec.Source.Ref.Kind == "Kamelet" && strings.HasPrefix(binding.Spec.Source.Ref.APIVersion, "camel.apache.org/") { |
| kameletRef = binding.Spec.Source.Ref |
| } else if binding.Spec.Sink.Ref != nil && binding.Spec.Sink.Ref.Kind == "Kamelet" && strings.HasPrefix(binding.Spec.Sink.Ref.APIVersion, "camel.apache.org/") { |
| kameletRef = binding.Spec.Sink.Ref |
| } |
| |
| if kameletRef == nil { |
| return "", nil |
| } |
| |
| repo, err := repository.New(ctx, action.client, binding.Namespace, platform.GetOperatorNamespace()) |
| if err != nil { |
| return "", err |
| } |
| |
| kamelet, err := repo.Get(ctx, kameletRef.Name) |
| if err != nil { |
| return "", err |
| } |
| if kamelet == nil { |
| return "", nil |
| } |
| |
| return kamelet.Annotations[v1alpha1.AnnotationIcon], nil |
| } |