use of com.netflix.spinnaker.halyard.deploy.spinnaker.v1.RunningServiceDetails.Instance in project halyard by spinnaker.
the class KubernetesV1DistributedService method connectCommand.
default String connectCommand(AccountDeploymentDetails<KubernetesAccount> details, SpinnakerRuntimeSettings runtimeSettings, int localPort) {
ServiceSettings settings = runtimeSettings.getServiceSettings(getService());
RunningServiceDetails runningServiceDetails = getRunningServiceDetails(details, runtimeSettings);
Map<Integer, List<Instance>> instances = runningServiceDetails.getInstances();
Integer latest = runningServiceDetails.getLatestEnabledVersion();
String namespace = getNamespace(settings);
List<Instance> latestInstances = instances.get(latest);
if (latestInstances.isEmpty()) {
throw new HalException(Problem.Severity.FATAL, "No instances running in latest server group for service " + getServiceName() + " in namespace " + namespace);
}
return Strings.join(KubernetesV1ProviderUtils.kubectlPortForwardCommand(details, namespace, latestInstances.get(0).getId(), settings.getPort(), localPort), " ");
}
use of com.netflix.spinnaker.halyard.deploy.spinnaker.v1.RunningServiceDetails.Instance in project halyard by spinnaker.
the class GoogleDistributedService method connectCommand.
@Override
default String connectCommand(AccountDeploymentDetails<GoogleAccount> details, SpinnakerRuntimeSettings runtimeSettings) {
RunningServiceDetails runningServiceDetails = getRunningServiceDetails(details, runtimeSettings);
Integer version = runningServiceDetails.getLatestEnabledVersion();
if (version == null) {
throw new HalException(FATAL, "No version of " + getServiceName() + " to connect to.");
}
List<RunningServiceDetails.Instance> instances = runningServiceDetails.getInstances().get(version);
if (instances.isEmpty()) {
throw new HalException(FATAL, "Version " + version + " of " + getServiceName() + " has no instances to connect to");
}
RunningServiceDetails.Instance instance = instances.get(0);
String instanceName = instance.getId();
String zone = instance.getLocation();
ServiceSettings settings = runtimeSettings.getServiceSettings(getService());
int port = settings.getPort();
return String.format("gcloud compute ssh %s --zone %s -- -L %d:localhost:%d -N", instanceName, zone, port, port);
}
use of com.netflix.spinnaker.halyard.deploy.spinnaker.v1.RunningServiceDetails.Instance in project halyard by spinnaker.
the class GoogleDistributedService method getMetadata.
default List<Metadata.Items> getMetadata(AccountDeploymentDetails<GoogleAccount> details, SpinnakerRuntimeSettings runtimeSettings, List<ConfigSource> configSources, Integer version) {
List<Metadata.Items> metadataItems = new ArrayList<>();
String deploymentName = details.getDeploymentName();
Metadata.Items items = new Metadata.Items().setKey("startup-script").setValue(getStartupScript());
metadataItems.add(items);
items = new Metadata.Items().setKey("ssh-keys").setValue(GoogleProviderUtils.getSshPublicKey());
metadataItems.add(items);
if (!configSources.isEmpty()) {
DaemonTaskHandler.message("Mounting config in vault server");
GoogleVaultServerService vaultService = getVaultServerService();
VaultServerService.Vault vault = vaultService.connectToPrimaryService(details, runtimeSettings);
String secretName = secretName("config-mounts", version);
VaultConfigMountSet mountSet = VaultConfigMountSet.fromConfigSources(configSources);
secretName = vaultService.writeVaultConfigMountSet(deploymentName, vault, secretName, mountSet);
VaultConnectionDetails connectionDetails = buildConnectionDetails(details, runtimeSettings, secretName);
DaemonTaskHandler.message("Placing vault connection details into instance metadata");
items = new Metadata.Items().setKey("vault_address").setValue(connectionDetails.getAddress());
metadataItems.add(items);
items = new Metadata.Items().setKey("vault_token").setValue(connectionDetails.getToken());
metadataItems.add(items);
items = new Metadata.Items().setKey("vault_secret").setValue(connectionDetails.getSecret());
metadataItems.add(items);
}
GoogleConsulServerService consulServerService = getConsulServerService();
RunningServiceDetails consulServerDetails = consulServerService.getRunningServiceDetails(details, runtimeSettings);
Integer latestConsulVersion = consulServerDetails.getLatestEnabledVersion();
if (latestConsulVersion != null) {
List<RunningServiceDetails.Instance> instances = consulServerDetails.getInstances().get(latestConsulVersion);
String instancesValue = String.join(" ", instances.stream().map(RunningServiceDetails.Instance::getId).collect(Collectors.toList()));
items = new Metadata.Items().setKey(// TODO(lwander) change to consul_members for consistency w/ vault
"consul-members").setValue(instancesValue);
DaemonTaskHandler.message("Placing consul connection details into instance metadata");
metadataItems.add(items);
}
return metadataItems;
}
use of com.netflix.spinnaker.halyard.deploy.spinnaker.v1.RunningServiceDetails.Instance in project halyard by spinnaker.
the class GoogleDistributedService method ensureRunning.
@Override
default void ensureRunning(AccountDeploymentDetails<GoogleAccount> details, ResolvedConfiguration resolvedConfiguration, List<ConfigSource> configSources, boolean recreate) {
DaemonTaskHandler.newStage("Deploying " + getServiceName() + " via GCE API");
Integer version = 0;
ServiceSettings settings = resolvedConfiguration.getServiceSettings(getService());
SpinnakerRuntimeSettings runtimeSettings = resolvedConfiguration.getRuntimeSettings();
RunningServiceDetails runningServiceDetails = getRunningServiceDetails(details, runtimeSettings);
GoogleAccount account = details.getAccount();
Compute compute = GoogleProviderUtils.getCompute(details);
String project = account.getProject();
String zone = settings.getLocation();
boolean exists = runningServiceDetails.getInstances().containsKey(version);
if (!recreate && exists) {
DaemonTaskHandler.message("Service " + getServiceName() + " is already deployed and not safe to restart");
return;
} else if (exists) {
DaemonTaskHandler.message("Recreating existing " + getServiceName() + "...");
deleteVersion(details, settings, version);
}
InstanceGroupManager manager = new InstanceGroupManager();
InstanceTemplate template = new InstanceTemplate().setName(getServiceName() + "-hal-" + System.currentTimeMillis()).setDescription("Halyard-generated instance template for deploying Spinnaker");
Metadata metadata = new Metadata().setItems(getMetadata(details, runtimeSettings, configSources, version));
AccessConfig accessConfig = new AccessConfig().setName("External NAT").setType("ONE_TO_ONE_NAT");
NetworkInterface networkInterface = new NetworkInterface().setNetwork(GoogleProviderUtils.ensureSpinnakerNetworkExists(details)).setAccessConfigs(Collections.singletonList(accessConfig));
ServiceAccount sa = new ServiceAccount().setEmail(GoogleProviderUtils.defaultServiceAccount(details)).setScopes(getScopes());
InstanceProperties properties = new InstanceProperties().setMachineType(getDefaultInstanceType()).setMetadata(metadata).setServiceAccounts(Collections.singletonList(sa)).setNetworkInterfaces(Collections.singletonList(networkInterface));
AttachedDisk disk = new AttachedDisk().setBoot(true).setAutoDelete(true).setType("PERSISTENT");
AttachedDiskInitializeParams diskParams = new AttachedDiskInitializeParams().setDiskSizeGb(20L).setDiskStorageType(GCEUtil.buildDiskTypeUrl(project, zone, GoogleDiskType.PD_SSD)).setSourceImage(getArtifactId(details.getDeploymentName()));
disk.setInitializeParams(diskParams);
List<AttachedDisk> disks = new ArrayList<>();
disks.add(disk);
properties.setDisks(disks);
template.setProperties(properties);
String instanceTemplateUrl;
Operation operation;
try {
DaemonTaskHandler.message("Creating an instance template");
operation = compute.instanceTemplates().insert(project, template).execute();
instanceTemplateUrl = operation.getTargetLink();
GoogleProviderUtils.waitOnGlobalOperation(compute, project, operation);
} catch (IOException e) {
throw new HalException(FATAL, "Failed to create instance template for " + settings.getArtifactId() + ": " + e.getMessage(), e);
}
String migName = getVersionedName(version);
manager.setInstanceTemplate(instanceTemplateUrl);
manager.setBaseInstanceName(migName);
manager.setTargetSize(settings.getTargetSize());
manager.setName(migName);
try {
DaemonTaskHandler.message("Deploying the instance group manager");
operation = compute.instanceGroupManagers().insert(project, settings.getLocation(), manager).execute();
GoogleProviderUtils.waitOnZoneOperation(compute, project, settings.getLocation(), operation);
} catch (IOException e) {
throw new HalException(FATAL, "Failed to create instance group to run artifact " + settings.getArtifactId() + ": " + e.getMessage(), e);
}
boolean ready = false;
DaemonTaskHandler.message("Waiting for all instances to become healthy.");
while (!ready) {
ready = getRunningServiceDetails(details, runtimeSettings).getLatestEnabledVersion() == version;
DaemonTaskHandler.safeSleep(TimeUnit.SECONDS.toMillis(2));
}
}
use of com.netflix.spinnaker.halyard.deploy.spinnaker.v1.RunningServiceDetails.Instance 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;
}
Aggregations