kubernetes-client / csharp

Officially supported dotnet Kubernetes Client library
Apache License 2.0
1.1k stars 295 forks source link

How to approve generated k8s signin certificate? #814

Closed kibernetik542 closed 2 years ago

kibernetik542 commented 2 years ago

I have method to generate signin certificate and in the end I'd like try to approve it same as approving csr in official doc

My whole code looks like:

        var certificate = "...";
        var bases = Convert.FromBase64String(cert);
        var reqq = new V1CertificateSigningRequest
        {
            ApiVersion = "certificates.k8s.io/v1",
            Kind = "CertificateSigningRequest",
            Metadata = new V1ObjectMeta
            {
                Name = "sonic"
            },
            Spec = new V1CertificateSigningRequestSpec
            {
                Request = bases,
                SignerName = "kubernetes.io/kube-apiserver-client",
                Usages = new List<string> { "client auth" },
                ExpirationSeconds = 600
            }
        };
        var sign = await client.CreateCertificateSigningRequestAsync(reqq, cancellationToken: cancellationToken);

        var restart = new List<V1CertificateSigningRequestCondition>
        {
            new("Approved", "Approved", DateTime.UtcNow, DateTime.UtcNow, "Certificate Approved")
        };
        var patch = new JsonPatchDocument<V1CertificateSigningRequest>();
        patch.Replace(e => e.Status.Conditions, restart);
        await client.PatchCertificateSigningRequestAsync(new V1Patch(patch, V1Patch.PatchType.JsonPatch),
          "sonic", cancellationToken: cancellationToken);

I was not able to find put method for this so I decided to use path instead. Is it any another way for this, or what I am doing wrong?

P.S. I am getting BadRequest back as exception

tg123 commented 2 years ago

the reason of badrequest is due to you are using old jsonpatch library #772

put method == replace?

kibernetik542 commented 2 years ago

the reason of badrequest is due to you are using old jsonpatch library #772

put method == replace?

thanks for answer, simply I would like to approve csr, I don't know it should be values replaced or merge patch.

1 - it seems it is general issue with Microsoft.AspNetCore.JsonPatch ( I also tried Microsoft.AspNetCore.Mvc.Formatters version ) followed this issue which is still open

here

2 - It was issue also in go client, and in this client I see it is UpdateApproval method which I was not able to find

3 - I also tried example from minkube-tests

Installed json patch nuget and applied code like this in deployment patch but it returned Operation returned an invalid status code 'UnprocessableEntity'

And code looks like this:

        var config = KubernetesClientConfiguration.BuildConfigFromConfigFile(fileName);
        IKubernetes client = new k8s.Kubernetes(config);
        config.HttpClientTimeout = new TimeSpan(0, 0, 0, 5);
        var serializeOptions = new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            WriteIndented = true
        };
        var deployment = await client.ReadNamespacedDeploymentAsync(request.Name, request.Namespace, cancellationToken: cancellationToken);
        var old = JsonSerializer.SerializeToDocument(deployment,serializeOptions);

        var restart = new Dictionary<string, string>(deployment.Metadata.Annotations)
        {
            ["kubectl.kubernetes.io/restartedAt"] = DateTime.UtcNow.ToString("s")
        };
        deployment.Metadata.Annotations = restart;

        var expected = JsonSerializer.SerializeToDocument(deployment,serializeOptions);
        var patch = old.CreatePatch(expected);
        await client.PatchNamespacedDeploymentAsync(new V1Patch(patch, V1Patch.PatchType.JsonPatch), request.Name, request.Namespace, cancellationToken: cancellationToken);

Question how to properly do approve csr functionality?

brendandburns commented 2 years ago

The easier thing to do is to use client.replace but if you use replace you will need to do (pseudo-code)

currentCSR = getCSR
newCSR = modifyCSR(currentCSR)
replaceCSR(newCSR)

Patch should work in theory, but patch is definitely harder to get right.

kibernetik542 commented 2 years ago

The easier thing to do is to use client.replace but if you use replace you will need to do (pseudo-code)


currentCSR = getCSR

newCSR = modifyCSR(currentCSR)

replaceCSR(newCSR)

Patch should work in theory, but patch is definitely harder to get right.

Patch worked on 6x version of k8s client. After 7x it is System.Text.Json major update on client side. I described several problems and what I tried to fix. Well it is not only approve csr. We have also restart deployment and daemon set via using patch approach ( which worked on 6x version ) now they are also broken due to release. I will try replace but is it efficient to use replace instead of patch? As we are only changing few lines. Thanks for reply

kibernetik542 commented 2 years ago

After spending some time I found I am calling wrong method for approval.

I should call below method and all works fine.

Well not recommended to use Microsoft.AspNetCore.JsonPatch

1 - First it is compatible with Newtonsoft.Json 2 - It will not work with k8s client > 7x

Solution Using JsonPatch.Net

await client.PatchCertificateSigningRequestApprovalAsync(new V1Patch(patch, V1Patch.PatchType.JsonPatch), name, cancellationToken: cancellationToken);

tg123 commented 2 years ago

could you please send an example PR of CSR approval?

kibernetik542 commented 2 years ago

could you please send an example PR of CSR approval?

Made PR, please check it out