001/*
002 * VM-Operator
003 * Copyright (C) 2024 Michael N. Lipp
004 * 
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
017 */
018
019package org.jdrupes.vmoperator.manager;
020
021import io.kubernetes.client.openapi.ApiException;
022import io.kubernetes.client.openapi.models.V1Service;
023import io.kubernetes.client.openapi.models.V1ServiceList;
024import io.kubernetes.client.util.Watch.Response;
025import io.kubernetes.client.util.generic.options.ListOptions;
026import java.io.IOException;
027import static org.jdrupes.vmoperator.common.Constants.APP_NAME;
028import org.jdrupes.vmoperator.common.K8sClient;
029import org.jdrupes.vmoperator.common.K8sObserver.ResponseType;
030import org.jdrupes.vmoperator.common.K8sV1ServiceStub;
031import org.jdrupes.vmoperator.manager.events.ServiceChanged;
032import org.jdrupes.vmoperator.manager.events.VmChannel;
033import org.jgrapes.core.Channel;
034
035/**
036 * Watches for changes of services.
037 */
038@SuppressWarnings("PMD.DataflowAnomalyAnalysis")
039public class ServiceMonitor
040        extends AbstractMonitor<V1Service, V1ServiceList, VmChannel> {
041
042    /**
043     * Instantiates a new display secrets monitor.
044     *
045     * @param componentChannel the component channel
046     */
047    public ServiceMonitor(Channel componentChannel) {
048        super(componentChannel, V1Service.class, V1ServiceList.class);
049        context(K8sV1ServiceStub.CONTEXT);
050        ListOptions options = new ListOptions();
051        options.setLabelSelector("app.kubernetes.io/name=" + APP_NAME);
052        options(options);
053    }
054
055    @Override
056    protected void prepareMonitoring() throws IOException, ApiException {
057        client(new K8sClient());
058    }
059
060    @Override
061    protected void handleChange(K8sClient client, Response<V1Service> change) {
062        String vmName = change.object.getMetadata().getLabels()
063            .get("app.kubernetes.io/instance");
064        if (vmName == null) {
065            return;
066        }
067        var channel = channel(vmName).orElse(null);
068        if (channel == null || channel.vmDefinition() == null) {
069            return;
070        }
071        channel.pipeline().fire(new ServiceChanged(
072            ResponseType.valueOf(change.type), change.object), channel);
073    }
074}