Search in sources :

Example 6 with ImmutableGcloudExtension

use of org.curioswitch.gradle.plugins.gcloud.ImmutableGcloudExtension in project curiostack by curioswitch.

the class CreateClientCertTask method exec.

@TaskAction
public void exec() {
    ImmutableClusterExtension cluster = getProject().getExtensions().getByType(ClusterExtension.class);
    String commonName = (String) getProject().getRootProject().findProperty("commonName");
    checkNotNull(commonName, "-PcommonName must be set");
    final KeyPairGenerator keygen;
    try {
        keygen = KeyPairGenerator.getInstance("ECDSA", BouncyCastleProvider.PROVIDER_NAME);
    } catch (NoSuchAlgorithmException | NoSuchProviderException e) {
        throw new IllegalStateException("Could not find RSA, can't happen.", e);
    }
    keygen.initialize(256, new SecureRandom());
    KeyPair keyPair = keygen.generateKeyPair();
    PKCS10CertificationRequestBuilder p10Builder = new JcaPKCS10CertificationRequestBuilder(new X500Principal("CN=" + commonName), keyPair.getPublic());
    final ContentSigner signer;
    try {
        signer = new JcaContentSignerBuilder("SHA256withECDSA").build(keyPair.getPrivate());
    } catch (OperatorCreationException e) {
        throw new IllegalStateException("Could not find signer, can't happen.", e);
    }
    PKCS10CertificationRequest csr = p10Builder.build(signer);
    StringWriter csrWriter = new StringWriter();
    try (JcaPEMWriter pemWriter = new JcaPEMWriter(csrWriter)) {
        pemWriter.writeObject(csr);
    } catch (IOException e) {
        throw new IllegalStateException("Could not encode csr, can't happen.", e);
    }
    String encodedCsr = Base64.getEncoder().encodeToString(csrWriter.toString().getBytes(StandardCharsets.UTF_8));
    String csrName = cluster.namespace() + "." + commonName + ".client.crt";
    Map<Object, Object> csrApiRequest = ImmutableMap.of("apiVersion", "certificates.k8s.io/v1beta1", "kind", "CertificateSigningRequest", "metadata", ImmutableMap.of("name", csrName), "spec", ImmutableMap.of("request", encodedCsr, "usages", ImmutableList.of("digital signature", "key encipherment", "server auth", "client auth")));
    final byte[] encodedApiRequest;
    try {
        encodedApiRequest = OBJECT_MAPPER.writeValueAsBytes(csrApiRequest);
    } catch (JsonProcessingException e) {
        throw new IllegalStateException("Could not encode yaml", e);
    }
    ImmutableGcloudExtension config = getProject().getRootProject().getExtensions().getByType(GcloudExtension.class);
    String command = config.download() ? new File(config.platformConfig().gcloudBinDir(), "kubectl").getAbsolutePath() : "kubectl";
    getProject().exec(exec -> {
        exec.executable(command);
        exec.args("create", "-f", "-");
        exec.setStandardInput(new ByteArrayInputStream(encodedApiRequest));
    });
    getProject().exec(exec -> {
        exec.executable(command);
        exec.args("certificate", "approve", csrName);
    });
    // Need to wait a bit for certificate to propagate before fetching.
    try {
        TimeUnit.SECONDS.sleep(5);
    } catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
    ByteArrayOutputStream certStream = new ByteArrayOutputStream();
    getProject().exec(exec -> {
        exec.executable(command);
        exec.args("get", "csr", csrName, "-o", "jsonpath={.status.certificate}");
        exec.setStandardOutput(certStream);
    });
    String certificate = new String(Base64.getDecoder().decode(certStream.toByteArray()), StandardCharsets.UTF_8);
    final JcaPKCS8Generator keyGenerator;
    final PemObject keyObject;
    try {
        keyGenerator = new JcaPKCS8Generator(keyPair.getPrivate(), null);
        keyObject = keyGenerator.generate();
    } catch (PemGenerationException e) {
        throw new IllegalStateException("Could not encode to pkcs8.", e);
    }
    StringWriter keyWriter = new StringWriter();
    try (JcaPEMWriter pemWriter = new JcaPEMWriter(keyWriter)) {
        pemWriter.writeObject(keyObject);
    } catch (IOException e) {
        throw new IllegalStateException("Could not encode csr, can't happen.", e);
    }
    String key = keyWriter.toString();
    KubernetesClient client = new DefaultKubernetesClient();
    Secret certificateSecret = new SecretBuilder().withMetadata(new ObjectMetaBuilder().withName(commonName + "-client-tls").withNamespace(cluster.namespace()).build()).withType("Opaque").withData(ImmutableMap.of("client.crt", Base64.getEncoder().encodeToString(certificate.getBytes(StandardCharsets.UTF_8)), "client-key.pem", Base64.getEncoder().encodeToString(key.getBytes(StandardCharsets.UTF_8)))).build();
    client.resource(certificateSecret).createOrReplace();
}
Also used : ImmutableGcloudExtension(org.curioswitch.gradle.plugins.gcloud.ImmutableGcloudExtension) JcaContentSignerBuilder(org.bouncycastle.operator.jcajce.JcaContentSignerBuilder) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) ImmutableClusterExtension(org.curioswitch.gradle.plugins.gcloud.ImmutableClusterExtension) SecretBuilder(io.fabric8.kubernetes.api.model.SecretBuilder) StringWriter(java.io.StringWriter) JcaPKCS8Generator(org.bouncycastle.openssl.jcajce.JcaPKCS8Generator) OperatorCreationException(org.bouncycastle.operator.OperatorCreationException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) PKCS10CertificationRequest(org.bouncycastle.pkcs.PKCS10CertificationRequest) KeyPair(java.security.KeyPair) DefaultKubernetesClient(io.fabric8.kubernetes.client.DefaultKubernetesClient) KubernetesClient(io.fabric8.kubernetes.client.KubernetesClient) JcaPKCS10CertificationRequestBuilder(org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder) PemGenerationException(org.bouncycastle.util.io.pem.PemGenerationException) ContentSigner(org.bouncycastle.operator.ContentSigner) SecureRandom(java.security.SecureRandom) PKCS10CertificationRequestBuilder(org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder) JcaPKCS10CertificationRequestBuilder(org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequestBuilder) KeyPairGenerator(java.security.KeyPairGenerator) IOException(java.io.IOException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ObjectMetaBuilder(io.fabric8.kubernetes.api.model.ObjectMetaBuilder) Secret(io.fabric8.kubernetes.api.model.Secret) PemObject(org.bouncycastle.util.io.pem.PemObject) ByteArrayInputStream(java.io.ByteArrayInputStream) X500Principal(javax.security.auth.x500.X500Principal) PemObject(org.bouncycastle.util.io.pem.PemObject) DefaultKubernetesClient(io.fabric8.kubernetes.client.DefaultKubernetesClient) NoSuchProviderException(java.security.NoSuchProviderException) JcaPEMWriter(org.bouncycastle.openssl.jcajce.JcaPEMWriter) File(java.io.File) TaskAction(org.gradle.api.tasks.TaskAction)

Aggregations

ImmutableGcloudExtension (org.curioswitch.gradle.plugins.gcloud.ImmutableGcloudExtension)6 TaskAction (org.gradle.api.tasks.TaskAction)5 ImmutableList (com.google.common.collect.ImmutableList)3 ImmutableMap (com.google.common.collect.ImmutableMap)3 ObjectMetaBuilder (io.fabric8.kubernetes.api.model.ObjectMetaBuilder)3 DefaultKubernetesClient (io.fabric8.kubernetes.client.DefaultKubernetesClient)3 KubernetesClient (io.fabric8.kubernetes.client.KubernetesClient)3 Map (java.util.Map)3 GcloudExtension (org.curioswitch.gradle.plugins.gcloud.GcloudExtension)3 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)2 Secret (io.fabric8.kubernetes.api.model.Secret)2 SecretBuilder (io.fabric8.kubernetes.api.model.SecretBuilder)2 File (java.io.File)2 DefaultTask (org.gradle.api.DefaultTask)2 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)1 YAMLFactory (com.fasterxml.jackson.dataformat.yaml.YAMLFactory)1 Domain (com.google.cloud.storage.Acl.Domain)1 Storage (com.google.cloud.storage.Storage)1 Streams (com.google.common.collect.Streams)1 ByteStreams (com.google.common.io.ByteStreams)1