/* * Copyright 2016 Red Hat, Inc. * <p> * Red Hat 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 * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * 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 io.fabric8.funktion.agent; import com.fasterxml.jackson.core.JsonProcessingException; import io.fabric8.funktion.DataKeys; import io.fabric8.funktion.Labels; import io.fabric8.funktion.model.Funktion; import io.fabric8.kubernetes.api.KubernetesHelper; import io.fabric8.kubernetes.api.model.ConfigMap; import io.fabric8.kubernetes.api.model.ConfigMapBuilder; import io.fabric8.kubernetes.api.model.ConfigMapList; import io.fabric8.kubernetes.client.DefaultKubernetesClient; import io.fabric8.kubernetes.client.KubernetesClient; import io.fabric8.utils.Objects; import io.fabric8.utils.Strings; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import static io.fabric8.funktion.ApplicationProperties.toPropertiesString; import static io.fabric8.funktion.Labels.Kind.SUBSCRIPTION; import static io.fabric8.funktion.support.YamlHelper.createYamlMapper; import static io.fabric8.utils.Lists.notNullList; /** */ public class Agent { private static final transient Logger LOG = LoggerFactory.getLogger(Agent.class); private KubernetesClient kubernetesClient = new DefaultKubernetesClient(); public KubernetesClient getKubernetesClient() { return kubernetesClient; } public void setKubernetesClient(KubernetesClient kubernetesClient) { this.kubernetesClient = kubernetesClient; } public SubscribeResponse subscribe(SubscribeRequest request) throws InternalException { String namespace = request.getNamespace(); Objects.notNull(namespace, "namespace"); ConfigMap configMap = createSubscriptionResource(request, namespace); kubernetesClient.configMaps().inNamespace(namespace).create(configMap); return new SubscribeResponse(namespace, KubernetesHelper.getName(configMap)); } public void unsubscribe(String namespace, String name) { kubernetesClient.configMaps().inNamespace(namespace).withName(name).delete(); } public String getCurrentNamespace() { String answer = kubernetesClient.getNamespace(); if (Strings.isNullOrBlank(answer)) { answer = KubernetesHelper.defaultNamespace(); } if (Strings.isNullOrBlank(answer)) { answer = System.getenv("KUBERNETES_NAMESPACE"); } if (Strings.isNullOrBlank(answer)) { answer = "default"; } return answer; } protected ConfigMap createSubscriptionResource(SubscribeRequest request, String namespace) throws InternalException { Map<String, String> annotations = new LinkedHashMap<>(); Map<String, String> data = new LinkedHashMap<>(); Map<String, String> labels = new HashMap<>(); labels.put(Labels.KIND, SUBSCRIPTION); String connectorName = request.findConnectorName(); String namePrefix = "design"; if (Strings.isNotBlank(connectorName)) { namePrefix += "-" + connectorName; labels.put(Labels.CONNECTOR, connectorName); } String name = createSubscriptionName(request, namespace, namePrefix); Funktion funktion = request.getFunktion(); Objects.notNull(funktion, "funktion"); try { String yaml = createYamlMapper().writeValueAsString(funktion); data.put(DataKeys.Subscription.FUNKTION_YAML, yaml); } catch (JsonProcessingException e) { throw new InternalException("Failed to marshal Funktion " + funktion + ". " + e, e); } Map<String, String> applicationProperties = request.getApplicationProperties(); if (applicationProperties != null) { String comments = null; String applicationPropertiesText = null; try { applicationPropertiesText = toPropertiesString(applicationProperties, comments); } catch (IOException e) { throw new InternalException("Failed to marshal applicationProperties " + applicationProperties + ". " + e, e); } if (Strings.isNotBlank(applicationPropertiesText)) { data.put(DataKeys.Subscription.APPLICATION_PROPERTIES, applicationPropertiesText); } } return new ConfigMapBuilder(). withNewMetadata().withName(name).withAnnotations(annotations).withLabels(labels).endMetadata(). withData(data).build(); } private String createSubscriptionName(SubscribeRequest request, String namespace, String prefix) { Set<String> configMapNames = new TreeSet<>(); ConfigMapList configMapList = kubernetesClient.configMaps().inNamespace(namespace).list(); List<ConfigMap> list = notNullList(configMapList.getItems()); for (ConfigMap configMap : list) { configMapNames.add(KubernetesHelper.getName(configMap)); } int idx = 0; while (true) { String name = prefix + (++idx); if (!configMapNames.contains(name)) { return name; } } } }