diff --git a/src/main/java/net/geant/nmaas/externalservices/kubernetes/RemoteClusterManager.java b/src/main/java/net/geant/nmaas/externalservices/kubernetes/RemoteClusterManager.java index 1ce39f84be89c9de640fbd791ff103417be68e18..7ab5cf48dd4a9f2d50d2f5cffecf48911b8649e8 100644 --- a/src/main/java/net/geant/nmaas/externalservices/kubernetes/RemoteClusterManager.java +++ b/src/main/java/net/geant/nmaas/externalservices/kubernetes/RemoteClusterManager.java @@ -349,4 +349,8 @@ public class RemoteClusterManager implements ClusterMonitoringService { } + public boolean clusterExist(Long id) { + return clusterRepository.existsById(id); + } + } \ No newline at end of file diff --git a/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/KubernetesManager.java b/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/KubernetesManager.java index 1cb6ce71487bd05b78fbade29f70dae91319b9af..b4668e77e24b3174555110a00f1175ec6229f886 100644 --- a/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/KubernetesManager.java +++ b/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/KubernetesManager.java @@ -4,6 +4,7 @@ import com.google.common.base.Strings; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import net.geant.nmaas.externalservices.kubernetes.KubernetesClusterIngressManager; +import net.geant.nmaas.externalservices.kubernetes.RemoteClusterManager; import net.geant.nmaas.externalservices.kubernetes.entities.IngressControllerConfigOption; import net.geant.nmaas.gitlab.GitLabManager; import net.geant.nmaas.gitlab.exceptions.GitLabInvalidConfigurationException; @@ -81,6 +82,7 @@ public class KubernetesManager implements ContainerOrchestrator { private final KubernetesClusterIngressManager ingressManager; private final GitLabManager gitLabManager; private final JanitorService janitorService; + private final RemoteClusterManager remoteClusterManager; @Override @Loggable(LogLevel.INFO) @@ -97,12 +99,25 @@ public class KubernetesManager implements ContainerOrchestrator { throw new NmServiceRequestVerificationException(iae.getMessage()); } - KubernetesNmServiceInfo serviceInfo = new KubernetesNmServiceInfo( - deploymentId, - appDeployment.getDeploymentName(), - appDeployment.getDomain(), - appDeployment.getDescriptiveDeploymentId() - ); + KubernetesNmServiceInfo serviceInfo; + //verify cluster + if(remoteClusterManager.clusterExist(appDeployment.getRemoteClusterId())) { + serviceInfo = new KubernetesNmServiceInfo( + deploymentId, + appDeployment.getDeploymentName(), + appDeployment.getDomain(), + appDeployment.getDescriptiveDeploymentId(), + remoteClusterManager.getCluster(appDeployment.getRemoteClusterId())); + } else { + serviceInfo = new KubernetesNmServiceInfo( + deploymentId, + appDeployment.getDeploymentName(), + appDeployment.getDomain(), + appDeployment.getDescriptiveDeploymentId() + ); + } + + serviceInfo.setKubernetesTemplate(KubernetesTemplate.copy(appDeploymentSpec.getKubernetesTemplate())); serviceInfo.setStorageVolumes(generateTemplateStorageVolumes(appDeploymentSpec.getStorageVolumes())); serviceInfo.setAccessMethods(generateTemplateAccessMethods(appDeploymentSpec.getAccessMethods())); diff --git a/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmCommand.java b/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmCommand.java index f4ba07022f7d0a78e95fe8f4dcf31ab0dec71644..fb2e4bd9fba8103546069873fc73cebef49ce47f 100644 --- a/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmCommand.java +++ b/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmCommand.java @@ -16,6 +16,8 @@ public abstract class HelmCommand implements Command { protected static final String HELM_VERSION_2 = "v2"; protected static final String HELM_VERSION_3 = "v3"; + protected static final String KUBECONFIG = "--kubeconfig"; + protected String command; @Override diff --git a/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmCommandExecutor.java b/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmCommandExecutor.java index 01a3fd9b4307cc5eea008c719b76d0442d1d6b4c..dfc719d8abda50051c29c5f4b2ed08aba522ece6 100644 --- a/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmCommandExecutor.java +++ b/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmCommandExecutor.java @@ -46,11 +46,11 @@ public class HelmCommandExecutor { this.enableTls = enableTls; } - void executeHelmInstallCommand(String namespace, String releaseName, KubernetesTemplate template, Map<String, String> arguments) { - executeInstall(namespace, releaseName, template, arguments); + void executeHelmInstallCommand(String namespace, String releaseName, KubernetesTemplate template, Map<String, String> arguments, String kubeConfigPath) { + executeInstall(namespace, releaseName, template, arguments, kubeConfigPath); } - private void executeInstall(String namespace, String releaseName, KubernetesTemplate template, Map<String, String> arguments) { + private void executeInstall(String namespace, String releaseName, KubernetesTemplate template, Map<String, String> arguments, String kubeConfigPath) { try { HelmInstallCommand command = HelmInstallCommand.commandWithRepo( helmVersion, @@ -59,7 +59,8 @@ public class HelmCommandExecutor { arguments, constructChartNameWithRepo(template.getChart().getName()), template.getChart().getVersion(), - enableTls + enableTls, + kubeConfigPath ); commandExecutor.execute(command); } catch (CommandExecutionException e) { diff --git a/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmKServiceManager.java b/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmKServiceManager.java index 753891c45e3e7d4b994bb74ab1a777580518e248..1cd6308aeb12415273517fef12184f3a2122415f 100644 --- a/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmKServiceManager.java +++ b/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmKServiceManager.java @@ -75,7 +75,8 @@ public class HelmKServiceManager implements KServiceLifecycleManager { namespaceService.namespace(serviceInfo.getDomain()), serviceInfo.getDescriptiveDeploymentId().getValue(), serviceInfo.getKubernetesTemplate(), - createArgumentsMap(serviceInfo) + createArgumentsMap(serviceInfo), + serviceInfo.getRemoteCluster() != null ? serviceInfo.getRemoteCluster().getPathConfigFile() : null ); } diff --git a/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/commands/HelmInstallCommand.java b/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/commands/HelmInstallCommand.java index 940c89fa9b85beac192549668b1df98f86943d54..c5cab7455db3c233b872095ed5eea07afdd93441 100644 --- a/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/commands/HelmInstallCommand.java +++ b/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/commands/HelmInstallCommand.java @@ -25,7 +25,7 @@ public class HelmInstallCommand extends HelmCommand { * @param enableTls flag indicating if tls option should be added * @return complete command object */ - public static HelmInstallCommand commandWithRepo(String helmVersion, String namespace, String releaseName, Map<String, String> values, String chartName, String chartVersion, boolean enableTls) { + public static HelmInstallCommand commandWithRepo(String helmVersion, String namespace, String releaseName, Map<String, String> values, String chartName, String chartVersion, boolean enableTls, String kubeConfigPath) { StringBuilder sb = buildBaseInstallCommand(helmVersion, namespace, releaseName, values); if (chartName == null || chartName.isEmpty()) { throw new IllegalArgumentException("Chart name can't be null or empty"); @@ -35,6 +35,10 @@ public class HelmInstallCommand extends HelmCommand { sb.append(SPACE).append(OPTION_VERSION).append(SPACE).append(chartVersion); } addTlsOptionIfRequired(helmVersion, enableTls, sb); + + if(kubeConfigPath != null && !kubeConfigPath.isEmpty()) { + sb.append(SPACE).append(KUBECONFIG).append(SPACE).append(kubeConfigPath); + } return new HelmInstallCommand(sb.toString()); } diff --git a/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/entities/KubernetesNmServiceInfo.java b/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/entities/KubernetesNmServiceInfo.java index e2f56ccb6d5a2c1c28894c21616ad0fec369d6bf..7c77eb8654a021dc403df24eec1052bda5bc8075 100644 --- a/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/entities/KubernetesNmServiceInfo.java +++ b/src/main/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/entities/KubernetesNmServiceInfo.java @@ -2,6 +2,7 @@ package net.geant.nmaas.nmservice.deployment.containerorchestrators.kubernetes.e import lombok.Getter; import lombok.Setter; +import net.geant.nmaas.externalservices.kubernetes.entities.KCluster; import net.geant.nmaas.nmservice.deployment.entities.NmServiceInfo; import net.geant.nmaas.orchestration.Identifier; @@ -38,6 +39,8 @@ public class KubernetesNmServiceInfo extends NmServiceInfo { @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER) private Set<ServiceAccessMethod> accessMethods; + private KCluster remoteCluster; + public KubernetesNmServiceInfo () { super(); } @@ -46,4 +49,9 @@ public class KubernetesNmServiceInfo extends NmServiceInfo { super(deploymentId, deploymentName, domain, descriptiveDeploymentId); } + public KubernetesNmServiceInfo(Identifier deploymentId, String deploymentName, String domain, Identifier descriptiveDeploymentId, KCluster kCluster) { + super(deploymentId, deploymentName, domain, descriptiveDeploymentId); + this.remoteCluster = kCluster; + } + } diff --git a/src/main/java/net/geant/nmaas/orchestration/entities/AppDeployment.java b/src/main/java/net/geant/nmaas/orchestration/entities/AppDeployment.java index 73173f116825dda60fe71b772bb9897e0b37927f..6593de17059fffb3ba403dc82acdda17ed701325 100644 --- a/src/main/java/net/geant/nmaas/orchestration/entities/AppDeployment.java +++ b/src/main/java/net/geant/nmaas/orchestration/entities/AppDeployment.java @@ -127,6 +127,8 @@ public class AppDeployment { private Long instanceId; + private Long remoteClusterId; + /** * Globally unique descriptive application deployment identifier */ diff --git a/src/main/java/net/geant/nmaas/orchestration/tasks/app/AppRequestVerificationTask.java b/src/main/java/net/geant/nmaas/orchestration/tasks/app/AppRequestVerificationTask.java index 3810ab4bbcf8f45dd015521e01b508f0d0dbd047..f7d1e2993767b4072f66086eae00a2cf6f0b13d0 100644 --- a/src/main/java/net/geant/nmaas/orchestration/tasks/app/AppRequestVerificationTask.java +++ b/src/main/java/net/geant/nmaas/orchestration/tasks/app/AppRequestVerificationTask.java @@ -2,6 +2,7 @@ package net.geant.nmaas.orchestration.tasks.app; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; +import net.geant.nmaas.externalservices.kubernetes.RemoteClusterManager; import net.geant.nmaas.nmservice.deployment.NmServiceDeploymentProvider; import net.geant.nmaas.orchestration.Identifier; import net.geant.nmaas.orchestration.entities.AppDeployment; @@ -29,6 +30,8 @@ public class AppRequestVerificationTask { private AppDeploymentRepository repository; private ApplicationRepository appRepository; + private RemoteClusterManager remoteClusterManager; + @EventListener @Loggable(LogLevel.INFO) @Transactional(propagation = Propagation.REQUIRES_NEW) @@ -39,6 +42,9 @@ public class AppRequestVerificationTask { final AppDeployment appDeployment = repository.findByDeploymentId(deploymentId).orElseThrow(() -> new InvalidDeploymentIdException(deploymentId)); final Application application = appRepository.findById(Long.valueOf(appDeployment.getApplicationId().getValue())).orElseThrow(() -> new InvalidApplicationIdException("Application for deployment " + deploymentId + " does not exist in repository")); + if(!remoteClusterManager.clusterExist(appDeployment.getRemoteClusterId())) { + throw new InvalidDeploymentIdException("Wrong remote cluster Id"); + } serviceDeployment.verifyRequest( deploymentId, appDeployment, diff --git a/src/main/java/net/geant/nmaas/portal/api/market/AppInstanceController.java b/src/main/java/net/geant/nmaas/portal/api/market/AppInstanceController.java index 81365d8a6ed7c899f34f4ee9eeff9ac7f03351a2..0a2f7e395efbcbc596163f69b7c6ffceeacc5919 100644 --- a/src/main/java/net/geant/nmaas/portal/api/market/AppInstanceController.java +++ b/src/main/java/net/geant/nmaas/portal/api/market/AppInstanceController.java @@ -297,6 +297,7 @@ public class AppInstanceController extends AppBaseController { .owner(principal.getName()) .appName(app.getName()) .descriptiveDeploymentId(createDescriptiveDeploymentId(domain.getCodename(), app.getName(), appInstance.getId())) + .remoteClusterId(clusterId) .build(); Identifier internalId = appLifecycleManager.deployApplication(appDeployment); diff --git a/src/main/java/net/geant/nmaas/portal/service/impl/DomainServiceImpl.java b/src/main/java/net/geant/nmaas/portal/service/impl/DomainServiceImpl.java index 5af2eeecbe42cc13ec5cc9c2f262f5fa23aa1f98..88cad0edcb8ff7dbb96d52536d6d811a61bb258d 100644 --- a/src/main/java/net/geant/nmaas/portal/service/impl/DomainServiceImpl.java +++ b/src/main/java/net/geant/nmaas/portal/service/impl/DomainServiceImpl.java @@ -200,7 +200,7 @@ public class DomainServiceImpl implements DomainService { eventPublisher.publishEvent(new DomainCreatedEvent(this, new DomainCreatedEvent.DomainSpec(saved.getId(), saved.getName(), saved.getCodename(), request.getAnnotations()))); } //call existing webhooks - webhookEventRepository.findIdByEventType(WebhookEventType.DOMAIN_CREATION).forEach(id -> scheduleManager.createOneTimeJob(DomainCreationJob.class, "DomainCreation_" + id + "_" + saved.getId(), Map.of("webhookId", id, "domainId", saved.getId()))); +// webhookEventRepository.findIdByEventType(WebhookEventType.DOMAIN_CREATION).forEach(id -> scheduleManager.createOneTimeJob(DomainCreationJob.class, "DomainCreation_" + id + "_" + saved.getId(), Map.of("webhookId", id, "domainId", saved.getId()))); return saved; } catch (Exception ex) { throw new ProcessingException("Unable to create new domain with given name or codename."); diff --git a/src/test/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmKServiceManagerTest.java b/src/test/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmKServiceManagerTest.java index 0ebf9adc9ddcfcaceebc693ebe1c5dfec3b704c1..b3e27ed59448daf424638912499f0d4a3de3f265 100644 --- a/src/test/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmKServiceManagerTest.java +++ b/src/test/java/net/geant/nmaas/nmservice/deployment/containerorchestrators/kubernetes/components/helm/HelmKServiceManagerTest.java @@ -119,7 +119,7 @@ public class HelmKServiceManagerTest { eq("namespace"), eq("descriptiveDeploymentId"), k8sTemplateArg.capture(), - argumentsArg.capture() + argumentsArg.capture(), null ); assertThat(argumentsArg.getValue()).isNotEmpty(); assertThat(argumentsArg.getValue().size()).isEqualTo(11); @@ -143,7 +143,7 @@ public class HelmKServiceManagerTest { eq("namespace"), eq("descriptiveDeploymentId"), any(), - any() + any(), null ); } diff --git a/src/test/java/net/geant/nmaas/orchestration/tasks/app/AppRequestVerificationTaskTest.java b/src/test/java/net/geant/nmaas/orchestration/tasks/app/AppRequestVerificationTaskTest.java index 6171c102318ac1bf8e99820409db14223e7b90f9..8112568adee274e43652fcf6d9e3793c9baf3f30 100644 --- a/src/test/java/net/geant/nmaas/orchestration/tasks/app/AppRequestVerificationTaskTest.java +++ b/src/test/java/net/geant/nmaas/orchestration/tasks/app/AppRequestVerificationTaskTest.java @@ -1,5 +1,6 @@ package net.geant.nmaas.orchestration.tasks.app; +import net.geant.nmaas.externalservices.kubernetes.RemoteClusterManager; import net.geant.nmaas.nmservice.deployment.NmServiceDeploymentProvider; import net.geant.nmaas.orchestration.Identifier; import net.geant.nmaas.orchestration.entities.AppDeployment; @@ -25,6 +26,7 @@ public class AppRequestVerificationTaskTest { private NmServiceDeploymentProvider deploy = mock(NmServiceDeploymentProvider.class); private AppDeploymentRepository deployments = mock(AppDeploymentRepository.class); private ApplicationRepository applications = mock(ApplicationRepository.class); + private RemoteClusterManager remoteClusterManager = mock(RemoteClusterManager.class); private AppRequestVerificationTask task; @@ -33,7 +35,7 @@ public class AppRequestVerificationTaskTest { @BeforeEach public void setup() { - task = new AppRequestVerificationTask(deploy, deployments, applications); + task = new AppRequestVerificationTask(deploy, deployments, applications, remoteClusterManager); } @Test