Search in sources :

Example 6 with JobExecutor

use of com.netflix.spinnaker.halyard.core.job.v1.JobExecutor in project halyard by spinnaker.

the class GoogleProviderUtils method ensureSshKeysExist.

private static void ensureSshKeysExist() {
    File sshKeyFile = new File(getSshKeyFile());
    if (!sshKeyFile.exists()) {
        if (!sshKeyFile.getParentFile().exists()) {
            sshKeyFile.getParentFile().mkdirs();
        }
        log.info("Generating a new ssh key file...");
        JobExecutor jobExecutor = DaemonTaskHandler.getJobExecutor();
        List<String> command = new ArrayList<>();
        command.add("ssh-keygen");
        // no password
        command.add("-N");
        command.add("");
        // rsa key
        command.add("-t");
        command.add("rsa");
        // path to keyfile
        command.add("-f");
        command.add(getSshKeyFile());
        // username sshing into machine
        command.add("-C");
        command.add("ubuntu");
        JobRequest request = new JobRequest().setTokenizedCommand(command);
        JobStatus status;
        try {
            status = jobExecutor.backoffWait(jobExecutor.startJob(request));
        } catch (InterruptedException e) {
            throw new DaemonTaskInterrupted(e);
        }
        if (status.getResult() == JobStatus.Result.FAILURE) {
            throw new HalException(FATAL, "ssh-keygen failed: " + status.getStdErr());
        }
        try {
            File sshPublicKeyFile = new File(getSshPublicKeyFile());
            String sshKeyContents = IOUtils.toString(new FileInputStream(sshPublicKeyFile));
            if (!sshKeyContents.startsWith("ubuntu:")) {
                sshKeyContents = "ubuntu:" + sshKeyContents;
                FileUtils.writeByteArrayToFile(sshPublicKeyFile, sshKeyContents.getBytes());
            }
        } catch (IOException e) {
            throw new HalException(FATAL, "Cannot reformat ssh key to match google key format expectation: " + e.getMessage(), e);
        }
        command = new ArrayList<>();
        command.add("chmod");
        command.add("400");
        command.add(getSshKeyFile());
        request = new JobRequest().setTokenizedCommand(command);
        try {
            status = jobExecutor.backoffWait(jobExecutor.startJob(request));
        } catch (InterruptedException e) {
            throw new DaemonTaskInterrupted(e);
        }
        if (status.getResult() == JobStatus.Result.FAILURE) {
            throw new HalException(FATAL, "chmod failed: " + status.getStdErr() + status.getStdOut());
        }
    }
}
Also used : HalException(com.netflix.spinnaker.halyard.core.error.v1.HalException) ArrayList(java.util.ArrayList) IOException(java.io.IOException) DaemonTaskInterrupted(com.netflix.spinnaker.halyard.core.tasks.v1.DaemonTaskInterrupted) FileInputStream(java.io.FileInputStream) JobStatus(com.netflix.spinnaker.halyard.core.job.v1.JobStatus) JobRequest(com.netflix.spinnaker.halyard.core.job.v1.JobRequest) JobExecutor(com.netflix.spinnaker.halyard.core.job.v1.JobExecutor) File(java.io.File)

Example 7 with JobExecutor

use of com.netflix.spinnaker.halyard.core.job.v1.JobExecutor in project halyard by spinnaker.

the class KubernetesAccountValidator method ensureKubectlExists.

public void ensureKubectlExists(ConfigProblemSetBuilder p) {
    JobExecutor jobExecutor = DaemonTaskHandler.getJobExecutor();
    JobRequest request = new JobRequest().setTokenizedCommand(Collections.singletonList("kubectl")).setTimeoutMillis(TimeUnit.SECONDS.toMillis(10));
    JobStatus status;
    try {
        status = jobExecutor.backoffWait(jobExecutor.startJob(request));
    } catch (InterruptedException e) {
        throw new DaemonTaskInterrupted(e);
    }
    if (status.getResult() != JobStatus.Result.SUCCESS) {
        p.addProblem(FATAL, String.join(" ", "`kubectl` not installed, or can't be found by Halyard. It is needed for", "opening connections to your Kubernetes cluster to send commands to the Spinnaker deployment running there.")).setRemediation(String.join(" ", "Visit https://kubernetes.io/docs/tasks/kubectl/install/.", "If you've already installed kubectl via gcloud, it's possible updates to your $PATH aren't visible to Halyard."));
    }
}
Also used : JobStatus(com.netflix.spinnaker.halyard.core.job.v1.JobStatus) JobRequest(com.netflix.spinnaker.halyard.core.job.v1.JobRequest) JobExecutor(com.netflix.spinnaker.halyard.core.job.v1.JobExecutor) DaemonTaskInterrupted(com.netflix.spinnaker.halyard.core.tasks.v1.DaemonTaskInterrupted)

Example 8 with JobExecutor

use of com.netflix.spinnaker.halyard.core.job.v1.JobExecutor in project halyard by spinnaker.

the class KubernetesV1ProviderUtils method openProxy.

static Proxy openProxy(JobExecutor jobExecutor, AccountDeploymentDetails<KubernetesAccount> details) {
    KubernetesAccount account = details.getAccount();
    Proxy proxy = proxyMap.getOrDefault(Proxy.buildKey(details.getDeploymentName()), new Proxy());
    String jobId = proxy.jobId;
    if (StringUtils.isEmpty(jobId) || !jobExecutor.jobExists(jobId)) {
        DaemonTaskHandler.newStage("Connecting to the Kubernetes cluster in account \"" + account.getName() + "\"");
        List<String> command = kubectlAccountCommand(details);
        command.add("proxy");
        // select a random port
        command.add("--port=0");
        JobRequest request = new JobRequest().setTokenizedCommand(command);
        proxy.jobId = jobExecutor.startJob(request);
        JobStatus status = jobExecutor.updateJob(proxy.jobId);
        while (status == null) {
            DaemonTaskHandler.safeSleep(TimeUnit.SECONDS.toMillis(2));
            status = jobExecutor.updateJob(proxy.jobId);
        }
        // This should be a long-running job.
        if (status.getState() == JobStatus.State.COMPLETED) {
            throw new HalException(Severity.FATAL, "Unable to establish a proxy against account " + account.getName() + ":\n" + status.getStdOut() + "\n" + status.getStdErr());
        }
        String connectionMessage = status.getStdOut();
        Pattern portPattern = Pattern.compile(":(\\d+)");
        Matcher matcher = portPattern.matcher(connectionMessage);
        if (matcher.find()) {
            proxy.setPort(Integer.valueOf(matcher.group(1)));
            proxyMap.put(Proxy.buildKey(details.getDeploymentName()), proxy);
            DaemonTaskHandler.message("Connected to kubernetes cluster for account " + account.getName() + " on port " + proxy.getPort());
            DaemonTaskHandler.message("View the kube ui on http://localhost:" + proxy.getPort() + "/ui/");
        } else {
            throw new HalException(Severity.FATAL, "Could not parse connection information from:\n" + connectionMessage + "(" + status.getStdErr() + ")");
        }
    }
    return proxy;
}
Also used : JobStatus(com.netflix.spinnaker.halyard.core.job.v1.JobStatus) Pattern(java.util.regex.Pattern) JobRequest(com.netflix.spinnaker.halyard.core.job.v1.JobRequest) Matcher(java.util.regex.Matcher) KubernetesAccount(com.netflix.spinnaker.halyard.config.model.v1.providers.kubernetes.KubernetesAccount) HalException(com.netflix.spinnaker.halyard.core.error.v1.HalException)

Example 9 with JobExecutor

use of com.netflix.spinnaker.halyard.core.job.v1.JobExecutor in project halyard by spinnaker.

the class GoogleProviderUtils method openSshTunnel.

static URI openSshTunnel(AccountDeploymentDetails<GoogleAccount> details, String instanceName, ServiceSettings service) throws InterruptedException {
    int port = service.getPort();
    String key = Proxy.buildKey(details.getDeploymentName(), instanceName, port);
    Proxy proxy = proxyMap.getOrDefault(key, new Proxy());
    JobExecutor jobExecutor = DaemonTaskHandler.getJobExecutor();
    if (proxy.getJobId() == null || !jobExecutor.jobExists(proxy.getJobId())) {
        String ip = getInstanceIp(details, instanceName);
        String keyFile = getSshKeyFile();
        log.info("Opening port " + port + " against instance " + instanceName);
        boolean connected = false;
        int tries = 0;
        while (!connected && tries < openSshRetries) {
            tries++;
            proxy = openSshTunnel(ip, port, keyFile);
            connected = checkIfProxyIsOpen(proxy);
            if (!connected) {
                if (!jobExecutor.jobExists(proxy.jobId) || jobExecutor.updateJob(proxy.jobId).getState() == JobStatus.State.COMPLETED) {
                    log.warn("SSH tunnel closed prematurely");
                }
                log.info("SSH tunnel never opened, retrying in case the instance hasn't started yet... (" + tries + "/" + openSshRetries + ")");
                closeSshTunnel(proxy);
                DaemonTaskHandler.safeSleep(TimeUnit.SECONDS.toMillis(10));
            }
        }
        if (!connected) {
            JobStatus status = jobExecutor.updateJob(proxy.getJobId());
            throw new HalException(FATAL, "Unable to connect to instance " + instanceName + ": " + status.getStdErr());
        }
        proxyMap.put(key, proxy);
    }
    try {
        return new URIBuilder().setScheme("http").setHost("localhost").setPort(proxy.getPort()).build();
    } catch (URISyntaxException e) {
        throw new RuntimeException("Failed to build URI for SSH connection", e);
    }
}
Also used : JobStatus(com.netflix.spinnaker.halyard.core.job.v1.JobStatus) JobExecutor(com.netflix.spinnaker.halyard.core.job.v1.JobExecutor) HalException(com.netflix.spinnaker.halyard.core.error.v1.HalException) URISyntaxException(java.net.URISyntaxException) URIBuilder(org.apache.http.client.utils.URIBuilder)

Aggregations

JobRequest (com.netflix.spinnaker.halyard.core.job.v1.JobRequest)7 JobStatus (com.netflix.spinnaker.halyard.core.job.v1.JobStatus)7 JobExecutor (com.netflix.spinnaker.halyard.core.job.v1.JobExecutor)6 HalException (com.netflix.spinnaker.halyard.core.error.v1.HalException)5 DaemonTaskInterrupted (com.netflix.spinnaker.halyard.core.tasks.v1.DaemonTaskInterrupted)4 ArrayList (java.util.ArrayList)3 File (java.io.File)2 IOException (java.io.IOException)2 AnsiParagraphBuilder (com.netflix.spinnaker.halyard.cli.ui.v1.AnsiParagraphBuilder)1 AnsiStoryBuilder (com.netflix.spinnaker.halyard.cli.ui.v1.AnsiStoryBuilder)1 KubernetesAccount (com.netflix.spinnaker.halyard.config.model.v1.providers.kubernetes.KubernetesAccount)1 RemoteAction (com.netflix.spinnaker.halyard.core.RemoteAction)1 FileInputStream (java.io.FileInputStream)1 FileOutputStream (java.io.FileOutputStream)1 URISyntaxException (java.net.URISyntaxException)1 Matcher (java.util.regex.Matcher)1 Pattern (java.util.regex.Pattern)1 URIBuilder (org.apache.http.client.utils.URIBuilder)1