use of com.netflix.spinnaker.halyard.deploy.deployment.v1.AccountDeploymentDetails in project halyard by spinnaker.
the class DeployService method getDeploymentDetails.
private DeploymentDetails getDeploymentDetails(DeploymentConfiguration deploymentConfiguration) {
String deploymentName = deploymentConfiguration.getName();
BillOfMaterials billOfMaterials = artifactService.getBillOfMaterials(deploymentName);
DeploymentEnvironment.DeploymentType type = deploymentConfiguration.getDeploymentEnvironment().getType();
switch(type) {
case BakeDebian:
case LocalDebian:
case LocalGit:
return new DeploymentDetails().setDeploymentConfiguration(deploymentConfiguration).setDeploymentName(deploymentName).setBillOfMaterials(billOfMaterials);
case Distributed:
DeploymentEnvironment deploymentEnvironment = deploymentConfiguration.getDeploymentEnvironment();
String accountName = deploymentEnvironment.getAccountName();
if (accountName == null || accountName.isEmpty()) {
throw new HalException(FATAL, "An account name must be " + "specified as the desired place to deploy your simple clustered deployment.");
}
Account account = accountService.getAnyProviderAccount(deploymentConfiguration.getName(), accountName);
return new AccountDeploymentDetails().setAccount(account).setDeploymentConfiguration(deploymentConfiguration).setDeploymentName(deploymentName).setBillOfMaterials(billOfMaterials);
default:
throw new IllegalArgumentException("Unrecognized deployment type " + type);
}
}
use of com.netflix.spinnaker.halyard.deploy.deployment.v1.AccountDeploymentDetails in project halyard by spinnaker.
the class KubernetesV1DistributedService method stageProfiles.
default List<ConfigSource> stageProfiles(AccountDeploymentDetails<KubernetesAccount> details, GenerateService.ResolvedConfiguration resolvedConfiguration) {
SpinnakerService thisService = getService();
ServiceSettings thisServiceSettings = resolvedConfiguration.getServiceSettings(thisService);
SpinnakerRuntimeSettings runtimeSettings = resolvedConfiguration.getRuntimeSettings();
Integer version = getRunningServiceDetails(details, runtimeSettings).getLatestEnabledVersion();
if (version == null) {
version = 0;
} else {
version++;
}
String namespace = getNamespace(thisServiceSettings);
KubernetesV1ProviderUtils.createNamespace(details, namespace);
String name = getServiceName();
Map<String, String> env = new HashMap<>();
List<ConfigSource> configSources = new ArrayList<>();
Map<String, Profile> serviceProfiles = resolvedConfiguration.getProfilesForService(thisService.getType());
Set<String> requiredFiles = new HashSet<>();
for (SidecarService sidecarService : getSidecars(runtimeSettings)) {
for (Profile profile : sidecarService.getSidecarProfiles(resolvedConfiguration, thisService)) {
if (profile == null) {
throw new HalException(Problem.Severity.FATAL, "Service " + sidecarService.getService().getCanonicalName() + " is required but was not supplied for deployment.");
}
serviceProfiles.put(profile.getName(), profile);
requiredFiles.addAll(profile.getRequiredFiles());
}
}
Map<String, Set<Profile>> collapseByDirectory = new HashMap<>();
for (Map.Entry<String, Profile> entry : serviceProfiles.entrySet()) {
Profile profile = entry.getValue();
String mountPoint = Paths.get(profile.getOutputFile()).getParent().toString();
Set<Profile> profiles = collapseByDirectory.getOrDefault(mountPoint, new HashSet<>());
profiles.add(profile);
requiredFiles.addAll(profile.getRequiredFiles());
collapseByDirectory.put(mountPoint, profiles);
}
String stagingPath = getSpinnakerStagingPath(details.getDeploymentName());
if (!requiredFiles.isEmpty()) {
String secretName = KubernetesV1ProviderUtils.componentDependencies(name, version);
String mountPoint = null;
for (String file : requiredFiles) {
String nextMountPoint = Paths.get(file).getParent().toString();
if (mountPoint == null) {
mountPoint = nextMountPoint;
}
assert (mountPoint.equals(nextMountPoint));
}
Set<Pair<File, String>> pairs = requiredFiles.stream().map(f -> {
return new ImmutablePair<>(new File(f), new File(f).getName());
}).collect(Collectors.toSet());
KubernetesV1ProviderUtils.upsertSecret(details, pairs, secretName, namespace);
configSources.add(new ConfigSource().setId(secretName).setMountPath(mountPoint));
}
int ind = 0;
for (Map.Entry<String, Set<Profile>> entry : collapseByDirectory.entrySet()) {
env.clear();
String mountPoint = entry.getKey();
Set<Profile> profiles = entry.getValue();
env.putAll(profiles.stream().reduce(new HashMap<>(), (acc, profile) -> {
acc.putAll(profile.getEnv());
return acc;
}, (a, b) -> {
a.putAll(b);
return a;
}));
String secretName = KubernetesV1ProviderUtils.componentSecret(name + ind, version);
ind += 1;
Set<Pair<File, String>> pairs = profiles.stream().map(p -> {
return new ImmutablePair<>(new File(stagingPath, p.getName()), new File(p.getOutputFile()).getName());
}).collect(Collectors.toSet());
KubernetesV1ProviderUtils.upsertSecret(details, pairs, secretName, namespace);
configSources.add(new ConfigSource().setId(secretName).setMountPath(mountPoint).setEnv(env));
}
return configSources;
}
use of com.netflix.spinnaker.halyard.deploy.deployment.v1.AccountDeploymentDetails in project halyard by spinnaker.
the class KubernetesV1DistributedService method getRunningServiceDetails.
@Override
default RunningServiceDetails getRunningServiceDetails(AccountDeploymentDetails<KubernetesAccount> details, SpinnakerRuntimeSettings runtimeSettings) {
ServiceSettings settings = runtimeSettings.getServiceSettings(getService());
RunningServiceDetails res = new RunningServiceDetails();
KubernetesClient client = KubernetesV1ProviderUtils.getClient(details);
String name = getServiceName();
String namespace = getNamespace(settings);
RunningServiceDetails.LoadBalancer lb = new RunningServiceDetails.LoadBalancer();
lb.setExists(client.services().inNamespace(namespace).withName(name).get() != null);
res.setLoadBalancer(lb);
List<Pod> pods = client.pods().inNamespace(namespace).withLabel("load-balancer-" + name, "true").list().getItems();
pods.addAll(client.pods().inNamespace(namespace).withLabel("load-balancer-" + name, "false").list().getItems());
Map<Integer, List<Instance>> instances = res.getInstances();
for (Pod pod : pods) {
String podName = pod.getMetadata().getName();
String serverGroupName = podName.substring(0, podName.lastIndexOf("-"));
Names parsedName = Names.parseName(serverGroupName);
Integer version = parsedName.getSequence();
if (version == null) {
throw new IllegalStateException("Server group for service " + getServiceName() + " has unknown sequence (" + serverGroupName + ")");
}
String location = pod.getMetadata().getNamespace();
String id = pod.getMetadata().getName();
Instance instance = new Instance().setId(id).setLocation(location);
List<ContainerStatus> containerStatuses = pod.getStatus().getContainerStatuses();
if (!containerStatuses.isEmpty() && containerStatuses.stream().allMatch(ContainerStatus::getReady)) {
instance.setHealthy(true);
}
if (!containerStatuses.isEmpty() && containerStatuses.stream().allMatch(s -> s.getState().getRunning() != null && s.getState().getTerminated() == null)) {
instance.setRunning(true);
}
List<Instance> knownInstances = instances.getOrDefault(version, new ArrayList<>());
knownInstances.add(instance);
instances.put(version, knownInstances);
}
List<ReplicaSet> replicaSets = client.extensions().replicaSets().inNamespace(settings.getLocation()).list().getItems();
for (ReplicaSet rs : replicaSets) {
String rsName = rs.getMetadata().getName();
Names parsedRsName = Names.parseName(rsName);
if (!parsedRsName.getCluster().equals(getServiceName())) {
continue;
}
instances.computeIfAbsent(parsedRsName.getSequence(), i -> new ArrayList<>());
}
return res;
}
use of com.netflix.spinnaker.halyard.deploy.deployment.v1.AccountDeploymentDetails in project halyard by spinnaker.
the class KubernetesV1DistributedService method ensureRunning.
default void ensureRunning(AccountDeploymentDetails<KubernetesAccount> details, GenerateService.ResolvedConfiguration resolvedConfiguration, List<ConfigSource> configSources, boolean recreate) {
ServiceSettings settings = resolvedConfiguration.getServiceSettings(getService());
SpinnakerRuntimeSettings runtimeSettings = resolvedConfiguration.getRuntimeSettings();
String namespace = getNamespace(settings);
String serviceName = getServiceName();
String replicaSetName = serviceName + "-v000";
int port = settings.getPort();
SpinnakerMonitoringDaemonService monitoringService = getMonitoringDaemonService();
ServiceSettings monitoringSettings = runtimeSettings.getServiceSettings(monitoringService);
KubernetesClient client = KubernetesV1ProviderUtils.getClient(details);
KubernetesV1ProviderUtils.createNamespace(details, namespace);
Map<String, String> serviceSelector = new HashMap<>();
serviceSelector.put("load-balancer-" + serviceName, "true");
Map<String, String> replicaSetSelector = new HashMap<>();
replicaSetSelector.put("replication-controller", replicaSetName);
Map<String, String> podLabels = new HashMap<>();
podLabels.putAll(replicaSetSelector);
podLabels.putAll(serviceSelector);
Map<String, String> serviceLabels = new HashMap<>();
serviceLabels.put("app", "spin");
serviceLabels.put("stack", getCanonicalName());
ServiceBuilder serviceBuilder = new ServiceBuilder();
serviceBuilder = serviceBuilder.withNewMetadata().withName(serviceName).withNamespace(namespace).withLabels(serviceLabels).endMetadata().withNewSpec().withSelector(serviceSelector).withPorts(new ServicePortBuilder().withPort(port).withName("http").build(), new ServicePortBuilder().withPort(monitoringSettings.getPort()).withName("monitoring").build()).endSpec();
boolean create = true;
if (client.services().inNamespace(namespace).withName(serviceName).get() != null) {
if (recreate) {
client.services().inNamespace(namespace).withName(serviceName).delete();
} else {
create = false;
}
}
if (create) {
client.services().inNamespace(namespace).create(serviceBuilder.build());
}
List<Container> containers = new ArrayList<>();
DeploymentEnvironment deploymentEnvironment = details.getDeploymentConfiguration().getDeploymentEnvironment();
containers.add(ResourceBuilder.buildContainer(serviceName, settings, configSources, deploymentEnvironment));
for (SidecarService sidecarService : getSidecars(runtimeSettings)) {
String sidecarName = sidecarService.getService().getServiceName();
ServiceSettings sidecarSettings = resolvedConfiguration.getServiceSettings(sidecarService.getService());
containers.add(ResourceBuilder.buildContainer(sidecarName, sidecarSettings, configSources, deploymentEnvironment));
}
List<Volume> volumes = configSources.stream().map(c -> {
return new VolumeBuilder().withName(c.getId()).withSecret(new SecretVolumeSourceBuilder().withSecretName(c.getId()).build()).build();
}).collect(Collectors.toList());
ReplicaSetBuilder replicaSetBuilder = new ReplicaSetBuilder();
List<LocalObjectReference> imagePullSecrets = getImagePullSecrets(settings);
Map componentSizing = deploymentEnvironment.getCustomSizing().get(serviceName);
replicaSetBuilder = replicaSetBuilder.withNewMetadata().withName(replicaSetName).withNamespace(namespace).endMetadata().withNewSpec().withReplicas(retrieveKubernetesTargetSize(componentSizing)).withNewSelector().withMatchLabels(replicaSetSelector).endSelector().withNewTemplate().withNewMetadata().withAnnotations(settings.getKubernetes().getPodAnnotations()).withLabels(podLabels).endMetadata().withNewSpec().withContainers(containers).withTerminationGracePeriodSeconds(5L).withVolumes(volumes).withImagePullSecrets(imagePullSecrets).endSpec().endTemplate().endSpec();
create = true;
if (client.extensions().replicaSets().inNamespace(namespace).withName(replicaSetName).get() != null) {
if (recreate) {
client.extensions().replicaSets().inNamespace(namespace).withName(replicaSetName).delete();
RunningServiceDetails runningServiceDetails = getRunningServiceDetails(details, runtimeSettings);
while (runningServiceDetails.getLatestEnabledVersion() != null) {
DaemonTaskHandler.safeSleep(TimeUnit.SECONDS.toMillis(5));
runningServiceDetails = getRunningServiceDetails(details, runtimeSettings);
}
} else {
create = false;
}
}
if (create) {
client.extensions().replicaSets().inNamespace(namespace).create(replicaSetBuilder.build());
}
RunningServiceDetails runningServiceDetails = getRunningServiceDetails(details, runtimeSettings);
Integer version = runningServiceDetails.getLatestEnabledVersion();
while (version == null || runningServiceDetails.getInstances().get(version).stream().anyMatch(i -> !(i.isHealthy() && i.isRunning()))) {
DaemonTaskHandler.safeSleep(TimeUnit.SECONDS.toMillis(5));
runningServiceDetails = getRunningServiceDetails(details, runtimeSettings);
version = runningServiceDetails.getLatestEnabledVersion();
}
}
use of com.netflix.spinnaker.halyard.deploy.deployment.v1.AccountDeploymentDetails in project halyard by spinnaker.
the class KubernetesV2Service method stageConfig.
default List<ConfigSource> stageConfig(AccountDeploymentDetails<KubernetesAccount> details, GenerateService.ResolvedConfiguration resolvedConfiguration) {
Map<String, Profile> profiles = resolvedConfiguration.getProfilesForService(getService().getType());
String stagingPath = getSpinnakerStagingPath(details.getDeploymentName());
Map<String, Set<Profile>> profilesByDirectory = new HashMap<>();
List<String> requiredFiles = new ArrayList<>();
List<ConfigSource> configSources = new ArrayList<>();
String secretNamePrefix = getServiceName() + "-files";
String namespace = getNamespace(resolvedConfiguration.getServiceSettings(getService()));
KubernetesAccount account = details.getAccount();
for (Entry<String, Profile> entry : profiles.entrySet()) {
Profile profile = entry.getValue();
String outputFile = profile.getOutputFile();
String mountPoint = Paths.get(outputFile).getParent().toString();
Set<Profile> profilesInDirectory = profilesByDirectory.getOrDefault(mountPoint, new HashSet<>());
profilesInDirectory.add(profile);
requiredFiles.addAll(profile.getRequiredFiles());
profilesByDirectory.put(mountPoint, profilesInDirectory);
}
for (Entry<String, Set<Profile>> entry : profilesByDirectory.entrySet()) {
Set<Profile> profilesInDirectory = entry.getValue();
String mountPath = entry.getKey();
List<SecretMountPair> files = profilesInDirectory.stream().map(p -> {
File input = new File(p.getStagedFile(stagingPath));
File output = new File(p.getOutputFile());
return new SecretMountPair(input, output);
}).collect(Collectors.toList());
Map<String, String> env = profilesInDirectory.stream().map(Profile::getEnv).map(Map::entrySet).flatMap(Collection::stream).collect(Collectors.toMap(Entry::getKey, Entry::getValue));
String name = KubernetesV2Utils.createSecret(account, namespace, secretNamePrefix, files);
configSources.add(new ConfigSource().setId(name).setMountPath(mountPath).setEnv(env));
}
if (!requiredFiles.isEmpty()) {
List<SecretMountPair> files = requiredFiles.stream().map(File::new).map(SecretMountPair::new).collect(Collectors.toList());
String name = KubernetesV2Utils.createSecret(account, namespace, secretNamePrefix, files);
configSources.add(new ConfigSource().setId(name).setMountPath(files.get(0).getContents().getParent()));
}
return configSources;
}
Aggregations