├── .devcontainer
└── devcontainer.json
├── .editorconfig
├── .gitattributes
├── .github
├── ISSUE_TEMPLATE
│ └── bug_report.md
├── dependabot.yml
└── workflows
│ ├── buildtest.yaml
│ ├── codeql-analysis.yml
│ ├── docfx.yaml
│ ├── draft.yaml
│ └── nuget.yaml
├── .gitignore
├── CONTRIBUTING.md
├── CodeCoverage.runsettings
├── Directory.Build.props
├── Directory.Build.targets
├── Directory.Packages.props
├── LICENSE
├── OWNERS
├── README.md
├── SECURITY_CONTACTS
├── code-of-conduct.md
├── csharp.settings
├── doc
├── .gitignore
├── docfx.json
├── index.md
└── toc.yml
├── examples
├── Directory.Build.props
├── Directory.Build.targets
├── aks-kubelogin
│ ├── Program.cs
│ ├── README.md
│ └── aks-kubelogin.csproj
├── aot
│ ├── Program.cs
│ └── aot.csproj
├── attach
│ ├── Attach.cs
│ └── attach.csproj
├── clientset
│ ├── Program.cs
│ └── clientset.csproj
├── cp
│ ├── Cp.cs
│ └── cp.csproj
├── csrApproval
│ ├── Program.cs
│ └── csrApproval.csproj
├── customResource
│ ├── CustomResourceDefinition.cs
│ ├── Program.cs
│ ├── README.md
│ ├── Utils.cs
│ ├── cResource.cs
│ ├── config
│ │ ├── crd.yaml
│ │ └── yaml-cr-instance.yaml
│ └── customResource.csproj
├── exec
│ ├── Exec.cs
│ └── exec.csproj
├── generic
│ ├── Generic.cs
│ └── generic.csproj
├── labels
│ ├── PodList.cs
│ └── labels.csproj
├── logs
│ ├── Logs.cs
│ └── logs.csproj
├── metrics
│ ├── Program.cs
│ └── metrics.csproj
├── namespace
│ ├── NamespaceExample.cs
│ └── namespace.csproj
├── openTelemetryConsole
│ ├── Program.cs
│ └── openTelemetryConsole.csproj
├── patch-aot
│ ├── Program.cs
│ └── patch-aot.csproj
├── patch
│ ├── Program.cs
│ └── patch.csproj
├── portforward
│ ├── PortForward.cs
│ └── portforward.csproj
├── restart
│ ├── Program.cs
│ └── restart.csproj
├── simple
│ ├── PodList.cs
│ └── simple.csproj
├── watch
│ ├── Program.cs
│ └── watch.csproj
├── webApiDependencyInjection
│ ├── Controllers
│ │ ├── ExampleDependencyInjectionOnConstructorController.cs
│ │ └── ExampleDependencyInjectionOnMethodController.cs
│ ├── Program.cs
│ ├── appsettings.Development.json
│ ├── appsettings.json
│ └── webApiDependencyInjection.csproj
├── workerServiceDependencyInjection
│ ├── Program.cs
│ ├── Worker.cs
│ ├── appsettings.Development.json
│ ├── appsettings.json
│ └── workerServiceDependencyInjection.csproj
└── yaml
│ ├── Program.cs
│ └── yaml.csproj
├── global.json
├── kubernetes-client.proj
├── kubernetes-client.ruleset
├── logo.png
├── nuget.config
├── src
├── KubernetesClient.Aot
│ ├── Global.cs
│ ├── KubeConfigModels
│ │ ├── AuthProvider.cs
│ │ ├── Cluster.cs
│ │ ├── ClusterEndpoint.cs
│ │ ├── Context.cs
│ │ ├── ContextDetails.cs
│ │ ├── ExecCredentialResponse.cs
│ │ ├── ExternalExecution.cs
│ │ ├── K8SConfiguration.cs
│ │ ├── StaticContext.cs
│ │ ├── User.cs
│ │ └── UserCredentials.cs
│ ├── KubernetesClient.Aot.csproj
│ ├── KubernetesClientConfiguration.ConfigFile.cs
│ ├── KubernetesJson.cs
│ ├── KubernetesYaml.cs
│ ├── SourceGenerationContext.cs
│ └── V1PatchJsonConverter.cs
├── KubernetesClient.Classic
│ ├── CertUtils.cs
│ ├── Global.cs
│ ├── Kubernetes.Websocket.Netstandard.cs
│ └── KubernetesClient.Classic.csproj
├── KubernetesClient.Kubectl
│ ├── Beta
│ │ ├── AsyncKubectl.Cordon.cs
│ │ ├── AsyncKubectl.Version.cs
│ │ ├── AsyncKubectl.cs
│ │ ├── Kubectl.Cordon.cs
│ │ ├── Kubectl.Version.cs
│ │ └── Kubectl.cs
│ └── KubernetesClient.Kubectl.csproj
├── KubernetesClient
│ ├── AbstractKubernetes.cs
│ ├── Authentication
│ │ ├── BasicAuthenticationCredentials.cs
│ │ ├── ExecTokenProvider.cs
│ │ ├── ITokenProvider.cs
│ │ ├── OidcTokenProvider.cs
│ │ ├── ServiceClientCredentials.cs
│ │ ├── StringTokenProvider.cs
│ │ ├── TokenCredentials.cs
│ │ └── TokenFileAuth.cs
│ ├── Autorest
│ │ ├── HttpExtensions.cs
│ │ ├── HttpMessageWrapper.cs
│ │ ├── HttpOperationException.cs
│ │ ├── HttpOperationResponse.cs
│ │ ├── HttpRequestMessageWrapper.cs
│ │ └── HttpResponseMessageWrapper.cs
│ ├── ByteBuffer.cs
│ ├── CertUtils.cs
│ ├── ChannelIndex.cs
│ ├── ClientSets
│ │ ├── ClientSet.cs
│ │ └── ResourceClient.cs
│ ├── Exceptions
│ │ ├── KubeConfigException.cs
│ │ └── KubernetesClientException.cs
│ ├── ExecAsyncCallback.cs
│ ├── Extensions.cs
│ ├── FileSystem.cs
│ ├── FloatEmitter.cs
│ ├── GeneratedApiVersion.cs
│ ├── GenericClient.cs
│ ├── Global.cs
│ ├── IItems.cs
│ ├── IKubernetes.Exec.cs
│ ├── IKubernetes.WebSocket.cs
│ ├── IKubernetes.cs
│ ├── IKubernetesObject.cs
│ ├── IMetadata.cs
│ ├── ISpec.cs
│ ├── IStatus.cs
│ ├── IStreamDemuxer.cs
│ ├── IValidate.cs
│ ├── KubeConfigModels
│ │ ├── AuthProvider.cs
│ │ ├── Cluster.cs
│ │ ├── ClusterEndpoint.cs
│ │ ├── Context.cs
│ │ ├── ContextDetails.cs
│ │ ├── ExecCredentialResponse.cs
│ │ ├── ExternalExecution.cs
│ │ ├── K8SConfiguration.cs
│ │ ├── NamedExtension.cs
│ │ ├── User.cs
│ │ └── UserCredentials.cs
│ ├── Kubernetes.ConfigInit.cs
│ ├── Kubernetes.Exec.cs
│ ├── Kubernetes.WebSocket.cs
│ ├── Kubernetes.cs
│ ├── KubernetesClient.csproj
│ ├── KubernetesClientConfiguration.ConfigFile.cs
│ ├── KubernetesClientConfiguration.InCluster.cs
│ ├── KubernetesClientConfiguration.cs
│ ├── KubernetesException.cs
│ ├── KubernetesJson.cs
│ ├── KubernetesMetricsExtensions.cs
│ ├── KubernetesObject.cs
│ ├── KubernetesRequestDigest.cs
│ ├── KubernetesYaml.cs
│ ├── LeaderElection
│ │ ├── ILock.cs
│ │ ├── LeaderElectionConfig.cs
│ │ ├── LeaderElectionRecord.cs
│ │ ├── LeaderElector.cs
│ │ └── ResourceLock
│ │ │ ├── ConfigMapLock.cs
│ │ │ ├── EndpointsLock.cs
│ │ │ ├── LeaseLock.cs
│ │ │ ├── MetaObjectAnnotationLock.cs
│ │ │ ├── MetaObjectLock.cs
│ │ │ └── MultiLock.cs
│ ├── LineSeparatedHttpContent.cs
│ ├── Models
│ │ ├── ContainerMetrics.cs
│ │ ├── GeneratedModelVersion.cs
│ │ ├── IntOrStringJsonConverter.cs
│ │ ├── IntOrStringYamlConverter.cs
│ │ ├── IntstrIntOrString.cs
│ │ ├── KubernetesEntityAttribute.cs
│ │ ├── KubernetesList.cs
│ │ ├── ModelExtensions.cs
│ │ ├── ModelVersionConverter.cs
│ │ ├── NodeMetrics.cs
│ │ ├── NodeMetricsList.cs
│ │ ├── PodMetrics.cs
│ │ ├── PodMetricsList.cs
│ │ ├── ResourceQuantity.cs
│ │ ├── ResourceQuantityJsonConverter.cs
│ │ ├── ResourceQuantityYamlConverter.cs
│ │ ├── V1Patch.cs
│ │ ├── V1PatchJsonConverter.cs
│ │ ├── V1PodTemplateSpec.cs
│ │ ├── V1Status.ObjectView.cs
│ │ └── V1Status.cs
│ ├── MuxedStream.cs
│ ├── PrometheusHandler.cs
│ ├── StreamDemuxer.cs
│ ├── StreamType.cs
│ ├── StringQuotingEmitter.cs
│ ├── Utilities.cs
│ ├── Watcher.cs
│ ├── WatcherExt.cs
│ ├── WebSocketBuilder.cs
│ └── WebSocketProtocol.cs
├── LibKubernetesGenerator
│ ├── ApiGenerator.cs
│ ├── ClassNameHelper.cs
│ ├── ClientSetGenerator.cs
│ ├── EmbedResource.cs
│ ├── GeneralNameHelper.cs
│ ├── GeneratorExecutionContextExt.cs
│ ├── IScriptObjectHelper.cs
│ ├── KubernetesClientSourceGenerator.cs
│ ├── LibKubernetesGenerator.target
│ ├── MetaHelper.cs
│ ├── ModelExtGenerator.cs
│ ├── ModelGenerator.cs
│ ├── ParamHelper.cs
│ ├── PluralHelper.cs
│ ├── ScriptObjectFactory.cs
│ ├── SourceGenerationContextGenerator.cs
│ ├── StringHelpers.cs
│ ├── TypeHelper.cs
│ ├── UtilHelper.cs
│ ├── VersionConverterStubGenerator.cs
│ ├── VersionGenerator.cs
│ ├── generators
│ │ └── LibKubernetesGenerator
│ │ │ └── LibKubernetesGenerator.csproj
│ └── templates
│ │ ├── AbstractKubernetes.cs.template
│ │ ├── Client.cs.template
│ │ ├── ClientSet.cs.template
│ │ ├── GroupClient.cs.template
│ │ ├── IBasicKubernetes.cs.template
│ │ ├── IOperations.cs.template
│ │ ├── Model.cs.template
│ │ ├── ModelExtensions.cs.template
│ │ ├── Operations.cs.template
│ │ ├── OperationsExtensions.cs.template
│ │ └── SourceGenerationContext.cs.template
└── nuget.proj
├── stylecop.json
├── swagger.json
├── tests
├── E2E.Aot.Tests
│ ├── E2E.Aot.Tests.csproj
│ └── MinikubeTests.cs
├── E2E.Tests
│ ├── E2E.Tests.csproj
│ ├── KubectlTests.cs
│ ├── MinikubeFactAttribute.cs
│ ├── MinikubeTests.cs
│ └── Onebyone.cs
├── Kubectl.Tests
│ ├── Kubectl.Tests.csproj
│ ├── KubectlTests.Version.cs
│ └── KubectlTests.cs
├── KubernetesClient.Classic.Tests
│ ├── KubernetesClient.Classic.Tests.csproj
│ └── SimpleTests.cs
├── KubernetesClient.Tests
│ ├── AssemblyInfo.cs
│ ├── AuthTests.cs
│ ├── ByteBufferTests.cs
│ ├── CertUtilsTests.cs
│ ├── CertificateValidationTests.cs
│ ├── ExternalExecutionTests.cs
│ ├── IntOrStringTests.cs
│ ├── ItemsEnumTests.cs
│ ├── KubernetesClient.Tests.csproj
│ ├── KubernetesClientConfigurationTests.cs
│ ├── KubernetesExecTests.cs
│ ├── KubernetesJsonTests.cs
│ ├── KubernetesMetricsTests.cs
│ ├── KubernetesYamlTests.cs
│ ├── LeaderElection
│ │ └── LeaderElectionTests.cs
│ ├── Logging
│ │ ├── TestOutputLogger.cs
│ │ ├── TestOutputLoggerProvider.cs
│ │ └── TestOutputLoggingExtensions.cs
│ ├── Mock
│ │ ├── MockKubeApiServer.cs
│ │ ├── MockWebSocket.cs
│ │ ├── MockWebSocketBuilder.cs
│ │ └── Server
│ │ │ ├── Controllers
│ │ │ ├── PodExecController.cs
│ │ │ └── PodPortForwardController.cs
│ │ │ ├── Startup.cs
│ │ │ └── WebSocketTestAdapter.cs
│ ├── ModelExtensionTests.cs
│ ├── OidcAuthTests.cs
│ ├── OperatingSystemDependentFactAttribute.cs
│ ├── OperatingSystems.cs
│ ├── PodExecTests.cs
│ ├── QuantityValueTests.cs
│ ├── SerializationTests.cs
│ ├── StreamDemuxerTests.cs
│ ├── TaskAssert.cs
│ ├── TokenFileAuthTests.cs
│ ├── UtilityTests.cs
│ ├── V1StatusObjectViewTests.cs
│ ├── WatchTests.cs
│ ├── WebSocketTestBase.cs
│ └── assets
│ │ ├── apiserver-pfx-data.txt
│ │ ├── ca-bundle-correct.crt
│ │ ├── ca-bundle-incorrect.crt
│ │ ├── ca-bundle-intermediate.crt
│ │ ├── ca-bundle-root.crt
│ │ ├── ca-bundle.crt
│ │ ├── ca-data.txt
│ │ ├── ca.crt
│ │ ├── ca2.crt
│ │ ├── ca3.crt
│ │ ├── client-certificate-data.txt
│ │ ├── client-key-data.txt
│ │ ├── client.crt
│ │ ├── client.key
│ │ ├── elliptic-client.key
│ │ ├── elliptic.crt
│ │ ├── gcloud-config-helper.json
│ │ ├── kubeconfig.additional-properties.yml
│ │ ├── kubeconfig.as-user-extra.yml
│ │ ├── kubeconfig.cluster-extensions.yml
│ │ ├── kubeconfig.cluster-missmatch.yml
│ │ ├── kubeconfig.no-cluster.yml
│ │ ├── kubeconfig.no-context-details.yml
│ │ ├── kubeconfig.no-context.yml
│ │ ├── kubeconfig.no-credentials.yml
│ │ ├── kubeconfig.no-current-context.yml
│ │ ├── kubeconfig.no-server.yml
│ │ ├── kubeconfig.no-user.yml
│ │ ├── kubeconfig.preferences-extensions.yml
│ │ ├── kubeconfig.relative.yml
│ │ ├── kubeconfig.tls-no-skip.yml
│ │ ├── kubeconfig.tls-servername.yml
│ │ ├── kubeconfig.tls-skip-http.yml
│ │ ├── kubeconfig.tls-skip.yml
│ │ ├── kubeconfig.user-not-found.yml
│ │ ├── kubeconfig.user-oidc.yml
│ │ ├── kubeconfig.user-pass.yml
│ │ ├── kubeconfig.wildcard-ipv4.yml
│ │ ├── kubeconfig.wildcard-ipv6.yml
│ │ ├── kubeconfig.wildcard-ipv6_2.yml
│ │ ├── kubeconfig.yml
│ │ ├── mock-gcloud.cmd
│ │ ├── mock-gcloud.sh
│ │ ├── token1
│ │ └── token2
└── SkipTestLogger
│ ├── SkipTestLogger.cs
│ └── SkipTestLogger.csproj
└── version.json
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | {
2 | "image": "mcr.microsoft.com/dotnet/sdk:8.0"
3 | }
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.doc diff=astextplain
2 | *.DOC diff=astextplain
3 | *.docx diff=astextplain
4 | *.DOCX diff=astextplain
5 | *.dot diff=astextplain
6 | *.DOT diff=astextplain
7 | *.pdf diff=astextplain
8 | *.PDF diff=astextplain
9 | *.rtf diff=astextplain
10 | *.RTF diff=astextplain
11 |
12 | *.jpg binary
13 | *.png binary
14 | *.gif binary
15 |
16 | *.cs text=auto diff=csharp
17 | *.vb text=auto
18 | *.resx text=auto
19 | *.c text=auto
20 | *.cpp text=auto
21 | *.cxx text=auto
22 | *.h text=auto
23 | *.hxx text=auto
24 | *.py text=auto
25 | *.rb text=auto
26 | *.java text=auto
27 | *.html text=auto
28 | *.htm text=auto
29 | *.css text=auto
30 | *.scss text=auto
31 | *.sass text=auto
32 | *.less text=auto
33 | *.js text=auto
34 | *.lisp text=auto
35 | *.clj text=auto
36 | *.sql text=auto
37 | *.php text=auto
38 | *.lua text=auto
39 | *.m text=auto
40 | *.asm text=auto
41 | *.erl text=auto
42 | *.fs text=auto
43 | *.fsx text=auto
44 | *.hs text=auto
45 |
46 | *.csproj text=auto
47 | *.vbproj text=auto
48 | *.fsproj text=auto
49 | *.dbproj text=auto
50 | *.sln text=auto eol=crlf
51 |
52 | src/KubernetesClient/generated/** linguist-generated
53 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **Kubernetes C# SDK Client Version**
14 | e.g. `9.0.1`
15 |
16 | **Server Kubernetes Version**
17 | e.g. `1.22.3`
18 |
19 | **Dotnet Runtime Version**
20 | e.g. net6
21 |
22 | **To Reproduce**
23 | Steps to reproduce the behavior:
24 |
25 | **Expected behavior**
26 | A clear and concise description of what you expected to happen.
27 |
28 | **KubeConfig**
29 | If applicable, add a KubeConfig file with secrets redacted.
30 |
31 | **Where do you run your app with Kubernetes SDK (please complete the following information):**
32 | - OS: [e.g. Linux]
33 | - Environment [e.g. container]
34 | - Cloud [e.g. Azure]
35 |
36 | **Additional context**
37 | Add any other context about the problem here.
38 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # To get started with Dependabot version updates, you'll need to specify which
2 | # package ecosystems to update and where the package manifests are located.
3 | # Please see the documentation for all configuration options:
4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
5 |
6 | version: 2
7 | updates:
8 |
9 | # Maintain dependencies for GitHub Actions
10 | - package-ecosystem: "github-actions"
11 | directory: "/"
12 | schedule:
13 | interval: "daily"
14 | # Allow up to 5 open pull requests for GitHub Actions dependencies
15 | open-pull-requests-limit: 5
16 | labels:
17 | - "dependencies"
18 | # Rebase open pull requests when changes are detected
19 | rebase-strategy: "auto"
20 |
21 | # Maintain dependencies for NuGet packages
22 | - package-ecosystem: "nuget"
23 | directory: "/"
24 | schedule:
25 | interval: "daily"
26 | # Allow up to 10 open pull requests for NuGet dependencies
27 | open-pull-requests-limit: 10
28 | labels:
29 | - "dependencies"
30 | # Rebase open pull requests when changes are detected
31 | rebase-strategy: "auto"
32 |
--------------------------------------------------------------------------------
/.github/workflows/docfx.yaml:
--------------------------------------------------------------------------------
1 | name: Docfx
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 |
7 | # Allows you to run this workflow manually from the Actions tab
8 | workflow_dispatch:
9 |
10 | # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
11 | permissions:
12 | contents: read
13 | pages: write
14 | id-token: write
15 |
16 | # Allow one concurrent deployment
17 | concurrency:
18 | group: "pages"
19 | cancel-in-progress: true
20 |
21 | jobs:
22 | docfx:
23 | runs-on: ubuntu-latest
24 | environment:
25 | name: github-pages
26 | url: ${{ steps.deployment.outputs.page_url }}
27 | steps:
28 | - uses: actions/checkout@v4
29 | with:
30 | fetch-depth: 0
31 |
32 | - name: Setup dotnet
33 | uses: actions/setup-dotnet@v4
34 | with:
35 | dotnet-version: |
36 | 8.0.x
37 | 9.0.x
38 |
39 | - name: Build
40 | run: dotnet build -c Release
41 |
42 | - uses: nunit/docfx-action@v4.1.0
43 | name: Build Documentation
44 | with:
45 | args: doc/docfx.json
46 |
47 | - name: Setup Pages
48 | uses: actions/configure-pages@v5
49 | - name: Upload artifact
50 | uses: actions/upload-pages-artifact@v3
51 | with:
52 | # Upload entire repository
53 | path: doc/_site
54 | - name: Deploy to GitHub Pages
55 | id: deployment
56 | uses: actions/deploy-pages@v4
57 |
--------------------------------------------------------------------------------
/.github/workflows/draft.yaml:
--------------------------------------------------------------------------------
1 | name: Draft Release
2 |
3 | permissions:
4 | contents: write
5 |
6 | on:
7 | push:
8 | branches: [ master ]
9 |
10 | jobs:
11 | draft:
12 |
13 | runs-on: windows-latest
14 |
15 | steps:
16 | - uses: actions/checkout@v4
17 | with:
18 | fetch-depth: 0
19 |
20 | - name: Setup dotnet
21 | uses: actions/setup-dotnet@v4
22 | with:
23 | dotnet-version: |
24 | 8.0.x
25 | 9.0.x
26 |
27 | - name: dotnet restore
28 | run: dotnet restore --verbosity minimal --configfile nuget.config
29 |
30 | - name: dotnet test
31 | run: dotnet test
32 |
33 | - uses: dotnet/nbgv@master
34 | with:
35 | setAllVars: true
36 |
37 | - name: create release
38 | shell: pwsh
39 | env:
40 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
41 | run: |
42 | gh release create -d --generate-notes v$env:NBGV_NuGetPackageVersion
43 |
--------------------------------------------------------------------------------
/.github/workflows/nuget.yaml:
--------------------------------------------------------------------------------
1 | name: Nuget
2 |
3 | on:
4 | release:
5 | types: [ released ]
6 |
7 | jobs:
8 | nuget:
9 |
10 | runs-on: windows-latest
11 |
12 | steps:
13 | - uses: actions/checkout@v4
14 | with:
15 | fetch-depth: 0
16 |
17 | - name: Setup dotnet
18 | uses: actions/setup-dotnet@v4
19 | with:
20 | dotnet-version: |
21 | 8.0.x
22 | 9.0.x
23 |
24 | - name: dotnet restore
25 | run: dotnet restore --verbosity minimal --configfile nuget.config
26 |
27 | - name: dotnet test
28 | run: dotnet test
29 |
30 | - name: dotnet pack
31 | run: dotnet pack -c Release src/nuget.proj -o pkg --include-symbols
32 |
33 | - name: dotnet nuget push
34 | run: |
35 | dotnet nuget push pkg\*.nupkg -s https://nuget.pkg.github.com/$env:GITHUB_REPOSITORY_OWNER -k ${{ secrets.GITHUB_TOKEN }} --skip-duplicate
36 | dotnet nuget push pkg\*.nupkg -s https://www.nuget.org/ -k ${{ secrets.nuget_api_key }} --skip-duplicate
37 |
38 |
39 | ## Remove old versions of NuGet packages form github NuGet feed
40 | nuget-delete-old-packages:
41 | name: "Delete Old NuGet"
42 | needs: [nuget]
43 | strategy:
44 | matrix:
45 | nuget-package:
46 | - "KubernetesClient"
47 | - "KubernetesClient.Classic"
48 | runs-on: ubuntu-latest
49 | permissions:
50 | packages: write
51 |
52 | steps:
53 | - name: Delete old NuGet packages
54 | uses: actions/delete-package-versions@v5
55 | with:
56 | owner: ${{ env.GITHUB_REPOSITORY_OWNER }}
57 | token: ${{ secrets.GITHUB_TOKEN }}
58 | package-name: ${{ matrix.nuget-package }}
59 | package-type: nuget
60 | min-versions-to-keep: 10
61 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .vscode
2 | .vs
3 | obj/
4 | bin/
5 | **/TestResults
6 |
7 | # User-specific VS files
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # JetBrains Rider
14 | .idea/
15 | *.sln.iml
16 |
17 | launchSettings.json
18 | *.DotSettings
19 |
20 | *.sln
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | Thanks for taking the time to join our community and start contributing!
4 |
5 | Please remember to read and observe the [Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).
6 |
7 | This project accepts contribution via github [pull requests](https://help.github.com/articles/about-pull-requests/). This document outlines the process to help get your contribution accepted. Please also read the [Kubernetes contributor guide](https://github.com/kubernetes/community/blob/master/contributors/guide/README.md) which provides detailed instructions on how to get your ideas and bug fixes seen and accepted.
8 |
9 | ## Sign the Contributor License Agreement
10 | We'd love to accept your patches! Before we can accept them you need to sign Cloud Native Computing Foundation (CNCF) [CLA](https://github.com/kubernetes/community/blob/master/CLA.md).
11 |
12 | ## Reporting an issue
13 | If you have any problem with the package or any suggestions, please file an [issue](https://github.com/kubernetes-client/csharp/issues).
14 |
15 | ## Contributing a Patch
16 | 1. Submit an issue describing your proposed change to the repo.
17 | 2. Fork this repo, develop and test your code changes.
18 | 3. Submit a pull request.
19 | 4. The bot will automatically assigns someone to review your PR. Check the full list of bot commands [here](https://prow.k8s.io/command-help).
20 |
21 | ### Contact
22 | You can reach the maintainers of this project at [SIG API Machinery](https://github.com/kubernetes/community/tree/master/sig-api-machinery) or on the [#kubernetes-client](https://kubernetes.slack.com/messages/kubernetes-client) channel on the Kubernetes slack.
23 |
--------------------------------------------------------------------------------
/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/OWNERS:
--------------------------------------------------------------------------------
1 | # See the OWNERS docs at https://go.k8s.io/owners
2 |
3 | approvers:
4 | - brendandburns
5 | - tg123
6 | reviewers:
7 | - brendandburns
8 | - tg123
9 | emeritus_approvers:
10 | - krabhishek8260 # 4/4/2022
11 |
--------------------------------------------------------------------------------
/SECURITY_CONTACTS:
--------------------------------------------------------------------------------
1 | # Defined below are the security contacts for this repo.
2 | #
3 | # They are the contact point for the Product Security Team to reach out
4 | # to for triaging and handling of incoming issues.
5 | #
6 | # The below names agree to abide by the
7 | # [Embargo Policy](https://github.com/kubernetes/sig-release/blob/master/security-release-process-documentation/security-release-process.md#embargo-policy)
8 | # and will be removed and replaced if they violate that agreement.
9 | #
10 | # DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE
11 | # INSTRUCTIONS AT https://kubernetes.io/security/
12 |
13 | brendandburns
14 |
--------------------------------------------------------------------------------
/code-of-conduct.md:
--------------------------------------------------------------------------------
1 | # Kubernetes Community Code of Conduct
2 |
3 | Please refer to our [Kubernetes Community Code of Conduct](https://git.k8s.io/community/code-of-conduct.md)
4 |
--------------------------------------------------------------------------------
/csharp.settings:
--------------------------------------------------------------------------------
1 | export KUBERNETES_BRANCH=v1.33.0
2 | export CLIENT_VERSION=0.0.1
3 | export PACKAGE_NAME=k8s
4 |
--------------------------------------------------------------------------------
/doc/.gitignore:
--------------------------------------------------------------------------------
1 | ###############
2 | # folder #
3 | ###############
4 | /**/DROP/
5 | /**/TEMP/
6 | /**/packages/
7 | /**/bin/
8 | /**/obj/
9 | _site
10 |
11 | api
--------------------------------------------------------------------------------
/doc/docfx.json:
--------------------------------------------------------------------------------
1 | {
2 | "metadata": [
3 | {
4 | "src": [
5 | {
6 | "files": [
7 | "KubernetesClient/KubernetesClient.csproj"
8 | ],
9 | "src": "../src"
10 | }
11 | ],
12 | "dest": "api",
13 | "disableGitFeatures": false,
14 | "disableDefaultFilter": false
15 | }
16 | ],
17 | "build": {
18 | "content": [
19 | {
20 | "files": [
21 | "api/**.yml",
22 | "index.md",
23 | "toc.yml"
24 | ]
25 | }
26 | ],
27 | "dest": "_site",
28 | "globalMetadataFiles": [],
29 | "fileMetadataFiles": [],
30 | "template": [
31 | "default"
32 | ],
33 | "postProcessors": [],
34 | "markdownEngineName": "markdig",
35 | "noLangKeyword": false,
36 | "keepFileLink": false,
37 | "cleanupCacheHistory": false,
38 | "disableGitFeatures": false
39 | }
40 | }
--------------------------------------------------------------------------------
/doc/index.md:
--------------------------------------------------------------------------------
1 | ../README.md
--------------------------------------------------------------------------------
/doc/toc.yml:
--------------------------------------------------------------------------------
1 | - name: API Documentation
2 | href: api/k8s.yml
3 |
--------------------------------------------------------------------------------
/examples/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | net9.0
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/examples/aks-kubelogin/Program.cs:
--------------------------------------------------------------------------------
1 | using k8s;
2 | using System;
3 | using System.IO;
4 | using System.Text;
5 |
6 | var server = "https://example.hcp.eastus.azmk8s.io"; // the server url of your aks
7 | var clientid = "00000000-0000-0000-0000-000000000000"; // the client id of the your msi
8 | var kubelogin = @"C:\bin\kubelogin.exe"; // the path to the kubelogin.exe
9 |
10 | using var configstream = new MemoryStream(Encoding.ASCII.GetBytes($"""
11 | apiVersion: v1
12 | clusters:
13 | - cluster:
14 | insecure-skip-tls-verify: true
15 | server: {server}
16 | name: aks
17 | contexts:
18 | - context:
19 | cluster: aks
20 | user: msi
21 | name: aks
22 | current-context: aks
23 | kind: Config
24 | users:
25 | - name: msi
26 | user:
27 | exec:
28 | apiVersion: client.authentication.k8s.io/v1beta1
29 | args:
30 | - get-token
31 | - --login
32 | - msi
33 | - --server-id
34 | - 6dae42f8-4368-4678-94ff-3960e28e3630
35 | - --client-id
36 | - {clientid}
37 | command: {kubelogin}
38 | env: null
39 | """));
40 |
41 | var config = KubernetesClientConfiguration.BuildConfigFromConfigFile(configstream);
42 | IKubernetes client = new Kubernetes(config);
43 | Console.WriteLine("Starting Request!");
44 |
45 | var list = client.CoreV1.ListNamespacedPod("default");
46 | foreach (var item in list.Items)
47 | {
48 | Console.WriteLine(item.Metadata.Name);
49 | }
50 |
--------------------------------------------------------------------------------
/examples/aks-kubelogin/README.md:
--------------------------------------------------------------------------------
1 | # AKS C# example using kubelogin + MSI
2 |
3 | This example shows how to use the [kubelogin](https://github.com/Azure/kubelogin) to authenticate using [managed identities](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/overview) with Azure Kubernetes Service (AKS) using the C# SDK.
4 |
5 |
6 | ## Prerequisites
7 |
8 | - turn on AAD support for AKS, see [here](https://docs.microsoft.com/en-us/azure/aks/managed-aad)
9 | - create a managed identity for the AKS cluster
10 | - assign the managed identity the `Azure Kubernetes Service RBAC Cluster Admin` (or other RBAC permission) on the AKS cluster
11 | - assign the managed identity to the VM, see [here](https://docs.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/qs-configure-portal-windows-vm)
12 | - install the [kubelogin](https://github.com/Azure/kubelogin) to your machine
13 |
14 | ## Running the code
15 |
16 | *You must the the code on VM with MSI*
17 |
18 | - Replace `server` with the address of your AKS cluster
19 | - Replace `clientid` with the client id of the managed identity
20 | - Replace `kubelogin` with the path to the kubelogin executable
21 |
22 | ```
23 | dotnet run
24 | ```
--------------------------------------------------------------------------------
/examples/aks-kubelogin/aks-kubelogin.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Exe
4 |
5 |
--------------------------------------------------------------------------------
/examples/aot/Program.cs:
--------------------------------------------------------------------------------
1 | using k8s;
2 |
3 | var config = KubernetesClientConfiguration.BuildDefaultConfig();
4 | IKubernetes client = new Kubernetes(config);
5 | Console.WriteLine("Starting Request!");
6 |
7 | var list = client.CoreV1.ListNamespacedPod("default");
8 | foreach (var item in list.Items)
9 | {
10 | Console.WriteLine(item.Metadata.Name);
11 | }
12 |
13 | if (list.Items.Count == 0)
14 | {
15 | Console.WriteLine("Empty!");
16 | }
--------------------------------------------------------------------------------
/examples/aot/aot.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Exe
4 | enable
5 | enable
6 | true
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/examples/attach/Attach.cs:
--------------------------------------------------------------------------------
1 | using k8s;
2 | using k8s.Models;
3 | using System;
4 | using System.Threading.Tasks;
5 |
6 | var config = KubernetesClientConfiguration.BuildConfigFromConfigFile();
7 | IKubernetes client = new Kubernetes(config);
8 | Console.WriteLine("Starting Request!");
9 |
10 | var list = client.CoreV1.ListNamespacedPod("default");
11 | var pod = list.Items[0];
12 | await AttachToPod(client, pod).ConfigureAwait(false);
13 |
14 | async Task AttachToPod(IKubernetes client, V1Pod pod)
15 | {
16 | var webSocket =
17 | await client.WebSocketNamespacedPodAttachAsync(pod.Metadata.Name, "default",
18 | pod.Spec.Containers[0].Name).ConfigureAwait(false);
19 |
20 | var demux = new StreamDemuxer(webSocket);
21 | demux.Start();
22 |
23 | var buff = new byte[4096];
24 | var stream = demux.GetStream(1, 1);
25 | while (true)
26 | {
27 | var read = stream.Read(buff, 0, 4096);
28 | var str = System.Text.Encoding.Default.GetString(buff);
29 | Console.WriteLine(str);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/examples/attach/attach.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/clientset/Program.cs:
--------------------------------------------------------------------------------
1 | // See https://aka.ms/new-console-template for more information
2 | using k8s;
3 | using k8s.ClientSets;
4 | using System.Threading.Tasks;
5 |
6 | namespace clientset
7 | {
8 | internal class Program
9 | {
10 | private static async Task Main(string[] args)
11 | {
12 | var config = KubernetesClientConfiguration.BuildConfigFromConfigFile();
13 | var client = new Kubernetes(config);
14 |
15 | ClientSet clientSet = new ClientSet(client);
16 | var list = await clientSet.CoreV1.Pod.ListAsync("default").ConfigureAwait(false);
17 | foreach (var item in list)
18 | {
19 | System.Console.WriteLine(item.Metadata.Name);
20 | }
21 |
22 | var pod = await clientSet.CoreV1.Pod.GetAsync("test","default").ConfigureAwait(false);
23 | System.Console.WriteLine(pod?.Metadata?.Name);
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/examples/clientset/clientset.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Exe
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/examples/cp/cp.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/examples/csrApproval/csrApproval.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | enable
6 | enable
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/customResource/CustomResourceDefinition.cs:
--------------------------------------------------------------------------------
1 | using k8s;
2 | using k8s.Models;
3 | using System.Collections.Generic;
4 | using System.Text.Json.Serialization;
5 |
6 | [module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "CA1724:TypeNamesShouldNotMatchNamespaces", Justification = "This is just an example.")]
7 | [module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass", Justification = "This is just an example.")]
8 |
9 | namespace customResource
10 | {
11 | public class CustomResourceDefinition
12 | {
13 | public string Version { get; set; }
14 |
15 | public string Group { get; set; }
16 |
17 | public string PluralName { get; set; }
18 |
19 | public string Kind { get; set; }
20 |
21 | public string Namespace { get; set; }
22 | }
23 |
24 | public abstract class CustomResource : KubernetesObject, IMetadata
25 | {
26 | [JsonPropertyName("metadata")]
27 | public V1ObjectMeta Metadata { get; set; }
28 | }
29 |
30 | public abstract class CustomResource : CustomResource
31 | {
32 | [JsonPropertyName("spec")]
33 | public TSpec Spec { get; set; }
34 |
35 | [JsonPropertyName("status")]
36 | public TStatus Status { get; set; }
37 | }
38 |
39 | public class CustomResourceList : KubernetesObject
40 | where T : CustomResource
41 | {
42 | public V1ListMeta Metadata { get; set; }
43 | public List Items { get; set; }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/examples/customResource/README.md:
--------------------------------------------------------------------------------
1 | # Custom Resource Client Example
2 |
3 | This example demonstrates how to use the C# Kubernetes Client library to create, get and list custom resources.
4 |
5 | ## Pre-requisits
6 |
7 | Make sure your have added the library package
8 |
9 | ```shell
10 | dotnet add package KubernetesClient
11 | ```
12 |
13 | ## Create Custom Resource Definition (CRD)
14 |
15 | Make sure the [CRD](./config/crd.yaml) is created, in order to create an instance of it after.
16 |
17 | ```shell
18 | kubectl create -f ./config/crd.yaml
19 | ```
20 |
21 | You can test that the CRD is successfully added, by creating an [instance](./config/yaml-cr-instance.yaml) of it using kubectl:
22 |
23 | ```shell
24 | kubectl create -f ./config/yaml-cr-instance.yaml
25 | ```
26 |
27 | ```shell
28 | kubectl get customresources.csharp.com
29 | ```
30 |
31 | ## Execute the code
32 |
33 | The client uses the `BuildConfigFromConfigFile()` function. If the KUBECONFIG environment variable is set, then that path to the k8s config file will be used.
34 |
35 | `dotnet run`
36 |
37 | Expected output:
38 |
39 | ```
40 | strating main()...
41 | working with CRD: customresources.csharp.com
42 | creating CR cr-instance-london
43 | CR list:
44 | - CR Item 0 = cr-instance-london
45 | - CR Item 1 = cr-instance-paris
46 | fetchedCR = cr-instance-london (Labels: {identifier : city, newKey : newValue}), Spec: London
47 | Deleted the CR
48 | ```
49 |
50 | ## Under the hood
51 |
52 | For more details, you can look at the Generic client [implementation](https://github.com/kubernetes-client/csharp/blob/master/src/KubernetesClient/GenericClient.cs)
53 |
54 |
--------------------------------------------------------------------------------
/examples/customResource/Utils.cs:
--------------------------------------------------------------------------------
1 | using k8s.Models;
2 | using System.Collections.Generic;
3 | namespace customResource
4 | {
5 | public class Utils
6 | {
7 | // creats a CRD definition
8 | public static CustomResourceDefinition MakeCRD()
9 | {
10 | var myCRD = new CustomResourceDefinition()
11 | {
12 | Kind = "CResource",
13 | Group = "csharp.com",
14 | Version = "v1alpha1",
15 | PluralName = "customresources",
16 | };
17 |
18 | return myCRD;
19 | }
20 |
21 | // creats a CR instance
22 | public static CResource MakeCResource()
23 | {
24 | var myCResource = new CResource()
25 | {
26 | Kind = "CResource",
27 | ApiVersion = "csharp.com/v1alpha1",
28 | Metadata = new V1ObjectMeta
29 | {
30 | Name = "cr-instance-london",
31 | NamespaceProperty = "default",
32 | Labels = new Dictionary
33 | {
34 | {
35 | "identifier", "city"
36 | },
37 | },
38 | },
39 | // spec
40 | Spec = new CResourceSpec
41 | {
42 | CityName = "London",
43 | },
44 | };
45 | return myCResource;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/examples/customResource/cResource.cs:
--------------------------------------------------------------------------------
1 | using k8s.Models;
2 | using System.Text.Json.Serialization;
3 |
4 | namespace customResource
5 | {
6 | public class CResource : CustomResource
7 | {
8 | public override string ToString()
9 | {
10 | var labels = "{";
11 | foreach (var kvp in Metadata.Labels)
12 | {
13 | labels += kvp.Key + " : " + kvp.Value + ", ";
14 | }
15 |
16 | labels = labels.TrimEnd(',', ' ') + "}";
17 |
18 | return $"{Metadata.Name} (Labels: {labels}), Spec: {Spec.CityName}";
19 | }
20 | }
21 |
22 | public class CResourceSpec
23 | {
24 | [JsonPropertyName("cityName")]
25 | public string CityName { get; set; }
26 | }
27 |
28 | public class CResourceStatus : V1Status
29 | {
30 | [JsonPropertyName("temperature")]
31 | public string Temperature { get; set; }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/examples/customResource/config/crd.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apiextensions.k8s.io/v1
2 | kind: CustomResourceDefinition
3 | metadata:
4 | name: customresources.csharp.com
5 | spec:
6 | group: csharp.com
7 | versions:
8 | - name: v1alpha1
9 | storage: true
10 | served: true
11 | schema:
12 | openAPIV3Schema:
13 | type: object
14 | properties:
15 | spec:
16 | type: object
17 | properties:
18 | cityName:
19 | type: string
20 | names:
21 | kind: CResource
22 | plural: customresources
23 | scope: Namespaced
24 |
--------------------------------------------------------------------------------
/examples/customResource/config/yaml-cr-instance.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: csharp.com/v1alpha1
2 | kind: CResource
3 | metadata:
4 | name: cr-instance-paris
5 | namespace: default
6 | spec:
7 | cityName: Paris
8 |
--------------------------------------------------------------------------------
/examples/customResource/customResource.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/examples/exec/Exec.cs:
--------------------------------------------------------------------------------
1 | using k8s;
2 | using k8s.Models;
3 | using System;
4 | using System.Threading.Tasks;
5 |
6 | var config = KubernetesClientConfiguration.BuildConfigFromConfigFile();
7 | IKubernetes client = new Kubernetes(config);
8 | Console.WriteLine("Starting Request!");
9 |
10 | var list = client.CoreV1.ListNamespacedPod("default");
11 | var pod = list.Items[0];
12 | await ExecInPod(client, pod).ConfigureAwait(false);
13 |
14 | async Task ExecInPod(IKubernetes client, V1Pod pod)
15 | {
16 | var webSocket =
17 | await client.WebSocketNamespacedPodExecAsync(pod.Metadata.Name, "default", "ls",
18 | pod.Spec.Containers[0].Name).ConfigureAwait(false);
19 |
20 | var demux = new StreamDemuxer(webSocket);
21 | demux.Start();
22 |
23 | var buff = new byte[4096];
24 | var stream = demux.GetStream(1, 1);
25 | var read = stream.Read(buff, 0, 4096);
26 | var str = System.Text.Encoding.Default.GetString(buff);
27 | Console.WriteLine(str);
28 | }
29 |
--------------------------------------------------------------------------------
/examples/exec/exec.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/generic/Generic.cs:
--------------------------------------------------------------------------------
1 | using k8s;
2 | using k8s.Models;
3 | using System;
4 |
5 | var config = KubernetesClientConfiguration.BuildConfigFromConfigFile();
6 | IKubernetes client = new Kubernetes(config);
7 | var generic = new GenericClient(client, "", "v1", "nodes");
8 | var node = await generic.ReadAsync("kube0").ConfigureAwait(false);
9 | Console.WriteLine(node.Metadata.Name);
10 |
11 | var genericPods = new GenericClient(client, "", "v1", "pods");
12 | var pods = await genericPods.ListNamespacedAsync("default").ConfigureAwait(false);
13 | foreach (var pod in pods.Items)
14 | {
15 | Console.WriteLine(pod.Metadata.Name);
16 | }
17 |
--------------------------------------------------------------------------------
/examples/generic/generic.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/labels/PodList.cs:
--------------------------------------------------------------------------------
1 | using k8s;
2 | using System;
3 | using System.Collections.Generic;
4 |
5 | var config = KubernetesClientConfiguration.BuildConfigFromConfigFile();
6 | IKubernetes client = new Kubernetes(config);
7 | Console.WriteLine("Starting Request!");
8 |
9 | var list = client.CoreV1.ListNamespacedService("default");
10 | foreach (var item in list.Items)
11 | {
12 | Console.WriteLine("Pods for service: " + item.Metadata.Name);
13 | Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=");
14 | if (item.Spec == null || item.Spec.Selector == null)
15 | {
16 | continue;
17 | }
18 |
19 | var labels = new List();
20 | foreach (var key in item.Spec.Selector)
21 | {
22 | labels.Add(key.Key + "=" + key.Value);
23 | }
24 |
25 | var labelStr = string.Join(",", labels.ToArray());
26 | Console.WriteLine(labelStr);
27 | var podList = client.CoreV1.ListNamespacedPod("default", labelSelector: labelStr);
28 | foreach (var pod in podList.Items)
29 | {
30 | Console.WriteLine(pod.Metadata.Name);
31 | }
32 |
33 | if (podList.Items.Count == 0)
34 | {
35 | Console.WriteLine("Empty!");
36 | }
37 |
38 | Console.WriteLine();
39 | }
40 |
--------------------------------------------------------------------------------
/examples/labels/labels.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/logs/Logs.cs:
--------------------------------------------------------------------------------
1 | using k8s;
2 | using System;
3 |
4 | var config = KubernetesClientConfiguration.BuildConfigFromConfigFile();
5 | IKubernetes client = new Kubernetes(config);
6 | Console.WriteLine("Starting Request!");
7 |
8 | var list = client.CoreV1.ListNamespacedPod("default");
9 | if (list.Items.Count == 0)
10 | {
11 | Console.WriteLine("No pods!");
12 | return;
13 | }
14 |
15 | var pod = list.Items[0];
16 |
17 | var response = await client.CoreV1.ReadNamespacedPodLogWithHttpMessagesAsync(
18 | pod.Metadata.Name,
19 | pod.Metadata.NamespaceProperty, container: pod.Spec.Containers[0].Name, follow: true).ConfigureAwait(false);
20 | var stream = response.Body;
21 | stream.CopyTo(Console.OpenStandardOutput());
22 |
--------------------------------------------------------------------------------
/examples/logs/logs.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/metrics/Program.cs:
--------------------------------------------------------------------------------
1 | using k8s;
2 | using System;
3 | using System.Linq;
4 | using System.Threading.Tasks;
5 |
6 | async Task NodesMetrics(IKubernetes client)
7 | {
8 | var nodesMetrics = await client.GetKubernetesNodesMetricsAsync().ConfigureAwait(false);
9 |
10 | foreach (var item in nodesMetrics.Items)
11 | {
12 | Console.WriteLine(item.Metadata.Name);
13 |
14 | foreach (var metric in item.Usage)
15 | {
16 | Console.WriteLine($"{metric.Key}: {metric.Value}");
17 | }
18 | }
19 | }
20 |
21 | async Task PodsMetrics(IKubernetes client)
22 | {
23 | var podsMetrics = await client.GetKubernetesPodsMetricsAsync().ConfigureAwait(false);
24 |
25 | if (!podsMetrics.Items.Any())
26 | {
27 | Console.WriteLine("Empty");
28 | }
29 |
30 | foreach (var item in podsMetrics.Items)
31 | {
32 | foreach (var container in item.Containers)
33 | {
34 | Console.WriteLine(container.Name);
35 |
36 | foreach (var metric in container.Usage)
37 | {
38 | Console.WriteLine($"{metric.Key}: {metric.Value}");
39 | }
40 | }
41 |
42 | Console.Write(Environment.NewLine);
43 | }
44 | }
45 |
46 | var config = KubernetesClientConfiguration.BuildConfigFromConfigFile();
47 | var client = new Kubernetes(config);
48 |
49 | await NodesMetrics(client).ConfigureAwait(false);
50 | Console.WriteLine(Environment.NewLine);
51 | await PodsMetrics(client).ConfigureAwait(false);
52 |
--------------------------------------------------------------------------------
/examples/metrics/metrics.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/namespace/namespace.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/openTelemetryConsole/Program.cs:
--------------------------------------------------------------------------------
1 | using k8s;
2 | using OpenTelemetry;
3 | using OpenTelemetry.Resources;
4 | using OpenTelemetry.Trace;
5 |
6 | var serviceName = "MyCompany.MyProduct.MyService";
7 | var serviceVersion = "1.0.0";
8 |
9 | // Create the OpenTelemetry TraceProvide with HttpClient instrumentation enabled
10 | // NOTE: for this example telemetry will be exported to console
11 | using var tracerProvider = Sdk.CreateTracerProviderBuilder()
12 | .AddSource(serviceName)
13 | .SetResourceBuilder(ResourceBuilder.CreateDefault().AddService(serviceName: serviceName, serviceVersion: serviceVersion))
14 | .AddHttpClientInstrumentation()
15 | .AddConsoleExporter()
16 | .Build();
17 |
18 | // Load kubernetes configuration
19 | var config = KubernetesClientConfiguration.BuildDefaultConfig();
20 |
21 | // Create an istance of Kubernetes client
22 | IKubernetes client = new Kubernetes(config);
23 |
24 | // Read the list of pods contained in default namespace
25 | var list = client.CoreV1.ListNamespacedPod("default");
26 |
27 | // Print the name of pods
28 | foreach (var item in list.Items)
29 | {
30 | Console.WriteLine(item.Metadata.Name);
31 | }
32 |
33 | // Or empty if there are no pods
34 | if (list.Items.Count == 0)
35 | {
36 | Console.WriteLine("Empty!");
37 | }
38 |
--------------------------------------------------------------------------------
/examples/openTelemetryConsole/openTelemetryConsole.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | enable
6 | enable
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/examples/patch-aot/Program.cs:
--------------------------------------------------------------------------------
1 | using k8s;
2 | using k8s.Models;
3 |
4 | var config = KubernetesClientConfiguration.BuildConfigFromConfigFile();
5 | IKubernetes client = new Kubernetes(config);
6 | Console.WriteLine("Starting Request!");
7 |
8 | var pod = client.CoreV1.ListNamespacedPod("default").Items.First();
9 | var name = pod.Metadata.Name;
10 | PrintLabels(pod);
11 |
12 | var patchStr = @"
13 | {
14 | ""metadata"": {
15 | ""labels"": {
16 | ""test"": ""test""
17 | }
18 | }
19 | }";
20 |
21 | client.CoreV1.PatchNamespacedPod(new V1Patch(patchStr, V1Patch.PatchType.MergePatch), name, "default");
22 | PrintLabels(client.CoreV1.ReadNamespacedPod(name, "default"));
23 |
24 | static void PrintLabels(V1Pod pod)
25 | {
26 | Console.WriteLine($"Labels: for {pod.Metadata.Name}");
27 | foreach (var (k, v) in pod.Metadata.Labels)
28 | {
29 | Console.WriteLine($"{k} : {v}");
30 | }
31 |
32 | Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=");
33 | }
34 |
--------------------------------------------------------------------------------
/examples/patch-aot/patch-aot.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Exe
4 | enable
5 | enable
6 | true
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/examples/patch/Program.cs:
--------------------------------------------------------------------------------
1 | using k8s;
2 | using k8s.Models;
3 | using System;
4 | using System.Linq;
5 |
6 | var config = KubernetesClientConfiguration.BuildConfigFromConfigFile();
7 | IKubernetes client = new Kubernetes(config);
8 | Console.WriteLine("Starting Request!");
9 |
10 | var pod = client.CoreV1.ListNamespacedPod("default").Items.First();
11 | var name = pod.Metadata.Name;
12 | PrintLabels(pod);
13 |
14 | var patchStr = @"
15 | {
16 | ""metadata"": {
17 | ""labels"": {
18 | ""test"": ""test""
19 | }
20 | }
21 | }";
22 |
23 | client.CoreV1.PatchNamespacedPod(new V1Patch(patchStr, V1Patch.PatchType.MergePatch), name, "default");
24 | PrintLabels(client.CoreV1.ReadNamespacedPod(name, "default"));
25 |
26 | void PrintLabels(V1Pod pod)
27 | {
28 | Console.WriteLine($"Labels: for {pod.Metadata.Name}");
29 | foreach (var (k, v) in pod.Metadata.Labels)
30 | {
31 | Console.WriteLine($"{k} : {v}");
32 | }
33 |
34 | Console.WriteLine("=-=-=-=-=-=-=-=-=-=-=");
35 | }
36 |
--------------------------------------------------------------------------------
/examples/patch/patch.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/portforward/portforward.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 |
6 |
7 |
--------------------------------------------------------------------------------
/examples/restart/restart.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 | enable
6 | enable
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/simple/PodList.cs:
--------------------------------------------------------------------------------
1 | using k8s;
2 | using System;
3 |
4 | var config = KubernetesClientConfiguration.BuildDefaultConfig();
5 | IKubernetes client = new Kubernetes(config);
6 | Console.WriteLine("Starting Request!");
7 |
8 | var list = client.CoreV1.ListNamespacedPod("default");
9 | foreach (var item in list.Items)
10 | {
11 | Console.WriteLine(item.Metadata.Name);
12 | }
13 |
14 | if (list.Items.Count == 0)
15 | {
16 | Console.WriteLine("Empty!");
17 | }
18 |
--------------------------------------------------------------------------------
/examples/simple/simple.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/watch/Program.cs:
--------------------------------------------------------------------------------
1 | using k8s;
2 | using k8s.Models;
3 | using System;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 |
7 | var config = KubernetesClientConfiguration.BuildConfigFromConfigFile();
8 |
9 | IKubernetes client = new Kubernetes(config);
10 |
11 | var podlistResp = client.CoreV1.ListNamespacedPodWithHttpMessagesAsync("default", watch: true);
12 | // C# 8 required https://docs.microsoft.com/en-us/archive/msdn-magazine/2019/november/csharp-iterating-with-async-enumerables-in-csharp-8
13 | await foreach (var (type, item) in podlistResp.WatchAsync().ConfigureAwait(false))
14 | {
15 | Console.WriteLine("==on watch event==");
16 | Console.WriteLine(type);
17 | Console.WriteLine(item.Metadata.Name);
18 | Console.WriteLine("==on watch event==");
19 | }
20 |
21 | #pragma warning disable CS8321 // Remove unused private members
22 | void WatchUsingCallback(IKubernetes client)
23 | #pragma warning restore CS8321 // Remove unused private members
24 | {
25 | var podlistResp = client.CoreV1.ListNamespacedPodWithHttpMessagesAsync("default", watch: true);
26 | using (podlistResp.Watch((type, item) =>
27 | {
28 | Console.WriteLine("==on watch event==");
29 | Console.WriteLine(type);
30 | Console.WriteLine(item.Metadata.Name);
31 | Console.WriteLine("==on watch event==");
32 | }))
33 | {
34 | Console.WriteLine("press ctrl + c to stop watching");
35 |
36 | var ctrlc = new ManualResetEventSlim(false);
37 | Console.CancelKeyPress += (sender, eventArgs) => ctrlc.Set();
38 | ctrlc.Wait();
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/examples/watch/watch.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Exe
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/examples/webApiDependencyInjection/Controllers/ExampleDependencyInjectionOnConstructorController.cs:
--------------------------------------------------------------------------------
1 | using k8s;
2 | using Microsoft.AspNetCore.Mvc;
3 |
4 | namespace webApiDependencyInjection.Controllers
5 | {
6 | [ApiController]
7 | [Route("[controller]")]
8 | public class ExampleDependencyInjectionOnConstructorController : ControllerBase
9 | {
10 | private readonly IKubernetes kubernetesClient;
11 |
12 | ///
13 | /// Initializes a new instance of the class.
14 | /// Injects the Kubernetes client into the controller.
15 | ///
16 | /// The Kubernetes client to interact with the Kubernetes API.
17 | public ExampleDependencyInjectionOnConstructorController(IKubernetes kubernetesClient)
18 | {
19 | this.kubernetesClient = kubernetesClient;
20 | }
21 |
22 | ///
23 | /// Retrieves the names of all pods in the default namespace using the injected Kubernetes client.
24 | ///
25 | /// A collection of pod names in the default namespace.
26 | [HttpGet]
27 | public IEnumerable GetPods()
28 | {
29 | // Read the list of pods contained in the default namespace
30 | var podList = this.kubernetesClient.CoreV1.ListNamespacedPod("default");
31 |
32 | // Return names of pods
33 | return podList.Items.Select(pod => pod.Metadata.Name);
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/examples/webApiDependencyInjection/Controllers/ExampleDependencyInjectionOnMethodController.cs:
--------------------------------------------------------------------------------
1 | using k8s;
2 | using Microsoft.AspNetCore.Mvc;
3 |
4 | namespace webApiDependencyInjection.Controllers
5 | {
6 | [ApiController]
7 | [Route("[controller]")]
8 | public class ExampleDependencyInjectionOnMethodController : ControllerBase
9 | {
10 | ///
11 | /// Example using the kubernetes client injected directly into the method ([FromServices] IKubernetes kubernetesClient).
12 | ///
13 | /// The Kubernetes client instance injected via dependency injection.
14 | /// A collection of pod names in the default namespace.
15 | [HttpGet]
16 | public IEnumerable GetPods([FromServices] IKubernetes kubernetesClient)
17 | {
18 | ArgumentNullException.ThrowIfNull(kubernetesClient);
19 |
20 | // Read the list of pods contained in default namespace
21 | var podList = kubernetesClient.CoreV1.ListNamespacedPod("default");
22 |
23 | // Return names of pods
24 | return podList.Items.Select(pod => pod.Metadata.Name);
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/examples/webApiDependencyInjection/Program.cs:
--------------------------------------------------------------------------------
1 | using k8s;
2 |
3 | var builder = WebApplication.CreateBuilder(args);
4 |
5 | // Load kubernetes configuration
6 | var kubernetesClientConfig = KubernetesClientConfiguration.BuildDefaultConfig();
7 |
8 | // Register Kubernetes client interface as sigleton
9 | builder.Services.AddSingleton(_ => new Kubernetes(kubernetesClientConfig));
10 |
11 | // Add services to the container.
12 | builder.Services.AddEndpointsApiExplorer();
13 | builder.Services.AddSwaggerGen();
14 |
15 | builder.Services.AddControllers();
16 |
17 | var app = builder.Build();
18 |
19 | // Configure the HTTP request pipeline.
20 | if (app.Environment.IsDevelopment())
21 | {
22 | app.UseSwagger();
23 | app.UseSwaggerUI();
24 | }
25 |
26 | app.UseAuthorization();
27 |
28 | app.MapControllers();
29 |
30 | // Start the service
31 | app.Run();
32 |
33 |
34 | // Swagger ui can be accesse at: http://localhost:/swagger
35 |
--------------------------------------------------------------------------------
/examples/webApiDependencyInjection/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.AspNetCore": "Warning"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/examples/webApiDependencyInjection/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.AspNetCore": "Warning"
6 | }
7 | },
8 | "AllowedHosts": "*"
9 | }
10 |
--------------------------------------------------------------------------------
/examples/webApiDependencyInjection/webApiDependencyInjection.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | enable
5 | enable
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/examples/workerServiceDependencyInjection/Program.cs:
--------------------------------------------------------------------------------
1 | using k8s;
2 | using workerServiceDependencyInjection;
3 |
4 | IHost host = Host.CreateDefaultBuilder(args)
5 | .ConfigureServices(services =>
6 | {
7 | // Load kubernetes configuration
8 | var kubernetesClientConfig = KubernetesClientConfiguration.BuildDefaultConfig();
9 |
10 | // Register Kubernetes client interface as sigleton
11 | services.AddSingleton(_ => new Kubernetes(kubernetesClientConfig));
12 |
13 | services.AddHostedService();
14 | })
15 | .Build();
16 |
17 | await host.RunAsync().ConfigureAwait(false);
18 |
--------------------------------------------------------------------------------
/examples/workerServiceDependencyInjection/Worker.cs:
--------------------------------------------------------------------------------
1 | using k8s;
2 |
3 | namespace workerServiceDependencyInjection
4 | {
5 | public class Worker : BackgroundService
6 | {
7 | private readonly ILogger logger;
8 | private readonly IKubernetes kubernetesClient;
9 |
10 | ///
11 | /// Initializes a new instance of the class.
12 | /// Inject in the constructor the IKubernetes interface.
13 | ///
14 | /// The logger instance used for logging information.
15 | /// The Kubernetes client used to interact with the Kubernetes API.
16 | public Worker(ILogger logger, IKubernetes kubernetesClient)
17 | {
18 | this.logger = logger;
19 | this.kubernetesClient = kubernetesClient;
20 | }
21 |
22 | protected override async Task ExecuteAsync(CancellationToken stoppingToken)
23 | {
24 | while (!stoppingToken.IsCancellationRequested)
25 | {
26 | logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
27 |
28 | // Read the list of pods contained in default namespace
29 | var podList = kubernetesClient.CoreV1.ListNamespacedPod("default");
30 |
31 | // Print pods names
32 | foreach (var pod in podList.Items)
33 | {
34 | Console.WriteLine(pod.Metadata.Name);
35 | }
36 |
37 | await Task.Delay(1000, stoppingToken).ConfigureAwait(false);
38 | }
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/examples/workerServiceDependencyInjection/appsettings.Development.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.Hosting.Lifetime": "Information"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/examples/workerServiceDependencyInjection/appsettings.json:
--------------------------------------------------------------------------------
1 | {
2 | "Logging": {
3 | "LogLevel": {
4 | "Default": "Information",
5 | "Microsoft.Hosting.Lifetime": "Information"
6 | }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/examples/workerServiceDependencyInjection/workerServiceDependencyInjection.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | enable
5 | enable
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/examples/yaml/Program.cs:
--------------------------------------------------------------------------------
1 | using k8s;
2 | using k8s.Models;
3 | using System;
4 | using System.Collections.Generic;
5 |
6 | var typeMap = new Dictionary
7 | {
8 | { "v1/Pod", typeof(V1Pod) },
9 | { "v1/Service", typeof(V1Service) },
10 | { "apps/v1/Deployment", typeof(V1Deployment) },
11 | };
12 |
13 | var objects = await KubernetesYaml.LoadAllFromFileAsync(args[0], typeMap).ConfigureAwait(false);
14 |
15 | foreach (var obj in objects)
16 | {
17 | Console.WriteLine(obj);
18 | }
19 |
--------------------------------------------------------------------------------
/examples/yaml/yaml.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | Exe
4 |
5 |
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "8.0.100",
4 | "rollForward": "latestMajor"
5 | },
6 | "msbuild-sdks": {
7 | "Microsoft.Build.Traversal": "4.1.0"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/kubernetes-client.proj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kubernetes-client/csharp/8d0547bcff45b589aeecf4590683986c8581dbbb/logo.png
--------------------------------------------------------------------------------
/nuget.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/KubernetesClient.Aot/Global.cs:
--------------------------------------------------------------------------------
1 | global using k8s.Autorest;
2 | global using k8s.Models;
3 | global using System;
4 | global using System.Collections.Generic;
5 | global using System.IO;
6 | global using System.Linq;
7 | global using System.Text.Json;
8 | global using System.Text.Json.Serialization;
9 | global using System.Threading;
10 | global using System.Threading.Tasks;
11 |
--------------------------------------------------------------------------------
/src/KubernetesClient.Aot/KubeConfigModels/AuthProvider.cs:
--------------------------------------------------------------------------------
1 | using YamlDotNet.Serialization;
2 |
3 | namespace k8s.KubeConfigModels
4 | {
5 | ///
6 | /// Contains information that describes identity information. This is use to tell the kubernetes cluster who you are.
7 | ///
8 | [YamlSerializable]
9 | public class AuthProvider
10 | {
11 | ///
12 | /// Gets or sets the nickname for this auth provider.
13 | ///
14 | [YamlMember(Alias = "name")]
15 | public string Name { get; set; }
16 |
17 | ///
18 | /// Gets or sets the configuration for this auth provider
19 | ///
20 | [YamlMember(Alias = "config")]
21 | public Dictionary Config { get; set; }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/KubernetesClient.Aot/KubeConfigModels/Cluster.cs:
--------------------------------------------------------------------------------
1 | using YamlDotNet.Serialization;
2 |
3 | namespace k8s.KubeConfigModels
4 | {
5 | ///
6 | /// Relates nicknames to cluster information.
7 | ///
8 | [YamlSerializable]
9 | public class Cluster
10 | {
11 | ///
12 | /// Gets or sets the cluster information.
13 | ///
14 | [YamlMember(Alias = "cluster")]
15 | public ClusterEndpoint ClusterEndpoint { get; set; }
16 |
17 | ///
18 | /// Gets or sets the nickname for this Cluster.
19 | ///
20 | [YamlMember(Alias = "name")]
21 | public string Name { get; set; }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/KubernetesClient.Aot/KubeConfigModels/ClusterEndpoint.cs:
--------------------------------------------------------------------------------
1 | using YamlDotNet.Serialization;
2 |
3 | namespace k8s.KubeConfigModels
4 | {
5 | ///
6 | /// Contains information about how to communicate with a kubernetes cluster
7 | ///
8 | [YamlSerializable]
9 | public class ClusterEndpoint
10 | {
11 | ///
12 | /// Gets or sets the path to a cert file for the certificate authority.
13 | ///
14 | [YamlMember(Alias = "certificate-authority", ApplyNamingConventions = false)]
15 | public string CertificateAuthority { get; set; }
16 |
17 | ///
18 | /// Gets or sets =PEM-encoded certificate authority certificates. Overrides .
19 | ///
20 | [YamlMember(Alias = "certificate-authority-data", ApplyNamingConventions = false)]
21 | public string CertificateAuthorityData { get; set; }
22 |
23 | ///
24 | /// Gets or sets the address of the kubernetes cluster (https://hostname:port).
25 | ///
26 | [YamlMember(Alias = "server")]
27 | public string Server { get; set; }
28 |
29 | ///
30 | /// Gets or sets a value to override the TLS server name.
31 | ///
32 | [YamlMember(Alias = "tls-server-name", ApplyNamingConventions = false)]
33 | public string TlsServerName { get; set; }
34 |
35 | ///
36 | /// Gets or sets a value indicating whether to skip the validity check for the server's certificate.
37 | /// This will make your HTTPS connections insecure.
38 | ///
39 | [YamlMember(Alias = "insecure-skip-tls-verify", ApplyNamingConventions = false)]
40 | public bool SkipTlsVerify { get; set; }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/KubernetesClient.Aot/KubeConfigModels/Context.cs:
--------------------------------------------------------------------------------
1 | using YamlDotNet.Serialization;
2 |
3 | namespace k8s.KubeConfigModels
4 | {
5 | ///
6 | /// Relates nicknames to context information.
7 | ///
8 | [YamlSerializable]
9 | public class Context
10 | {
11 | ///
12 | /// Gets or sets the context information.
13 | ///
14 | [YamlMember(Alias = "context")]
15 | public ContextDetails ContextDetails { get; set; }
16 |
17 | ///
18 | /// Gets or sets the nickname for this context.
19 | ///
20 | [YamlMember(Alias = "name")]
21 | public string Name { get; set; }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/KubernetesClient.Aot/KubeConfigModels/ContextDetails.cs:
--------------------------------------------------------------------------------
1 | using YamlDotNet.Serialization;
2 |
3 | namespace k8s.KubeConfigModels
4 | {
5 | ///
6 | /// Represents a tuple of references to a cluster (how do I communicate with a kubernetes cluster),
7 | /// a user (how do I identify myself), and a namespace (what subset of resources do I want to work with)
8 | ///
9 | [YamlSerializable]
10 | public class ContextDetails
11 | {
12 | ///
13 | /// Gets or sets the name of the cluster for this context.
14 | ///
15 | [YamlMember(Alias = "cluster")]
16 | public string Cluster { get; set; }
17 |
18 | ///
19 | /// Gets or sets the name of the user for this context.
20 | ///
21 | [YamlMember(Alias = "user")]
22 | public string User { get; set; }
23 |
24 | ///
25 | /// /Gets or sets the default namespace to use on unspecified requests.
26 | ///
27 | [YamlMember(Alias = "namespace")]
28 | public string Namespace { get; set; }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/KubernetesClient.Aot/KubeConfigModels/ExecCredentialResponse.cs:
--------------------------------------------------------------------------------
1 | using YamlDotNet.Serialization;
2 |
3 | namespace k8s.KubeConfigModels
4 | {
5 | [YamlSerializable]
6 | public class ExecCredentialResponse
7 | {
8 | public class ExecStatus
9 | {
10 | #nullable enable
11 | public DateTime? ExpirationTimestamp { get; set; }
12 | public string? Token { get; set; }
13 | public string? ClientCertificateData { get; set; }
14 | public string? ClientKeyData { get; set; }
15 | #nullable disable
16 |
17 | public bool IsValid()
18 | {
19 | return !string.IsNullOrEmpty(Token) ||
20 | (!string.IsNullOrEmpty(ClientCertificateData) && !string.IsNullOrEmpty(ClientKeyData));
21 | }
22 | }
23 |
24 | [JsonPropertyName("apiVersion")]
25 | public string ApiVersion { get; set; }
26 | [JsonPropertyName("kind")]
27 | public string Kind { get; set; }
28 | [JsonPropertyName("status")]
29 | public ExecStatus Status { get; set; }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/KubernetesClient.Aot/KubeConfigModels/ExternalExecution.cs:
--------------------------------------------------------------------------------
1 | using YamlDotNet.Serialization;
2 |
3 | namespace k8s.KubeConfigModels
4 | {
5 | [YamlSerializable]
6 | public class ExternalExecution
7 | {
8 | [YamlMember(Alias = "apiVersion")]
9 | public string ApiVersion { get; set; }
10 |
11 | ///
12 | /// The command to execute. Required.
13 | ///
14 | [YamlMember(Alias = "command")]
15 | public string Command { get; set; }
16 |
17 | ///
18 | /// Environment variables to set when executing the plugin. Optional.
19 | ///
20 | [YamlMember(Alias = "env")]
21 | public IList> EnvironmentVariables { get; set; }
22 |
23 | ///
24 | /// Arguments to pass when executing the plugin. Optional.
25 | ///
26 | [YamlMember(Alias = "args")]
27 | public IList Arguments { get; set; }
28 |
29 | ///
30 | /// Text shown to the user when the executable doesn't seem to be present. Optional.
31 | ///
32 | [YamlMember(Alias = "installHint")]
33 | public string InstallHint { get; set; }
34 |
35 | ///
36 | /// Whether or not to provide cluster information to this exec plugin as a part of
37 | /// the KUBERNETES_EXEC_INFO environment variable. Optional.
38 | ///
39 | [YamlMember(Alias = "provideClusterInfo")]
40 | public bool ProvideClusterInfo { get; set; }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/KubernetesClient.Aot/KubeConfigModels/StaticContext.cs:
--------------------------------------------------------------------------------
1 | using YamlDotNet.Serialization;
2 |
3 | namespace k8s.KubeConfigModels;
4 |
5 | [YamlStaticContext]
6 | public partial class StaticContext : YamlDotNet.Serialization.StaticContext
7 | {
8 | }
--------------------------------------------------------------------------------
/src/KubernetesClient.Aot/KubeConfigModels/User.cs:
--------------------------------------------------------------------------------
1 | using YamlDotNet.Serialization;
2 |
3 | namespace k8s.KubeConfigModels
4 | {
5 | ///
6 | /// Relates nicknames to auth information.
7 | ///
8 | [YamlSerializable]
9 | public class User
10 | {
11 | ///
12 | /// Gets or sets the auth information.
13 | ///
14 | [YamlMember(Alias = "user")]
15 | public UserCredentials UserCredentials { get; set; }
16 |
17 | ///
18 | /// Gets or sets the nickname for this auth information.
19 | ///
20 | [YamlMember(Alias = "name")]
21 | public string Name { get; set; }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/KubernetesClient.Aot/SourceGenerationContext.cs:
--------------------------------------------------------------------------------
1 | using static k8s.KubernetesJson;
2 |
3 | namespace k8s;
4 |
5 | [JsonSourceGenerationOptions(
6 | DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
7 | PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase,
8 | Converters = new[] { typeof(Iso8601TimeSpanConverter), typeof(KubernetesDateTimeConverter), typeof(KubernetesDateTimeOffsetConverter) })
9 | ]
10 | internal partial class SourceGenerationContext : JsonSerializerContext
11 | {
12 | }
13 |
--------------------------------------------------------------------------------
/src/KubernetesClient.Aot/V1PatchJsonConverter.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.Models
2 | {
3 | #pragma warning disable CA1812 // Avoid uninstantiated internal classes
4 | internal sealed class V1PatchJsonConverter : JsonConverter
5 | #pragma warning restore CA1812 // Avoid uninstantiated internal classes
6 | {
7 | public override V1Patch Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
8 | {
9 | throw new NotImplementedException();
10 | }
11 |
12 | public override void Write(Utf8JsonWriter writer, V1Patch value, JsonSerializerOptions options)
13 | {
14 | if (writer == null)
15 | {
16 | throw new ArgumentNullException(nameof(writer));
17 | }
18 |
19 | var content = value?.Content;
20 | if (content is string s)
21 | {
22 | writer.WriteRawValue(s);
23 | return;
24 | }
25 |
26 | throw new NotSupportedException("only string json patch is supported");
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/KubernetesClient.Classic/Global.cs:
--------------------------------------------------------------------------------
1 | global using k8s.Autorest;
2 | global using k8s.Models;
3 | global using System;
4 | global using System.Collections.Generic;
5 | global using System.IO;
6 | global using System.Linq;
7 | global using System.Text.Json;
8 | global using System.Text.Json.Serialization;
9 | global using System.Threading;
10 | global using System.Threading.Tasks;
11 |
--------------------------------------------------------------------------------
/src/KubernetesClient.Classic/Kubernetes.Websocket.Netstandard.cs:
--------------------------------------------------------------------------------
1 | using System.Net.Security;
2 | using System.Security.Cryptography.X509Certificates;
3 |
4 | namespace k8s;
5 |
6 | public partial class Kubernetes
7 | {
8 | partial void BeforeRequest()
9 | {
10 | System.Net.ServicePointManager.ServerCertificateValidationCallback += ServerCertificateValidationCallback;
11 | }
12 |
13 | partial void AfterRequest()
14 | {
15 | System.Net.ServicePointManager.ServerCertificateValidationCallback -= ServerCertificateValidationCallback;
16 | }
17 |
18 | private bool ServerCertificateValidationCallback(object sender, X509Certificate certificate, X509Chain chain,
19 | SslPolicyErrors sslPolicyErrors)
20 | {
21 | if (SkipTlsVerify)
22 | {
23 | return true;
24 | }
25 |
26 | return CertificateValidationCallBack(sender, CaCerts, certificate, chain, sslPolicyErrors);
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/KubernetesClient.Kubectl/Beta/AsyncKubectl.Cordon.cs:
--------------------------------------------------------------------------------
1 | using Json.Patch;
2 | using k8s.Models;
3 | using System.Text.Json;
4 |
5 | namespace k8s.kubectl.beta;
6 |
7 | public partial class AsyncKubectl
8 | {
9 | public async Task Cordon(string nodeName, CancellationToken cancellationToken = default)
10 | {
11 | await PatchNodeUnschedulable(nodeName, true, cancellationToken).ConfigureAwait(false);
12 | }
13 |
14 | public async Task Uncordon(string nodeName, CancellationToken cancellationToken = default)
15 | {
16 | await PatchNodeUnschedulable(nodeName, false, cancellationToken).ConfigureAwait(false);
17 | }
18 |
19 | private async Task PatchNodeUnschedulable(string nodeName, bool desired, CancellationToken cancellationToken = default)
20 | {
21 | var node = await client.CoreV1.ReadNodeAsync(nodeName, cancellationToken: cancellationToken).ConfigureAwait(false);
22 |
23 | var old = JsonSerializer.SerializeToDocument(node);
24 | node.Spec.Unschedulable = desired;
25 |
26 | var patch = old.CreatePatch(node);
27 |
28 | await client.CoreV1.PatchNodeAsync(new V1Patch(patch, V1Patch.PatchType.JsonPatch), nodeName, cancellationToken: cancellationToken).ConfigureAwait(false);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/KubernetesClient.Kubectl/Beta/AsyncKubectl.Version.cs:
--------------------------------------------------------------------------------
1 | using k8s.Models;
2 |
3 | namespace k8s.kubectl.beta;
4 |
5 | public partial class AsyncKubectl
6 | {
7 | private const string AsssemblyVersion = ThisAssembly.AssemblyInformationalVersion;
8 |
9 | public record KubernetesSDKVersion
10 | {
11 | public string ClientVersion { get; init; } = AsssemblyVersion;
12 |
13 | public string ClientSwaggerVersion { get; init; } = GeneratedApiVersion.SwaggerVersion;
14 |
15 | public VersionInfo ServerVersion { get; init; } = default!;
16 | }
17 |
18 | public async Task Version(CancellationToken cancellationToken = default)
19 | {
20 | var serverVersion = await client.Version.GetCodeAsync(cancellationToken).ConfigureAwait(false);
21 | return new KubernetesSDKVersion { ServerVersion = serverVersion };
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/KubernetesClient.Kubectl/Beta/AsyncKubectl.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.kubectl.beta;
2 |
3 | public partial class AsyncKubectl
4 | {
5 | private readonly IKubernetes client;
6 |
7 | public AsyncKubectl(IKubernetes client)
8 | {
9 | this.client = client;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/KubernetesClient.Kubectl/Beta/Kubectl.Cordon.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.kubectl.beta;
2 |
3 | public partial class Kubectl
4 | {
5 | public void Cordon(string nodeName)
6 | {
7 | client.Cordon(nodeName).GetAwaiter().GetResult();
8 | }
9 |
10 | public void Uncordon(string nodeName)
11 | {
12 | client.Uncordon(nodeName).GetAwaiter().GetResult();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/KubernetesClient.Kubectl/Beta/Kubectl.Version.cs:
--------------------------------------------------------------------------------
1 | using static k8s.kubectl.beta.AsyncKubectl;
2 |
3 | namespace k8s.kubectl.beta;
4 |
5 | public partial class Kubectl
6 | {
7 | // TODO should auto generate this
8 | public KubernetesSDKVersion Version()
9 | {
10 | return client.Version().GetAwaiter().GetResult();
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/KubernetesClient.Kubectl/Beta/Kubectl.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.kubectl.beta;
2 |
3 | public partial class Kubectl
4 | {
5 | private readonly AsyncKubectl client;
6 |
7 | public Kubectl(IKubernetes client)
8 | {
9 | this.client = new AsyncKubectl(client);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/KubernetesClient.Kubectl/KubernetesClient.Kubectl.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0;net9.0
5 | enable
6 | enable
7 | k8s.kubectl
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Authentication/ExecTokenProvider.cs:
--------------------------------------------------------------------------------
1 | using k8s.KubeConfigModels;
2 | using System.Net.Http.Headers;
3 |
4 | namespace k8s.Authentication
5 | {
6 | public class ExecTokenProvider : ITokenProvider
7 | {
8 | private readonly ExternalExecution exec;
9 | private ExecCredentialResponse response;
10 |
11 | public ExecTokenProvider(ExternalExecution exec)
12 | {
13 | this.exec = exec;
14 | }
15 |
16 | private bool NeedsRefresh()
17 | {
18 | if (response?.Status == null)
19 | {
20 | return true;
21 | }
22 |
23 | if (response.Status.ExpirationTimestamp == null)
24 | {
25 | return false;
26 | }
27 |
28 | return DateTime.UtcNow.AddSeconds(30) > response.Status.ExpirationTimestamp;
29 | }
30 |
31 | public async Task GetAuthenticationHeaderAsync(CancellationToken cancellationToken)
32 | {
33 | if (NeedsRefresh())
34 | {
35 | await RefreshToken().ConfigureAwait(false);
36 | }
37 |
38 | return new AuthenticationHeaderValue("Bearer", response.Status.Token);
39 | }
40 |
41 | private async Task RefreshToken()
42 | {
43 | response =
44 | await Task.Run(() => KubernetesClientConfiguration.ExecuteExternalCommand(this.exec)).ConfigureAwait(false);
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Authentication/ITokenProvider.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation. All rights reserved.
2 | // Licensed under the MIT License. See License.txt in the project root for license information.
3 |
4 | using System.Net.Http.Headers;
5 |
6 | #pragma warning disable SA1606
7 | #pragma warning disable SA1614
8 | namespace k8s.Authentication
9 | {
10 | ///
11 | /// Interface to a source of access tokens.
12 | ///
13 | public interface ITokenProvider
14 | {
15 | ///
16 | ///
17 | ///
18 | ///
19 | /// AuthenticationHeaderValue
20 | Task GetAuthenticationHeaderAsync(CancellationToken cancellationToken);
21 | }
22 | }
23 | #pragma warning restore SA1614
24 | #pragma warning restore SA1606
25 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Authentication/ServiceClientCredentials.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation. All rights reserved.
2 | // Licensed under the MIT License. See License.txt in the project root for license information.
3 |
4 | using System.Net.Http;
5 |
6 | namespace k8s.Authentication
7 | {
8 | ///
9 | /// ServiceClientCredentials is the abstraction for credentials used by ServiceClients accessing REST services.
10 | ///
11 | public abstract class ServiceClientCredentials
12 | {
13 | ///
14 | /// Apply the credentials to the HTTP request.
15 | ///
16 | /// The HTTP request message.
17 | /// Cancellation token.
18 | ///
19 | /// Task that will complete when processing has finished.
20 | ///
21 | public virtual Task ProcessHttpRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken)
22 | {
23 | // Return an empty task by default
24 | return Task.CompletedTask;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Authentication/StringTokenProvider.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation. All rights reserved.
2 | // Licensed under the MIT License. See License.txt in the project root for license information.
3 |
4 | using System.Net.Http.Headers;
5 |
6 | namespace k8s.Authentication
7 | {
8 | ///
9 | /// A simple token provider that always provides a static access token.
10 | ///
11 | public sealed class StringTokenProvider : ITokenProvider
12 | {
13 | private readonly string _accessToken;
14 | private readonly string _type;
15 |
16 | ///
17 | /// Initializes a new instance of the class.
18 | /// Create a token provider for the given token type that returns the given
19 | /// access token.
20 | ///
21 | /// The access token to return.
22 | /// The token type of the given access token.
23 | public StringTokenProvider(string accessToken, string tokenType)
24 | {
25 | _accessToken = accessToken;
26 | _type = tokenType;
27 | }
28 |
29 | ///
30 | /// Gets the token type of this access token.
31 | ///
32 | public string TokenType => _type;
33 |
34 | ///
35 | /// Returns the static access token.
36 | ///
37 | /// The cancellation token for this action.
38 | /// This will not be used since the returned token is static.
39 | /// The access token.
40 | public Task GetAuthenticationHeaderAsync(CancellationToken cancellationToken)
41 | {
42 | return Task.FromResult(new AuthenticationHeaderValue(_type, _accessToken));
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Autorest/HttpExtensions.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation. All rights reserved.
2 | // Licensed under the MIT License. See License.txt in the project root for license information.
3 |
4 | using System.Net.Http;
5 | using System.Net.Http.Headers;
6 |
7 | namespace k8s.Autorest
8 | {
9 | ///
10 | /// Extensions for manipulating HTTP request and response objects.
11 | ///
12 | internal static class HttpExtensions
13 | {
14 | ///
15 | /// Get the content headers of an HttpRequestMessage.
16 | ///
17 | /// The request message.
18 | /// The content headers.
19 | public static HttpHeaders GetContentHeaders(this HttpRequestMessage request)
20 | {
21 | return request?.Content?.Headers;
22 | }
23 |
24 | ///
25 | /// Get the content headers of an HttpResponseMessage.
26 | ///
27 | /// The response message.
28 | /// The content headers.
29 | public static HttpHeaders GetContentHeaders(this HttpResponseMessage response)
30 | {
31 | return response?.Content?.Headers;
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Autorest/HttpRequestMessageWrapper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation. All rights reserved.
2 | // Licensed under the MIT License. See License.txt in the project root for license information.
3 |
4 | using System.Net.Http;
5 |
6 | namespace k8s.Autorest
7 | {
8 | ///
9 | /// Wrapper around HttpRequestMessage type that copies properties of HttpRequestMessage so that
10 | /// they are available after the HttpClient gets disposed.
11 | ///
12 | public class HttpRequestMessageWrapper : HttpMessageWrapper
13 | {
14 | ///
15 | /// Initializes a new instance of the class from HttpRequestMessage.
16 | /// and content.
17 | ///
18 | #pragma warning disable SA1611 // Element parameters should be documented
19 | public HttpRequestMessageWrapper(HttpRequestMessage httpRequest, string content)
20 | #pragma warning restore SA1611 // Element parameters should be documented
21 | {
22 | if (httpRequest == null)
23 | {
24 | throw new ArgumentNullException("httpRequest");
25 | }
26 |
27 | CopyHeaders(httpRequest.Headers);
28 | CopyHeaders(httpRequest.GetContentHeaders());
29 |
30 | Content = content;
31 | Method = httpRequest.Method;
32 | RequestUri = httpRequest.RequestUri;
33 | }
34 |
35 | ///
36 | /// Gets or sets the HTTP method used by the HTTP request message.
37 | ///
38 | public HttpMethod Method { get; protected set; }
39 |
40 | ///
41 | /// Gets or sets the Uri used for the HTTP request.
42 | ///
43 | public Uri RequestUri { get; protected set; }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Autorest/HttpResponseMessageWrapper.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Microsoft Corporation. All rights reserved.
2 | // Licensed under the MIT License. See License.txt in the project root for license information.
3 |
4 | using System.Net;
5 | using System.Net.Http;
6 |
7 | namespace k8s.Autorest
8 | {
9 | ///
10 | /// Wrapper around HttpResponseMessage type that copies properties of HttpResponseMessage so that
11 | /// they are available after the HttpClient gets disposed.
12 | ///
13 | public class HttpResponseMessageWrapper : HttpMessageWrapper
14 | {
15 | ///
16 | /// Initializes a new instance of the class from HttpResponseMessage.
17 | /// and content.
18 | ///
19 | #pragma warning disable SA1611 // Element parameters should be documented
20 | public HttpResponseMessageWrapper(HttpResponseMessage httpResponse, string content)
21 | #pragma warning restore SA1611 // Element parameters should be documented
22 | {
23 | if (httpResponse == null)
24 | {
25 | throw new ArgumentNullException("httpResponse");
26 | }
27 |
28 | CopyHeaders(httpResponse.Headers);
29 | CopyHeaders(httpResponse.GetContentHeaders());
30 |
31 | Content = content;
32 | StatusCode = httpResponse.StatusCode;
33 | ReasonPhrase = httpResponse.ReasonPhrase;
34 | }
35 |
36 | ///
37 | /// Gets or sets the status code of the HTTP response.
38 | ///
39 | public HttpStatusCode StatusCode { get; protected set; }
40 |
41 | ///
42 | /// Exposes the reason phrase, typically sent along with the status code.
43 | ///
44 | public string ReasonPhrase { get; protected set; }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/KubernetesClient/ChannelIndex.cs:
--------------------------------------------------------------------------------
1 | namespace k8s
2 | {
3 | ///
4 | /// These values identify the various channels which you can use when interacting with a process running in a container in a Kubernetes
5 | /// pod.
6 | ///
7 | ///
8 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1028:Enum Storage should be Int32", Justification = "byte only")]
9 | public enum ChannelIndex : byte
10 | {
11 | ///
12 | /// The standard input channel. Use this channel to send input to a process running in a container inside a Kubernetes pod.
13 | ///
14 | StdIn,
15 |
16 | ///
17 | /// The standard output channel. Use this channel to read standard output generated by a process running in a container in a Kubernetes pod.
18 | ///
19 | StdOut,
20 |
21 | ///
22 | /// The standard error channel. Use this channel to read the error output generated by a process running in a container in a Kubernetes pod.
23 | ///
24 | StdErr,
25 |
26 | ///
27 | /// The error channel. This channel is used by Kubernetes to send you error messages, including the exit code of the process.
28 | ///
29 | Error,
30 |
31 | ///
32 | /// The resize channel. Use this channel to resize the terminal. You need to send a JSON-formatted object over this channel, which
33 | /// has a Width and Height property.
34 | ///
35 | ///
36 | Resize,
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/KubernetesClient/ClientSets/ClientSet.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.ClientSets
2 | {
3 | ///
4 | /// Represents a base class for clients that interact with Kubernetes resources.
5 | /// Provides shared functionality for derived resource-specific clients.
6 | ///
7 | public partial class ClientSet
8 | {
9 | private readonly Kubernetes _kubernetes;
10 |
11 | public ClientSet(Kubernetes kubernetes)
12 | {
13 | _kubernetes = kubernetes;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/KubernetesClient/ClientSets/ResourceClient.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.ClientSets
2 | {
3 | ///
4 | /// Represents a set of Kubernetes clients for interacting with the Kubernetes API.
5 | /// This class provides access to various client implementations for managing Kubernetes resources.
6 | ///
7 | public abstract class ResourceClient
8 | {
9 | protected Kubernetes Client { get; }
10 |
11 | public ResourceClient(Kubernetes kubernetes)
12 | {
13 | Client = kubernetes;
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Exceptions/KubeConfigException.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.Exceptions
2 | {
3 | ///
4 | /// The exception that is thrown when the kube config is invalid
5 | ///
6 | public class KubeConfigException : Exception
7 | {
8 | public KubeConfigException()
9 | {
10 | }
11 |
12 | public KubeConfigException(string message)
13 | : base(message)
14 | {
15 | }
16 |
17 | public KubeConfigException(string message, Exception inner)
18 | : base(message, inner)
19 | {
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Exceptions/KubernetesClientException.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.Exceptions
2 | {
3 | ///
4 | /// The exception that is thrown when there is a client exception
5 | ///
6 | public class KubernetesClientException : Exception
7 | {
8 | public KubernetesClientException()
9 | {
10 | }
11 |
12 | public KubernetesClientException(string message)
13 | : base(message)
14 | {
15 | }
16 |
17 | public KubernetesClientException(string message, Exception inner)
18 | : base(message, inner)
19 | {
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/KubernetesClient/ExecAsyncCallback.cs:
--------------------------------------------------------------------------------
1 | namespace k8s
2 | {
3 | ///
4 | /// A prototype for a callback which asynchronously processes the standard input, standard output and standard error of a command executing in
5 | /// a container.
6 | ///
7 | ///
8 | /// The standard input stream of the process.
9 | ///
10 | ///
11 | /// The standard output stream of the process.
12 | ///
13 | ///
14 | /// The standard error stream of the remote process.
15 | ///
16 | ///
17 | /// A which represents the asynchronous processing of the process input, output and error streams. This task
18 | /// should complete once you're done interacting with the remote process.
19 | ///
20 | public delegate Task ExecAsyncCallback(Stream stdIn, Stream stdOut, Stream stdErr);
21 | }
22 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Extensions.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Text.RegularExpressions;
3 |
4 | namespace k8s
5 | {
6 | public static class Extensions
7 | {
8 | public static KubernetesEntityAttribute GetKubernetesTypeMetadata(this T obj)
9 | where T : IKubernetesObject
10 | =>
11 | obj.GetType().GetKubernetesTypeMetadata();
12 | public static KubernetesEntityAttribute GetKubernetesTypeMetadata(this Type currentType)
13 | {
14 | var attr = currentType.GetCustomAttribute();
15 | if (attr == null)
16 | {
17 | throw new InvalidOperationException($"Custom resource must have {nameof(KubernetesEntityAttribute)} applied to it");
18 | }
19 |
20 | return attr;
21 | }
22 |
23 | public static T Initialize(this T obj)
24 | where T : IKubernetesObject
25 | {
26 | var metadata = obj.GetKubernetesTypeMetadata();
27 | obj.ApiVersion = !string.IsNullOrEmpty(metadata.Group) ? $"{metadata.Group}/{metadata.ApiVersion}" : metadata.ApiVersion;
28 | obj.Kind = metadata.Kind ?? obj.GetType().Name;
29 | if (obj is IMetadata withMetadata && withMetadata.Metadata == null)
30 | {
31 | withMetadata.Metadata = new V1ObjectMeta();
32 | }
33 |
34 | return obj;
35 | }
36 |
37 | internal static bool IsValidKubernetesName(this string value) => !Regex.IsMatch(value, "^[a-z0-9-]+$");
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/KubernetesClient/FileSystem.cs:
--------------------------------------------------------------------------------
1 | namespace k8s
2 | {
3 | internal static class FileSystem
4 | {
5 | public interface IFileSystem
6 | {
7 | Stream OpenRead(string path);
8 |
9 | bool Exists(string path);
10 |
11 | string ReadAllText(string path);
12 | }
13 |
14 | public static IFileSystem Current { get; private set; } = new RealFileSystem();
15 |
16 | public static IDisposable With(IFileSystem fileSystem)
17 | {
18 | return new InjectedFileSystem(fileSystem);
19 | }
20 |
21 | private class InjectedFileSystem : IDisposable
22 | {
23 | private readonly IFileSystem _original;
24 |
25 | public InjectedFileSystem(IFileSystem fileSystem)
26 | {
27 | _original = Current;
28 | Current = fileSystem;
29 | }
30 |
31 | public void Dispose()
32 | {
33 | Current = _original;
34 | }
35 | }
36 |
37 | private class RealFileSystem : IFileSystem
38 | {
39 | public bool Exists(string path)
40 | {
41 | return File.Exists(path);
42 | }
43 |
44 | public Stream OpenRead(string path)
45 | {
46 | return File.OpenRead(path);
47 | }
48 |
49 | public string ReadAllText(string path)
50 | {
51 | return File.ReadAllText(path);
52 | }
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/KubernetesClient/FloatEmitter.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using YamlDotNet.Core;
3 | using YamlDotNet.Core.Events;
4 | using YamlDotNet.Serialization;
5 | using YamlDotNet.Serialization.EventEmitters;
6 |
7 | namespace k8s
8 | {
9 | internal class FloatEmitter : ChainedEventEmitter
10 | {
11 | public FloatEmitter(IEventEmitter nextEmitter)
12 | : base(nextEmitter)
13 | {
14 | }
15 |
16 | public override void Emit(ScalarEventInfo eventInfo, IEmitter emitter)
17 | {
18 | switch (eventInfo.Source.Value)
19 | {
20 | // Floating point numbers should always render at least one zero (e.g. 1.0f => '1.0' not '1')
21 | case double d:
22 | emitter.Emit(new Scalar(d.ToString("0.0######################", CultureInfo.InvariantCulture)));
23 | break;
24 | case float f:
25 | emitter.Emit(new Scalar(f.ToString("0.0######################", CultureInfo.InvariantCulture)));
26 | break;
27 | default:
28 | base.Emit(eventInfo, emitter);
29 | break;
30 | }
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/KubernetesClient/GeneratedApiVersion.cs:
--------------------------------------------------------------------------------
1 | namespace k8s;
2 |
3 | public static class GeneratedApiVersion
4 | {
5 | // Now API version is the same as model version
6 | // Change this if api is generated from a separate swagger spec
7 |
8 | public const string AssemblyVersion = GeneratedModelVersion.AssemblyVersion;
9 | public const string SwaggerVersion = GeneratedModelVersion.SwaggerVersion;
10 | }
11 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Global.cs:
--------------------------------------------------------------------------------
1 | global using k8s.Autorest;
2 | global using k8s.Models;
3 | global using System;
4 | global using System.Collections.Generic;
5 | global using System.IO;
6 | global using System.Linq;
7 | global using System.Text.Json;
8 | global using System.Text.Json.Serialization;
9 | global using System.Threading;
10 | global using System.Threading.Tasks;
11 |
--------------------------------------------------------------------------------
/src/KubernetesClient/IItems.cs:
--------------------------------------------------------------------------------
1 | namespace k8s
2 | {
3 | ///
4 | /// Kubernetes object that exposes list of objects
5 | ///
6 | /// type of the objects
7 | public interface IItems
8 | {
9 | ///
10 | /// Gets or sets list of objects. More info:
11 | /// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md
12 | ///
13 | IList Items { get; set; }
14 | }
15 |
16 | public static class ItemsExt
17 | {
18 | public static IEnumerator GetEnumerator(this IItems items)
19 | {
20 | if (items is null)
21 | {
22 | throw new ArgumentNullException(nameof(items));
23 | }
24 |
25 | return items.Items.GetEnumerator();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/KubernetesClient/IKubernetes.Exec.cs:
--------------------------------------------------------------------------------
1 | namespace k8s
2 | {
3 | public partial interface IKubernetes
4 | {
5 | ///
6 | /// Executes a command in a container in a pod.
7 | ///
8 | ///
9 | /// The name of the pod which contains the container in which to execute the command.
10 | ///
11 | ///
12 | /// The namespace of the container.
13 | ///
14 | ///
15 | /// The container in which to run the command.
16 | ///
17 | ///
18 | /// The command to execute.
19 | ///
20 | ///
21 | /// if allocate a pseudo-TTY
22 | ///
23 | ///
24 | /// A callback which processes the standard input, standard output and standard error.
25 | ///
26 | ///
27 | /// A which can be used to cancel the asynchronous operation.
28 | ///
29 | ///
30 | /// A which represents the asynchronous operation.
31 | ///
32 | Task NamespacedPodExecAsync(string name, string @namespace, string container, IEnumerable command,
33 | bool tty, ExecAsyncCallback action, CancellationToken cancellationToken);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/KubernetesClient/IKubernetes.cs:
--------------------------------------------------------------------------------
1 | namespace k8s;
2 |
3 | public partial interface IKubernetes : IBasicKubernetes, IDisposable
4 | {
5 | ///
6 | /// The base URI of the service.
7 | ///
8 | Uri BaseUri { get; set; }
9 | }
10 |
--------------------------------------------------------------------------------
/src/KubernetesClient/IKubernetesObject.cs:
--------------------------------------------------------------------------------
1 | namespace k8s
2 | {
3 | ///
4 | /// Represents a generic Kubernetes object.
5 | ///
6 | ///
7 | /// You can use the if you receive JSON from a Kubernetes API server but
8 | /// are unsure which object the API server is about to return. You can parse the JSON as a
9 | /// and use the and properties to get basic metadata about any Kubernetes object.
10 | /// You can then
11 | ///
12 | public interface IKubernetesObject
13 | {
14 | ///
15 | /// Gets or sets aPIVersion defines the versioned schema of this
16 | /// representation of an object. Servers should convert recognized
17 | /// schemas to the latest internal value, and may reject unrecognized
18 | /// values. More info:
19 | /// https://git.k8s.io/community/contributors/devel/api-conventions.md#resources
20 | ///
21 | [JsonPropertyName("apiVersion")]
22 | string ApiVersion { get; set; }
23 |
24 | ///
25 | /// Gets or sets kind is a string value representing the REST resource
26 | /// this object represents. Servers may infer this from the endpoint
27 | /// the client submits requests to. Cannot be updated. In CamelCase.
28 | /// More info:
29 | /// https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
30 | ///
31 | [JsonPropertyName("kind")]
32 | string Kind { get; set; }
33 | }
34 |
35 | /// Represents a generic Kubernetes object that has an API version, a kind, and metadata.
36 | /// type of metadata
37 | public interface IKubernetesObject : IKubernetesObject, IMetadata
38 | {
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/KubernetesClient/IMetadata.cs:
--------------------------------------------------------------------------------
1 | namespace k8s
2 | {
3 | ///
4 | /// Kubernetes object that exposes metadata
5 | ///
6 | /// Type of metadata exposed. Usually this will be either
7 | /// for lists or for objects
8 | public interface IMetadata
9 | {
10 | ///
11 | /// Gets or sets standard object's metadata. More info:
12 | /// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
13 | ///
14 | T Metadata { get; set; }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/KubernetesClient/ISpec.cs:
--------------------------------------------------------------------------------
1 | namespace k8s
2 | {
3 | ///
4 | /// Represents a Kubernetes object that has a spec
5 | ///
6 | /// type of Kubernetes object
7 | public interface ISpec
8 | {
9 | ///
10 | /// Gets or sets specification of the desired behavior of the entity. More
11 | /// info:
12 | /// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
13 | ///
14 | T Spec { get; set; }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/KubernetesClient/IStatus.cs:
--------------------------------------------------------------------------------
1 | namespace k8s
2 | {
3 | ///
4 | /// Kubernetes object that exposes status
5 | ///
6 | /// The type of status object
7 | public interface IStatus
8 | {
9 | ///
10 | /// Gets or sets most recently observed status of the object. This data
11 | /// may not be up to date. Populated by the system. Read-only. More
12 | /// info:
13 | /// https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
14 | ///
15 | T Status { get; set; }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/KubernetesClient/IValidate.cs:
--------------------------------------------------------------------------------
1 | namespace k8s
2 | {
3 | ///
4 | /// Object that allows self validation
5 | ///
6 | public interface IValidate
7 | {
8 | ///
9 | /// Validate the object.
10 | ///
11 | void Validate();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/KubernetesClient/KubeConfigModels/AuthProvider.cs:
--------------------------------------------------------------------------------
1 | using YamlDotNet.Serialization;
2 |
3 | namespace k8s.KubeConfigModels
4 | {
5 | ///
6 | /// Contains information that describes identity information. This is use to tell the kubernetes cluster who you are.
7 | ///
8 | public class AuthProvider
9 | {
10 | ///
11 | /// Gets or sets the nickname for this auth provider.
12 | ///
13 | [YamlMember(Alias = "name")]
14 | public string Name { get; set; }
15 |
16 | ///
17 | /// Gets or sets the configuration for this auth provider
18 | ///
19 | [YamlMember(Alias = "config")]
20 | public Dictionary Config { get; set; }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/KubernetesClient/KubeConfigModels/Cluster.cs:
--------------------------------------------------------------------------------
1 | using YamlDotNet.Serialization;
2 |
3 | namespace k8s.KubeConfigModels
4 | {
5 | ///
6 | /// Relates nicknames to cluster information.
7 | ///
8 | public class Cluster
9 | {
10 | ///
11 | /// Gets or sets the cluster information.
12 | ///
13 | [YamlMember(Alias = "cluster")]
14 | public ClusterEndpoint ClusterEndpoint { get; set; }
15 |
16 | ///
17 | /// Gets or sets the nickname for this Cluster.
18 | ///
19 | [YamlMember(Alias = "name")]
20 | public string Name { get; set; }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/KubernetesClient/KubeConfigModels/Context.cs:
--------------------------------------------------------------------------------
1 | using YamlDotNet.Serialization;
2 |
3 | namespace k8s.KubeConfigModels
4 | {
5 | ///
6 | /// Relates nicknames to context information.
7 | ///
8 | public class Context
9 | {
10 | ///
11 | /// Gets or sets the context information.
12 | ///
13 | [YamlMember(Alias = "context")]
14 | public ContextDetails ContextDetails { get; set; }
15 |
16 | ///
17 | /// Gets or sets the nickname for this context.
18 | ///
19 | [YamlMember(Alias = "name")]
20 | public string Name { get; set; }
21 |
22 | ///
23 | /// Gets or sets additional information. This is useful for extenders so that reads and writes don't clobber unknown fields.
24 | ///
25 | [YamlMember(Alias = "extensions")]
26 | public IEnumerable Extensions { get; set; }
27 |
28 |
29 | [Obsolete("This property is not set by the YAML config. Use ContextDetails.Namespace instead.")]
30 | [YamlMember(Alias = "namespace")]
31 | public string Namespace { get; set; }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/KubernetesClient/KubeConfigModels/ContextDetails.cs:
--------------------------------------------------------------------------------
1 | using YamlDotNet.Serialization;
2 |
3 | namespace k8s.KubeConfigModels
4 | {
5 | ///
6 | /// Represents a tuple of references to a cluster (how do I communicate with a kubernetes cluster),
7 | /// a user (how do I identify myself), and a namespace (what subset of resources do I want to work with)
8 | ///
9 | public class ContextDetails
10 | {
11 | ///
12 | /// Gets or sets the name of the cluster for this context.
13 | ///
14 | [YamlMember(Alias = "cluster")]
15 | public string Cluster { get; set; }
16 |
17 | ///
18 | /// Gets or sets the name of the user for this context.
19 | ///
20 | [YamlMember(Alias = "user")]
21 | public string User { get; set; }
22 |
23 | ///
24 | /// /Gets or sets the default namespace to use on unspecified requests.
25 | ///
26 | [YamlMember(Alias = "namespace")]
27 | public string Namespace { get; set; }
28 |
29 | ///
30 | /// Gets or sets additional information. This is useful for extenders so that reads and writes don't clobber unknown fields.
31 | ///
32 | [YamlMember(Alias = "extensions")]
33 | public IEnumerable Extensions { get; set; }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/KubernetesClient/KubeConfigModels/ExecCredentialResponse.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.KubeConfigModels
2 | {
3 | public class ExecCredentialResponse
4 | {
5 | public class ExecStatus
6 | {
7 | #nullable enable
8 | public DateTime? ExpirationTimestamp { get; set; }
9 | public string? Token { get; set; }
10 | public string? ClientCertificateData { get; set; }
11 | public string? ClientKeyData { get; set; }
12 | #nullable disable
13 |
14 | public bool IsValid()
15 | {
16 | return !string.IsNullOrEmpty(Token) ||
17 | (!string.IsNullOrEmpty(ClientCertificateData) && !string.IsNullOrEmpty(ClientKeyData));
18 | }
19 | }
20 |
21 | [JsonPropertyName("apiVersion")]
22 | public string ApiVersion { get; set; }
23 | [JsonPropertyName("kind")]
24 | public string Kind { get; set; }
25 | [JsonPropertyName("status")]
26 | public ExecStatus Status { get; set; }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/KubernetesClient/KubeConfigModels/ExternalExecution.cs:
--------------------------------------------------------------------------------
1 | using YamlDotNet.Serialization;
2 |
3 | namespace k8s.KubeConfigModels
4 | {
5 | public class ExternalExecution
6 | {
7 | [YamlMember(Alias = "apiVersion")]
8 | public string ApiVersion { get; set; }
9 |
10 | ///
11 | /// The command to execute. Required.
12 | ///
13 | [YamlMember(Alias = "command")]
14 | public string Command { get; set; }
15 |
16 | ///
17 | /// Environment variables to set when executing the plugin. Optional.
18 | ///
19 | [YamlMember(Alias = "env")]
20 | public IList> EnvironmentVariables { get; set; }
21 |
22 | ///
23 | /// Arguments to pass when executing the plugin. Optional.
24 | ///
25 | [YamlMember(Alias = "args")]
26 | public IList Arguments { get; set; }
27 |
28 | ///
29 | /// Text shown to the user when the executable doesn't seem to be present. Optional.
30 | ///
31 | [YamlMember(Alias = "installHint")]
32 | public string InstallHint { get; set; }
33 |
34 | ///
35 | /// Whether or not to provide cluster information to this exec plugin as a part of
36 | /// the KUBERNETES_EXEC_INFO environment variable. Optional.
37 | ///
38 | [YamlMember(Alias = "provideClusterInfo")]
39 | public bool ProvideClusterInfo { get; set; }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/KubernetesClient/KubeConfigModels/NamedExtension.cs:
--------------------------------------------------------------------------------
1 | using YamlDotNet.Serialization;
2 |
3 | namespace k8s.KubeConfigModels
4 | {
5 | ///
6 | /// relates nicknames to extension information
7 | ///
8 | public class NamedExtension
9 | {
10 | ///
11 | /// Gets or sets the nickname for this extension.
12 | ///
13 | [YamlMember(Alias = "name")]
14 | public string Name { get; set; }
15 |
16 | ///
17 | /// Get or sets the extension information.
18 | ///
19 | [YamlMember(Alias = "extension")]
20 | public dynamic Extension { get; set; }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/KubernetesClient/KubeConfigModels/User.cs:
--------------------------------------------------------------------------------
1 | using YamlDotNet.Serialization;
2 |
3 | namespace k8s.KubeConfigModels
4 | {
5 | ///
6 | /// Relates nicknames to auth information.
7 | ///
8 | public class User
9 | {
10 | ///
11 | /// Gets or sets the auth information.
12 | ///
13 | [YamlMember(Alias = "user")]
14 | public UserCredentials UserCredentials { get; set; }
15 |
16 | ///
17 | /// Gets or sets the nickname for this auth information.
18 | ///
19 | [YamlMember(Alias = "name")]
20 | public string Name { get; set; }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/KubernetesClient/KubernetesClient.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0;net9.0
5 | k8s
6 | true
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/KubernetesClient/KubernetesObject.cs:
--------------------------------------------------------------------------------
1 | namespace k8s
2 | {
3 | ///
4 | /// Represents a generic Kubernetes object.
5 | ///
6 | ///
7 | /// You can use the if you receive JSON from a Kubernetes API server but
8 | /// are unsure which object the API server is about to return. You can parse the JSON as a
9 | /// and use the and properties to get basic metadata about any Kubernetes object.
10 | /// You can then
11 | ///
12 | public class KubernetesObject : IKubernetesObject
13 | {
14 | ///
15 | /// Gets or sets aPIVersion defines the versioned schema of this
16 | /// representation of an object. Servers should convert recognized
17 | /// schemas to the latest internal value, and may reject unrecognized
18 | /// values. More info:
19 | /// https://git.k8s.io/community/contributors/devel/api-conventions.md#resources
20 | ///
21 | [JsonPropertyName("apiVersion")]
22 | public string ApiVersion { get; set; }
23 |
24 | ///
25 | /// Gets or sets kind is a string value representing the REST resource
26 | /// this object represents. Servers may infer this from the endpoint
27 | /// the client submits requests to. Cannot be updated. In CamelCase.
28 | /// More info:
29 | /// https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds
30 | ///
31 | [JsonPropertyName("kind")]
32 | public string Kind { get; set; }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/KubernetesClient/LeaderElection/ILock.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.LeaderElection
2 | {
3 | ///
4 | /// ILock offers a common interface for locking on arbitrary resources used in leader election. The Interface is used to hide the details on specific implementations in order to allow them to change over time.
5 | ///
6 | public interface ILock
7 | {
8 | ///
9 | /// Get returns the LeaderElectionRecord
10 | ///
11 | /// token to cancel the task
12 | /// the record
13 | Task GetAsync(CancellationToken cancellationToken = default);
14 |
15 | ///
16 | /// Create attempts to create a LeaderElectionRecord
17 | ///
18 | /// record to create
19 | /// token to cancel the task
20 | /// true if created
21 | Task CreateAsync(LeaderElectionRecord record, CancellationToken cancellationToken = default);
22 |
23 | ///
24 | /// Update will update and existing LeaderElectionRecord
25 | ///
26 | /// record to create
27 | /// token to cancel the task
28 | /// true if updated
29 | Task UpdateAsync(LeaderElectionRecord record, CancellationToken cancellationToken = default);
30 |
31 |
32 | ///
33 | /// the locks Identity
34 | ///
35 | string Identity { get; }
36 |
37 | ///
38 | /// Describe is used to convert details on current resource lock into a string
39 | ///
40 | /// resource lock description
41 | string Describe();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/KubernetesClient/LeaderElection/LeaderElectionConfig.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.LeaderElection
2 | {
3 | public class LeaderElectionConfig
4 | {
5 | public ILock Lock { get; set; }
6 |
7 | public TimeSpan LeaseDuration { get; set; } = TimeSpan.FromSeconds(15);
8 |
9 | public TimeSpan RenewDeadline { get; set; } = TimeSpan.FromSeconds(10);
10 |
11 | public TimeSpan RetryPeriod { get; set; } = TimeSpan.FromSeconds(2);
12 |
13 | public LeaderElectionConfig(ILock @lock)
14 | {
15 | Lock = @lock;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/KubernetesClient/LeaderElection/ResourceLock/ConfigMapLock.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.LeaderElection.ResourceLock
2 | {
3 | public class ConfigMapLock : MetaObjectAnnotationLock
4 | {
5 | public ConfigMapLock(IKubernetes client, string @namespace, string name, string identity)
6 | : base(client, @namespace, name, identity)
7 | {
8 | }
9 |
10 | protected override Task ReadMetaObjectAsync(IKubernetes client, string name,
11 | string namespaceParameter,
12 | CancellationToken cancellationToken)
13 | {
14 | if (client is null)
15 | {
16 | throw new ArgumentNullException(nameof(client));
17 | }
18 |
19 | return client.CoreV1.ReadNamespacedConfigMapAsync(name, namespaceParameter, cancellationToken: cancellationToken);
20 | }
21 |
22 | protected override Task CreateMetaObjectAsync(IKubernetes client, V1ConfigMap obj,
23 | string namespaceParameter,
24 | CancellationToken cancellationToken)
25 | {
26 | if (client is null)
27 | {
28 | throw new ArgumentNullException(nameof(client));
29 | }
30 |
31 | return client.CoreV1.CreateNamespacedConfigMapAsync(obj, namespaceParameter, cancellationToken: cancellationToken);
32 | }
33 |
34 | protected override Task ReplaceMetaObjectAsync(IKubernetes client, V1ConfigMap obj, string name,
35 | string namespaceParameter,
36 | CancellationToken cancellationToken)
37 | {
38 | if (client is null)
39 | {
40 | throw new ArgumentNullException(nameof(client));
41 | }
42 |
43 | return client.CoreV1.ReplaceNamespacedConfigMapAsync(obj, name, namespaceParameter, cancellationToken: cancellationToken);
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/KubernetesClient/LeaderElection/ResourceLock/EndpointsLock.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.LeaderElection.ResourceLock
2 | {
3 | public class EndpointsLock : MetaObjectAnnotationLock
4 | {
5 | public EndpointsLock(IKubernetes client, string @namespace, string name, string identity)
6 | : base(client, @namespace, name, identity)
7 | {
8 | }
9 |
10 | protected override Task ReadMetaObjectAsync(IKubernetes client, string name, string namespaceParameter, CancellationToken cancellationToken)
11 | {
12 | if (client is null)
13 | {
14 | throw new ArgumentNullException(nameof(client));
15 | }
16 |
17 | return client.CoreV1.ReadNamespacedEndpointsAsync(name, namespaceParameter, cancellationToken: cancellationToken);
18 | }
19 |
20 | protected override Task CreateMetaObjectAsync(IKubernetes client, V1Endpoints obj, string namespaceParameter,
21 | CancellationToken cancellationToken)
22 | {
23 | if (client is null)
24 | {
25 | throw new ArgumentNullException(nameof(client));
26 | }
27 |
28 | return client.CoreV1.CreateNamespacedEndpointsAsync(obj, namespaceParameter, cancellationToken: cancellationToken);
29 | }
30 |
31 | protected override Task ReplaceMetaObjectAsync(IKubernetes client, V1Endpoints obj, string name, string namespaceParameter,
32 | CancellationToken cancellationToken)
33 | {
34 | if (client is null)
35 | {
36 | throw new ArgumentNullException(nameof(client));
37 | }
38 |
39 | return client.CoreV1.ReplaceNamespacedEndpointsAsync(obj, name, namespaceParameter, cancellationToken: cancellationToken);
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/KubernetesClient/LeaderElection/ResourceLock/MetaObjectAnnotationLock.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.LeaderElection.ResourceLock
2 | {
3 | public abstract class MetaObjectAnnotationLock : MetaObjectLock
4 | where T : class, IMetadata, new()
5 | {
6 | protected MetaObjectAnnotationLock(IKubernetes client, string @namespace, string name, string identity)
7 | : base(client, @namespace, name, identity)
8 | {
9 | }
10 |
11 | private const string LeaderElectionRecordAnnotationKey = "control-plane.alpha.kubernetes.io/leader";
12 |
13 | protected override LeaderElectionRecord GetLeaderElectionRecord(T obj)
14 | {
15 | var recordRawStringContent = obj.GetAnnotation(LeaderElectionRecordAnnotationKey);
16 |
17 | if (string.IsNullOrEmpty(recordRawStringContent))
18 | {
19 | return new LeaderElectionRecord();
20 | }
21 |
22 | var record = KubernetesJson.Deserialize(recordRawStringContent);
23 | return record;
24 | }
25 |
26 |
27 | protected override T SetLeaderElectionRecord(LeaderElectionRecord record, T metaObj)
28 | {
29 | metaObj.SetAnnotation(LeaderElectionRecordAnnotationKey, KubernetesJson.Serialize(record));
30 | return metaObj;
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/KubernetesClient/LeaderElection/ResourceLock/MultiLock.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.LeaderElection.ResourceLock
2 | {
3 | public class MultiLock : ILock
4 | {
5 | private readonly ILock primary;
6 | private readonly ILock secondary;
7 |
8 | public MultiLock(ILock primary, ILock secondary)
9 | {
10 | this.primary = primary;
11 | this.secondary = secondary;
12 | }
13 |
14 | public Task GetAsync(CancellationToken cancellationToken = default)
15 | {
16 | return primary.GetAsync(cancellationToken);
17 | }
18 |
19 | public async Task CreateAsync(LeaderElectionRecord record, CancellationToken cancellationToken = default)
20 | {
21 | return await primary.CreateAsync(record, cancellationToken).ConfigureAwait(false)
22 | && await secondary.CreateAsync(record, cancellationToken).ConfigureAwait(false);
23 | }
24 |
25 | public async Task UpdateAsync(LeaderElectionRecord record, CancellationToken cancellationToken = default)
26 | {
27 | return await primary.UpdateAsync(record, cancellationToken).ConfigureAwait(false)
28 | && await secondary.UpdateAsync(record, cancellationToken).ConfigureAwait(false);
29 | }
30 |
31 | public string Identity => primary.Identity;
32 |
33 | public string Describe()
34 | {
35 | return primary.Describe();
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Models/ContainerMetrics.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.Models
2 | {
3 | ///
4 | /// Describes the resource usage metrics of a container pull from metrics server API.
5 | ///
6 | public class ContainerMetrics
7 | {
8 | ///
9 | /// Defines container name corresponding to the one from pod.spec.containers.
10 | ///
11 | [JsonPropertyName("name")]
12 | public string Name { get; set; }
13 |
14 | ///
15 | /// The resource usage.
16 | ///
17 | [JsonPropertyName("usage")]
18 | public IDictionary Usage { get; set; }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Models/GeneratedModelVersion.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.Models;
2 |
3 | public static class GeneratedModelVersion
4 | {
5 | public const string AssemblyVersion = ThisAssembly.AssemblyInformationalVersion;
6 | public const string SwaggerVersion = ThisAssembly.KubernetesSwaggerVersion;
7 | }
8 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Models/IntOrStringJsonConverter.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.Models
2 | {
3 | internal sealed class IntOrStringJsonConverter : JsonConverter
4 | {
5 | public override IntstrIntOrString Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
6 | {
7 | switch (reader.TokenType)
8 | {
9 | case JsonTokenType.String:
10 | return reader.GetString();
11 | case JsonTokenType.Number:
12 | return reader.GetInt64();
13 | default:
14 | break;
15 | }
16 |
17 | throw new NotSupportedException();
18 | }
19 |
20 | public override void Write(Utf8JsonWriter writer, IntstrIntOrString value, JsonSerializerOptions options)
21 | {
22 | if (writer == null)
23 | {
24 | throw new ArgumentNullException(nameof(writer));
25 | }
26 |
27 | var s = value?.Value;
28 |
29 | if (long.TryParse(s, out var intv))
30 | {
31 | writer.WriteNumberValue(intv);
32 | return;
33 | }
34 |
35 | writer.WriteStringValue(s);
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Models/IntOrStringYamlConverter.cs:
--------------------------------------------------------------------------------
1 | using YamlDotNet.Core;
2 | using YamlDotNet.Serialization;
3 |
4 | namespace k8s.Models
5 | {
6 | public class IntOrStringYamlConverter : IYamlTypeConverter
7 | {
8 | public bool Accepts(Type type)
9 | {
10 | return type == typeof(IntstrIntOrString);
11 | }
12 |
13 | public object ReadYaml(IParser parser, Type type, ObjectDeserializer rootDeserializer)
14 | {
15 | if (parser?.Current is YamlDotNet.Core.Events.Scalar scalar)
16 | {
17 | try
18 | {
19 | if (string.IsNullOrEmpty(scalar?.Value))
20 | {
21 | return null;
22 | }
23 |
24 | return new IntstrIntOrString(scalar?.Value);
25 | }
26 | finally
27 | {
28 | parser?.MoveNext();
29 | }
30 | }
31 |
32 | throw new InvalidOperationException(parser?.Current?.ToString());
33 | }
34 |
35 | public void WriteYaml(IEmitter emitter, object value, Type type, ObjectSerializer serializer)
36 | {
37 | var obj = (IntstrIntOrString)value;
38 | emitter?.Emit(new YamlDotNet.Core.Events.Scalar(obj?.Value));
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Models/IntstrIntOrString.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.Models
2 | {
3 | [JsonConverter(typeof(IntOrStringJsonConverter))]
4 | public partial class IntstrIntOrString
5 | {
6 | public static implicit operator IntstrIntOrString(int v)
7 | {
8 | return new IntstrIntOrString(Convert.ToString(v));
9 | }
10 |
11 | public static implicit operator IntstrIntOrString(long v)
12 | {
13 | return new IntstrIntOrString(Convert.ToString(v));
14 | }
15 |
16 | public static implicit operator string(IntstrIntOrString v)
17 | {
18 | return v?.Value;
19 | }
20 |
21 | public static implicit operator IntstrIntOrString(string v)
22 | {
23 | return new IntstrIntOrString(v);
24 | }
25 |
26 | protected bool Equals(IntstrIntOrString other)
27 | {
28 | return string.Equals(Value, other?.Value);
29 | }
30 |
31 | public override bool Equals(object obj)
32 | {
33 | if (ReferenceEquals(null, obj))
34 | {
35 | return false;
36 | }
37 |
38 | if (ReferenceEquals(this, obj))
39 | {
40 | return true;
41 | }
42 |
43 | if (obj.GetType() != GetType())
44 | {
45 | return false;
46 | }
47 |
48 | return Equals((IntstrIntOrString)obj);
49 | }
50 |
51 | public override int GetHashCode()
52 | {
53 | return Value != null ? Value.GetHashCode() : 0;
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Models/KubernetesEntityAttribute.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.Models
2 | {
3 | ///
4 | /// Describes object type in Kubernetes
5 | ///
6 | [AttributeUsage(AttributeTargets.Class)]
7 | public sealed class KubernetesEntityAttribute : Attribute
8 | {
9 | ///
10 | /// The Kubernetes named schema this object is based on.
11 | ///
12 | public string Kind { get; set; }
13 |
14 | ///
15 | /// The Group this Kubernetes type belongs to.
16 | ///
17 | public string Group { get; set; }
18 |
19 | ///
20 | /// The API Version this Kubernetes type belongs to.
21 | ///
22 | public string ApiVersion { get; set; }
23 |
24 | ///
25 | /// The plural name of the entity.
26 | ///
27 | public string PluralName { get; set; }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Models/ModelVersionConverter.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.Models;
2 |
3 | public static class ModelVersionConverter
4 | {
5 | public interface IModelVersionConverter
6 | {
7 | TTo Convert(TFrom from);
8 | }
9 |
10 | public static IModelVersionConverter Converter { get; set; }
11 |
12 | internal static TTo Convert(TFrom from)
13 | {
14 | if (Converter == null)
15 | {
16 | throw new InvalidOperationException("Converter is not set");
17 | }
18 |
19 | return Converter.Convert(from);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Models/NodeMetrics.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.Models
2 | {
3 | ///
4 | /// Describes the resource usage metrics of a node pull from metrics server API.
5 | ///
6 | public class NodeMetrics : IMetadata
7 | {
8 | ///
9 | /// The kubernetes standard object's metadata.
10 | ///
11 | [JsonPropertyName("metadata")]
12 | public V1ObjectMeta Metadata { get; set; }
13 |
14 | ///
15 | /// The timestamp when metrics were collected.
16 | ///
17 | [JsonPropertyName("timestamp")]
18 | public DateTime? Timestamp { get; set; }
19 |
20 | ///
21 | /// The interval from which metrics were collected.
22 | ///
23 | [JsonPropertyName("window")]
24 | public string Window { get; set; }
25 |
26 | ///
27 | /// The resource usage.
28 | ///
29 | [JsonPropertyName("usage")]
30 | public IDictionary Usage { get; set; }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Models/NodeMetricsList.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.Models
2 | {
3 | public class NodeMetricsList : IMetadata
4 | {
5 | ///
6 | /// Defines the versioned schema of this representation of an object.
7 | ///
8 | [JsonPropertyName("apiVersion")]
9 | public string ApiVersion { get; set; }
10 |
11 | ///
12 | /// Defines the REST resource this object represents.
13 | ///
14 | [JsonPropertyName("kind")]
15 | public string Kind { get; set; }
16 |
17 | ///
18 | /// The kubernetes standard object's metadata.
19 | ///
20 | [JsonPropertyName("metadata")]
21 | public V1ObjectMeta Metadata { get; set; }
22 |
23 | ///
24 | /// The list of node metrics.
25 | ///
26 | [JsonPropertyName("items")]
27 | public IEnumerable Items { get; set; }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Models/PodMetrics.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.Models
2 | {
3 | ///
4 | /// Describes the resource usage metrics of a pod pull from metrics server API.
5 | ///
6 | public class PodMetrics : IMetadata
7 | {
8 | ///
9 | /// The kubernetes standard object's metadata.
10 | ///
11 | [JsonPropertyName("metadata")]
12 | public V1ObjectMeta Metadata { get; set; }
13 |
14 | ///
15 | /// The timestamp when metrics were collected.
16 | ///
17 | [JsonPropertyName("timestamp")]
18 | public DateTime? Timestamp { get; set; }
19 |
20 | ///
21 | /// The interval from which metrics were collected.
22 | ///
23 | [JsonPropertyName("window")]
24 | public string Window { get; set; }
25 |
26 | ///
27 | /// The list of containers metrics.
28 | ///
29 | [JsonPropertyName("containers")]
30 | public List Containers { get; set; }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Models/PodMetricsList.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.Models
2 | {
3 | public class PodMetricsList : IMetadata
4 | {
5 | ///
6 | /// Defines the versioned schema of this representation of an object.
7 | ///
8 | [JsonPropertyName("apiVersion")]
9 | public string ApiVersion { get; set; }
10 |
11 | ///
12 | /// Defines the REST resource this object represents.
13 | ///
14 | [JsonPropertyName("kind")]
15 | public string Kind { get; set; }
16 |
17 | ///
18 | /// The kubernetes standard object's metadata.
19 | ///
20 | [JsonPropertyName("metadata")]
21 | public V1ObjectMeta Metadata { get; set; }
22 |
23 | ///
24 | /// The list of pod metrics.
25 | ///
26 | [JsonPropertyName("items")]
27 | public IEnumerable Items { get; set; }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Models/ResourceQuantityJsonConverter.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.Models
2 | {
3 | internal sealed class ResourceQuantityJsonConverter : JsonConverter
4 | {
5 | // https://github.com/kubernetes/apimachinery/blob/4b14f804a0babdcc58e695d72f77ad29f536511e/pkg/api/resource/quantity.go#L683
6 | public override ResourceQuantity Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
7 | {
8 | switch (reader.TokenType)
9 | {
10 | case JsonTokenType.Null:
11 | return new ResourceQuantity(null);
12 | case JsonTokenType.Number:
13 | if (reader.TryGetDouble(out var val))
14 | {
15 | return new ResourceQuantity(Convert.ToString(val));
16 | }
17 |
18 | return reader.GetDecimal();
19 | default:
20 | return new ResourceQuantity(reader.GetString());
21 | }
22 | }
23 |
24 | public override void Write(Utf8JsonWriter writer, ResourceQuantity value, JsonSerializerOptions options)
25 | {
26 | if (writer == null)
27 | {
28 | throw new ArgumentNullException(nameof(writer));
29 | }
30 |
31 | writer.WriteStringValue(value?.ToString());
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Models/ResourceQuantityYamlConverter.cs:
--------------------------------------------------------------------------------
1 | using YamlDotNet.Core;
2 | using YamlDotNet.Serialization;
3 |
4 | namespace k8s.Models
5 | {
6 | public class ResourceQuantityYamlConverter : IYamlTypeConverter
7 | {
8 | public bool Accepts(Type type)
9 | {
10 | return type == typeof(ResourceQuantity);
11 | }
12 |
13 | public object ReadYaml(IParser parser, Type type, ObjectDeserializer rootDeserializer)
14 | {
15 | if (parser?.Current is YamlDotNet.Core.Events.Scalar scalar)
16 | {
17 | try
18 | {
19 | if (string.IsNullOrEmpty(scalar?.Value))
20 | {
21 | return null;
22 | }
23 |
24 | return new ResourceQuantity(scalar?.Value);
25 | }
26 | finally
27 | {
28 | parser?.MoveNext();
29 | }
30 | }
31 |
32 | throw new InvalidOperationException(parser?.Current?.ToString());
33 | }
34 |
35 | public void WriteYaml(IEmitter emitter, object value, Type type, ObjectSerializer serializer)
36 | {
37 | var obj = (ResourceQuantity)value;
38 | emitter?.Emit(new YamlDotNet.Core.Events.Scalar(obj?.ToString()));
39 | }
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Models/V1Patch.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.Models
2 | {
3 | [JsonConverter(typeof(V1PatchJsonConverter))]
4 | public partial class V1Patch
5 | {
6 | public enum PatchType
7 | {
8 | ///
9 | /// not set, this is not allowed
10 | ///
11 | Unknown,
12 |
13 | ///
14 | /// content type application/json-patch+json
15 | ///
16 | JsonPatch,
17 |
18 | ///
19 | /// content type application/merge-patch+json
20 | ///
21 | MergePatch,
22 |
23 | ///
24 | /// content type application/strategic-merge-patch+json
25 | ///
26 | StrategicMergePatch,
27 |
28 | ///
29 | /// content type application/apply-patch+yaml
30 | ///
31 | ApplyPatch,
32 | }
33 |
34 | public PatchType Type { get; private set; }
35 |
36 | public V1Patch(object body, PatchType type)
37 | {
38 | Content = body;
39 | Type = type;
40 | CustomInit();
41 | }
42 |
43 | partial void CustomInit()
44 | {
45 | if (Content == null)
46 | {
47 | throw new ArgumentNullException(nameof(Content), "object must be set");
48 | }
49 |
50 | if (Type == PatchType.Unknown)
51 | {
52 | throw new ArgumentException("patch type must be set", nameof(Type));
53 | }
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Models/V1PatchJsonConverter.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.Models
2 | {
3 | internal sealed class V1PatchJsonConverter : JsonConverter
4 | {
5 | public override V1Patch Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
6 | {
7 | throw new NotImplementedException();
8 | }
9 |
10 | public override void Write(Utf8JsonWriter writer, V1Patch value, JsonSerializerOptions options)
11 | {
12 | if (writer == null)
13 | {
14 | throw new ArgumentNullException(nameof(writer));
15 | }
16 |
17 | var content = value?.Content;
18 | if (content is string s)
19 | {
20 | writer.WriteRawValue(s);
21 | return;
22 | }
23 |
24 | JsonSerializer.Serialize(writer, content, options);
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Models/V1PodTemplateSpec.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.Models
2 | {
3 | ///
4 | /// Partial implementation of the IMetadata interface
5 | /// to open this class up to ModelExtensions methods
6 | ///
7 | public partial class V1PodTemplateSpec : IMetadata
8 | {
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Models/V1Status.ObjectView.cs:
--------------------------------------------------------------------------------
1 | namespace k8s.Models
2 | {
3 | public partial class V1Status
4 | {
5 | internal sealed class V1StatusObjectViewConverter : JsonConverter
6 | {
7 | public override V1Status Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
8 | {
9 | var obj = JsonElement.ParseValue(ref reader);
10 |
11 | try
12 | {
13 | return obj.Deserialize();
14 | }
15 | catch (JsonException)
16 | {
17 | // should be an object
18 | }
19 |
20 | return new V1Status { _original = obj, HasObject = true };
21 | }
22 |
23 | public override void Write(Utf8JsonWriter writer, V1Status value, JsonSerializerOptions options)
24 | {
25 | throw new NotImplementedException(); // will not send v1status to server
26 | }
27 | }
28 |
29 | private JsonElement _original;
30 |
31 | public bool HasObject { get; private set; }
32 |
33 | public T ObjectView()
34 | {
35 | return _original.Deserialize();
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Models/V1Status.cs:
--------------------------------------------------------------------------------
1 | using System.Net;
2 |
3 | namespace k8s.Models
4 | {
5 | public partial class V1Status
6 | {
7 | /// Converts a object into a short description of the status.
8 | /// string description of the status
9 | public override string ToString()
10 | {
11 | var reason = Reason;
12 | if (string.IsNullOrEmpty(reason) && Code.GetValueOrDefault() != 0)
13 | {
14 | reason = ((HttpStatusCode)Code.Value).ToString();
15 | }
16 |
17 | return string.IsNullOrEmpty(Message) ? string.IsNullOrEmpty(reason) ? Status : reason :
18 | string.IsNullOrEmpty(reason) ? Message : $"{reason} - {Message}";
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/KubernetesClient/StreamType.cs:
--------------------------------------------------------------------------------
1 | namespace k8s
2 | {
3 | ///
4 | /// When creating a object, specify to properly handle
5 | /// the underlying communication.
6 | ///
7 | public enum StreamType
8 | {
9 | ///
10 | /// This object is used to stream a remote command or attach to a remote
11 | /// container.
12 | ///
13 | RemoteCommand,
14 |
15 | ///
16 | /// This object is used in port forwarding.
17 | ///
18 | PortForward,
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/KubernetesClient/Utilities.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 |
3 | namespace k8s
4 | {
5 | internal static class Utilities
6 | {
7 | internal static void AddQueryParameter(StringBuilder sb, string key, string value)
8 | {
9 | if (sb == null)
10 | {
11 | throw new ArgumentNullException(nameof(sb));
12 | }
13 |
14 | if (string.IsNullOrEmpty(key))
15 | {
16 | throw new ArgumentNullException(nameof(key));
17 | }
18 |
19 | sb.Append(sb.Length != 0 ? '&' : '?').Append(Uri.EscapeDataString(key)).Append('=');
20 | if (!string.IsNullOrEmpty(value))
21 | {
22 | sb.Append(Uri.EscapeDataString(value));
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/LibKubernetesGenerator/EmbedResource.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Reflection;
3 |
4 | namespace LibKubernetesGenerator;
5 |
6 | internal static class EmbedResource
7 | {
8 | public static string GetResource(string name)
9 | {
10 | var assembly = Assembly.GetExecutingAssembly();
11 |
12 | var resourceName = assembly.GetName().Name + "." + name;
13 |
14 | using var stream = assembly.GetManifestResourceStream(resourceName);
15 | using var reader = new StreamReader(stream ?? throw new FileNotFoundException(resourceName));
16 | return reader.ReadToEnd();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/LibKubernetesGenerator/GeneratorExecutionContextExt.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis;
2 | using Microsoft.CodeAnalysis.Text;
3 | using Scriban;
4 | using Scriban.Runtime;
5 | using System.Text;
6 |
7 | namespace LibKubernetesGenerator
8 | {
9 | internal static class GeneratorExecutionContextExt
10 | {
11 | public static void RenderToContext(this IncrementalGeneratorPostInitializationContext context, string templatefile, ScriptObject sc, string generatedfile)
12 | {
13 | var tc = new TemplateContext();
14 | tc.PushGlobal(sc);
15 | context.RenderToContext(templatefile, tc, generatedfile);
16 | }
17 |
18 | public static void RenderToContext(this IncrementalGeneratorPostInitializationContext context, string templatefile, TemplateContext tc, string generatedfile)
19 | {
20 | var template = Template.Parse(EmbedResource.GetResource(templatefile));
21 | var generated = template.Render(tc);
22 | context.AddSource(generatedfile, SourceText.From(generated, Encoding.UTF8));
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/LibKubernetesGenerator/IScriptObjectHelper.cs:
--------------------------------------------------------------------------------
1 | using Scriban.Runtime;
2 |
3 | namespace LibKubernetesGenerator;
4 |
5 | internal interface IScriptObjectHelper
6 | {
7 | void RegisterHelper(ScriptObject scriptObject);
8 | }
9 |
--------------------------------------------------------------------------------
/src/LibKubernetesGenerator/ModelExtGenerator.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis;
2 | using NSwag;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 |
6 | namespace LibKubernetesGenerator
7 | {
8 | internal class ModelExtGenerator
9 | {
10 | private readonly ClassNameHelper classNameHelper;
11 | private readonly ScriptObjectFactory scriptObjectFactory;
12 |
13 | public ModelExtGenerator(ClassNameHelper classNameHelper, ScriptObjectFactory scriptObjectFactory)
14 | {
15 | this.classNameHelper = classNameHelper;
16 | this.scriptObjectFactory = scriptObjectFactory;
17 | }
18 |
19 | public void Generate(OpenApiDocument swagger, IncrementalGeneratorPostInitializationContext context)
20 | {
21 | // Generate the interface declarations
22 | var skippedTypes = new HashSet { "V1WatchEvent" };
23 |
24 | var definitions = swagger.Definitions.Values
25 | .Where(
26 | d => d.ExtensionData != null
27 | && d.ExtensionData.ContainsKey("x-kubernetes-group-version-kind")
28 | && !skippedTypes.Contains(classNameHelper.GetClassName(d)));
29 |
30 | var sc = scriptObjectFactory.CreateScriptObject();
31 | sc.SetValue("definitions", definitions, true);
32 |
33 | context.RenderToContext("ModelExtensions.cs.template", sc, "ModelExtensions.g.cs");
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/LibKubernetesGenerator/ModelGenerator.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis;
2 | using NSwag;
3 |
4 | namespace LibKubernetesGenerator
5 | {
6 | internal class ModelGenerator
7 | {
8 | private readonly ClassNameHelper classNameHelper;
9 | private readonly ScriptObjectFactory scriptObjectFactory;
10 |
11 | public ModelGenerator(ClassNameHelper classNameHelper, ScriptObjectFactory scriptObjectFactory)
12 | {
13 | this.classNameHelper = classNameHelper;
14 | this.scriptObjectFactory = scriptObjectFactory;
15 | }
16 |
17 | public void Generate(OpenApiDocument swagger, IncrementalGeneratorPostInitializationContext context)
18 | {
19 | var sc = scriptObjectFactory.CreateScriptObject();
20 |
21 |
22 | foreach (var kv in swagger.Definitions)
23 | {
24 | var def = kv.Value;
25 | var clz = classNameHelper.GetClassNameForSchemaDefinition(def);
26 |
27 | sc.SetValue("clz", clz, true);
28 | sc.SetValue("def", def, true);
29 | sc.SetValue("properties", def.Properties.Values, true);
30 |
31 | context.RenderToContext("Model.cs.template", sc, $"Models_{clz}.g.cs");
32 | }
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/LibKubernetesGenerator/ScriptObjectFactory.cs:
--------------------------------------------------------------------------------
1 | using Scriban.Runtime;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | namespace LibKubernetesGenerator;
6 |
7 | internal class ScriptObjectFactory
8 | {
9 | private readonly List scriptObjectHelpers;
10 |
11 | public ScriptObjectFactory(IEnumerable scriptObjectHelpers)
12 | {
13 | this.scriptObjectHelpers = scriptObjectHelpers.ToList();
14 | }
15 |
16 | public ScriptObject CreateScriptObject()
17 | {
18 | var scriptObject = new ScriptObject();
19 | foreach (var helper in scriptObjectHelpers)
20 | {
21 | helper.RegisterHelper(scriptObject);
22 | }
23 |
24 | return scriptObject;
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/src/LibKubernetesGenerator/SourceGenerationContextGenerator.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis;
2 | using NSwag;
3 |
4 | namespace LibKubernetesGenerator
5 | {
6 | internal class SourceGenerationContextGenerator
7 | {
8 | private readonly ScriptObjectFactory scriptObjectFactory;
9 |
10 | public SourceGenerationContextGenerator(ScriptObjectFactory scriptObjectFactory)
11 | {
12 | this.scriptObjectFactory = scriptObjectFactory;
13 | }
14 |
15 | public void Generate(OpenApiDocument swagger, IncrementalGeneratorPostInitializationContext context)
16 | {
17 | var definitions = swagger.Definitions.Values;
18 | var sc = scriptObjectFactory.CreateScriptObject();
19 | sc.SetValue("definitions", definitions, true);
20 |
21 | context.RenderToContext("SourceGenerationContext.cs.template", sc, "SourceGenerationContext.g.cs");
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/LibKubernetesGenerator/UtilHelper.cs:
--------------------------------------------------------------------------------
1 | using NSwag;
2 | using Scriban.Runtime;
3 |
4 | namespace LibKubernetesGenerator
5 | {
6 | internal class UtilHelper : IScriptObjectHelper
7 | {
8 | public void RegisterHelper(ScriptObject scriptObject)
9 | {
10 | scriptObject.Import(nameof(IfKindIs), IfKindIs);
11 | }
12 |
13 | public static bool IfKindIs(OpenApiParameter parameter, string kind)
14 | {
15 | if (parameter != null)
16 | {
17 | if (kind == "query" && parameter.Kind == OpenApiParameterKind.Query)
18 | {
19 | return true;
20 | }
21 | else if (kind == "path" && parameter.Kind == OpenApiParameterKind.Path)
22 | {
23 | return true;
24 | }
25 | }
26 |
27 | return false;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/LibKubernetesGenerator/VersionGenerator.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.CodeAnalysis;
2 | using NSwag;
3 |
4 | namespace LibKubernetesGenerator;
5 |
6 | internal class VersionGenerator
7 | {
8 | public void Generate(OpenApiDocument swagger, IncrementalGeneratorPostInitializationContext context)
9 | {
10 | context.AddSource("k8sver.cs", $"// \n" + "internal static partial class ThisAssembly { internal const string KubernetesSwaggerVersion = \"" + swagger.Info.Version + "\";}");
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/LibKubernetesGenerator/generators/LibKubernetesGenerator/LibKubernetesGenerator.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | $(DefineConstants);GENERATE_BASIC;
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/src/LibKubernetesGenerator/templates/AbstractKubernetes.cs.template:
--------------------------------------------------------------------------------
1 | //
2 | // Code generated by https://github.com/kubernetes-client/csharp/tree/master/src/LibKubernetesGenerator
3 | // Changes may cause incorrect behavior and will be lost if the code is
4 | // regenerated.
5 | //
6 |
7 | namespace k8s;
8 |
9 | ///
10 | ///
11 | public abstract partial class AbstractKubernetes
12 | {
13 | {{for group in groups}}
14 | public I{{group}}Operations {{group}} => this;
15 | {{end}}
16 | }
17 |
--------------------------------------------------------------------------------
/src/LibKubernetesGenerator/templates/ClientSet.cs.template:
--------------------------------------------------------------------------------
1 | //
2 | // Code generated by https://github.com/kubernetes-client/csharp/tree/master/src/LibKubernetesGenerator
3 | // Changes may cause incorrect behavior and will be lost if the code is
4 | // regenerated.
5 | //
6 |
7 | namespace k8s.ClientSets;
8 |
9 | ///
10 | ///
11 | public partial class ClientSet
12 | {
13 | {{for group in groups}}
14 | public {{group}}GroupClient {{group}} => new {{group}}GroupClient(_kubernetes);
15 | {{end}}
16 | }
17 |
--------------------------------------------------------------------------------
/src/LibKubernetesGenerator/templates/GroupClient.cs.template:
--------------------------------------------------------------------------------
1 | //
2 | // Code generated by https://github.com/kubernetes-client/csharp/tree/master/src/LibKubernetesGenerator
3 | // Changes may cause incorrect behavior and will be lost if the code is
4 | // regenerated.
5 | //
6 |
7 | namespace k8s.ClientSets;
8 |
9 |
10 | ///
11 | ///
12 | public partial class {{name}}GroupClient
13 | {
14 | private readonly Kubernetes _kubernetes;
15 |
16 | {{for client in clients}}
17 | public {{client}}Client {{client}} => new {{client}}Client(_kubernetes);
18 | {{end}}
19 |
20 | public {{name}}GroupClient(Kubernetes kubernetes)
21 | {
22 | _kubernetes = kubernetes;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/LibKubernetesGenerator/templates/IBasicKubernetes.cs.template:
--------------------------------------------------------------------------------
1 | //
2 | // Code generated by https://github.com/kubernetes-client/csharp/tree/master/src/LibKubernetesGenerator
3 | // Changes may cause incorrect behavior and will be lost if the code is
4 | // regenerated.
5 | //
6 |
7 | namespace k8s;
8 |
9 | ///
10 | ///
11 | public partial interface IBasicKubernetes
12 | {
13 | {{for group in groups}}
14 | I{{group}}Operations {{group}} { get; }
15 | {{end}}
16 | }
--------------------------------------------------------------------------------
/src/LibKubernetesGenerator/templates/ModelExtensions.cs.template:
--------------------------------------------------------------------------------
1 | //
2 | // Code generated by https://github.com/kubernetes-client/csharp/tree/master/src/LibKubernetesGenerator
3 | // Changes may cause incorrect behavior and will be lost if the code is regenerated.
4 | //
5 | namespace k8s.Models
6 | {
7 | {{ for definition in definitions }}
8 | [KubernetesEntity(Group=KubeGroup, Kind=KubeKind, ApiVersion=KubeApiVersion, PluralName=KubePluralName)]
9 | public partial class {{ GetClassName definition }} : {{ GetInterfaceName definition }}
10 | {
11 | public const string KubeApiVersion = "{{ GetApiVersion definition }}";
12 | public const string KubeKind = "{{ GetKind definition }}";
13 | public const string KubeGroup = "{{ GetGroup definition }}";
14 | public const string KubePluralName = "{{ GetPlural definition }}";
15 | }
16 | {{ end }}
17 | }
18 |
--------------------------------------------------------------------------------
/src/LibKubernetesGenerator/templates/SourceGenerationContext.cs.template:
--------------------------------------------------------------------------------
1 | //
2 | // Code generated by https://github.com/kubernetes-client/csharp/tree/master/src/LibKubernetesGenerator
3 | // Changes may cause incorrect behavior and will be lost if the code is regenerated.
4 | //
5 | #if NET8_0_OR_GREATER
6 | namespace k8s
7 | {
8 | {{ for definition in definitions }}
9 | [JsonSerializable(typeof({{ GetClassName definition }}))]
10 | {{ end }}
11 | internal partial class SourceGenerationContext : JsonSerializerContext
12 | {
13 | }
14 | }
15 | #endif
--------------------------------------------------------------------------------
/src/nuget.proj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/stylecop.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema":
3 | "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json",
4 | "settings": {
5 | "orderingRules": {
6 | "systemUsingDirectivesFirst": false,
7 | "usingDirectivesPlacement": "outsideNamespace"
8 | }
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/tests/E2E.Aot.Tests/E2E.Aot.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | false
4 | k8s.E2E
5 | net8.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | runtime; build; native; contentfiles; analyzers; buildtransitive
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/tests/E2E.Tests/E2E.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | false
4 | k8s.E2E
5 | net8.0;net9.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | runtime; build; native; contentfiles; analyzers; buildtransitive
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/tests/E2E.Tests/KubectlTests.cs:
--------------------------------------------------------------------------------
1 | using k8s.kubectl.beta;
2 | using System.Linq;
3 | using Xunit;
4 |
5 | namespace k8s.E2E;
6 |
7 | [Collection(nameof(Onebyone))]
8 | public class KubectlTests
9 | {
10 | [MinikubeFact]
11 | public void CordonTest()
12 | {
13 | var client = MinikubeTests.CreateClient();
14 |
15 | var node = client.CoreV1.ListNode().Items.First();
16 | var nodeName = node.Metadata.Name;
17 |
18 | var kubectl = new Kubectl(client);
19 |
20 | // cordon
21 | kubectl.Cordon(nodeName);
22 |
23 | // check node status
24 | var cordonNode = client.CoreV1.ReadNode(nodeName);
25 | Assert.True(cordonNode.Spec.Unschedulable);
26 |
27 | // uncordon
28 | kubectl.Uncordon(nodeName);
29 | cordonNode = client.CoreV1.ReadNode(nodeName);
30 | Assert.True(cordonNode.Spec.Unschedulable == null || cordonNode.Spec.Unschedulable == false);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/tests/E2E.Tests/MinikubeFactAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Xunit;
3 |
4 | namespace k8s.E2E
5 | {
6 | public sealed class MinikubeFactAttribute : FactAttribute
7 | {
8 | private static readonly bool HasEnv = !string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("K8S_E2E_MINIKUBE"));
9 |
10 | public override string Skip => !HasEnv ? "K8S_E2_MINIKUBE not set" : null;
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/tests/E2E.Tests/Onebyone.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 |
3 | namespace k8s.E2E;
4 |
5 | [CollectionDefinition(nameof(Onebyone), DisableParallelization = true)]
6 | public class Onebyone
7 | {
8 | }
9 |
--------------------------------------------------------------------------------
/tests/Kubectl.Tests/Kubectl.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0;net9.0
5 | enable
6 | enable
7 | false
8 | k8s.kubectl.Tests
9 |
10 |
11 |
12 |
13 |
14 |
15 | runtime; build; native; contentfiles; analyzers; buildtransitive
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | PreserveNewest
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/tests/Kubectl.Tests/KubectlTests.Version.cs:
--------------------------------------------------------------------------------
1 | using k8s.E2E;
2 | using k8s.kubectl.beta;
3 | using System.Text.Json;
4 | using Xunit;
5 |
6 | namespace k8s.kubectl.Tests;
7 |
8 | public partial class KubectlTests
9 | {
10 | [MinikubeFact]
11 | public void Version()
12 | {
13 | using var kubernetes = MinikubeTests.CreateClient();
14 | var client = new Kubectl(kubernetes);
15 | var version = client.Version();
16 | var serverobj = version.ServerVersion;
17 |
18 | var output = RunKubectl("version");
19 |
20 | var serverstr = output.Split('\n').Skip(1).First().Trim();
21 |
22 | Assert.Equal(serverstr, $"Server Version: version.Info{{Major:\"{serverobj.Major}\", Minor:\"{serverobj.Minor}\", GitVersion:\"{serverobj.GitVersion}\", GitCommit:\"{serverobj.GitCommit}\", GitTreeState:\"{serverobj.GitTreeState}\", BuildDate:\"{serverobj.BuildDate}\", GoVersion:\"{serverobj.GoVersion}\", Compiler:\"{serverobj.Compiler}\", Platform:\"{serverobj.Platform}\"}}");
23 |
24 | dynamic? swagger = JsonSerializer.Deserialize(File.OpenRead("swagger.json"), new
25 | {
26 | info = new
27 | {
28 | version = "",
29 | },
30 | }.GetType());
31 |
32 | Assert.Equal(swagger?.info.version, version.ClientSwaggerVersion);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/tests/Kubectl.Tests/KubectlTests.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 |
3 | namespace k8s.kubectl.Tests;
4 |
5 | public partial class KubectlTests
6 | {
7 | private string RunKubectl(string args)
8 | {
9 | var p = new Process
10 | {
11 | StartInfo = new ProcessStartInfo
12 | {
13 | FileName = "kubectl",
14 | Arguments = args,
15 | UseShellExecute = false,
16 | RedirectStandardOutput = true,
17 | RedirectStandardError = true,
18 | CreateNoWindow = true,
19 | },
20 | };
21 |
22 | p.Start();
23 |
24 | try
25 | {
26 | if (!p.WaitForExit((int)TimeSpan.FromSeconds(30).TotalMilliseconds))
27 | {
28 | throw new Exception("kubectl timed out");
29 | }
30 |
31 | if (p.ExitCode != 0)
32 | {
33 | throw new Exception(p.StandardError.ReadToEnd());
34 | }
35 |
36 | return p.StandardOutput.ReadToEnd();
37 | }
38 | finally
39 | {
40 | p.Kill(true);
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Classic.Tests/KubernetesClient.Classic.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | false
4 | k8s.Tests
5 | net8.0;net9.0
6 | net8.0;net9.0;net48
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | runtime; build; native; contentfiles; analyzers; buildtransitive
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using Xunit;
2 |
3 | [assembly: CollectionBehavior(DisableTestParallelization = true)]
4 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/ExternalExecutionTests.cs:
--------------------------------------------------------------------------------
1 | using k8s.KubeConfigModels;
2 | using System.Collections.Generic;
3 | using System.Text.Json;
4 | using Xunit;
5 |
6 | namespace k8s.Tests
7 | {
8 | public class ExternalExecutionTests
9 | {
10 | [Fact]
11 | public void CreateRunnableExternalProcess()
12 | {
13 | var actual = KubernetesClientConfiguration.CreateRunnableExternalProcess(new ExternalExecution
14 | {
15 | ApiVersion = "testingversion",
16 | Command = "command",
17 | Arguments = new List { "arg1", "arg2" },
18 | EnvironmentVariables = new List>
19 | { new Dictionary { { "name", "testkey" }, { "value", "testvalue" } } },
20 | });
21 |
22 | var actualExecInfo = JsonSerializer.Deserialize>(actual.StartInfo.EnvironmentVariables["KUBERNETES_EXEC_INFO"]);
23 | Assert.Equal("testingversion", actualExecInfo["apiVersion"].ToString());
24 | Assert.Equal("ExecCredentials", actualExecInfo["kind"].ToString());
25 |
26 | Assert.Equal("command", actual.StartInfo.FileName);
27 | Assert.Equal("arg1 arg2", actual.StartInfo.Arguments);
28 | Assert.Equal("testvalue", actual.StartInfo.EnvironmentVariables["testkey"]);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/IntOrStringTests.cs:
--------------------------------------------------------------------------------
1 | using k8s.Models;
2 | using Xunit;
3 |
4 | namespace k8s.Tests
5 | {
6 | public class IntOrStringTests
7 | {
8 | [Fact]
9 | public void Serialize()
10 | {
11 | {
12 | var v = 123;
13 | IntstrIntOrString intorstr = v;
14 |
15 | Assert.Equal("123", KubernetesJson.Serialize(intorstr));
16 | }
17 |
18 | {
19 | IntstrIntOrString intorstr = "12%";
20 | Assert.Equal("\"12%\"", KubernetesJson.Serialize(intorstr));
21 | }
22 | }
23 |
24 | [Fact]
25 | public void Deserialize()
26 | {
27 | {
28 | var v = KubernetesJson.Deserialize("1234");
29 | Assert.Equal("1234", v.Value);
30 | }
31 |
32 | {
33 | var v = KubernetesJson.Deserialize("\"12%\"");
34 | Assert.Equal("12%", v.Value);
35 | }
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/ItemsEnumTests.cs:
--------------------------------------------------------------------------------
1 | using k8s.Models;
2 | using Xunit;
3 |
4 | namespace k8s.Tests;
5 |
6 | public class ItemsEnumTests
7 | {
8 | [Fact]
9 | public void EnsureIItemsEnumerable()
10 | {
11 | var pods = new V1PodList
12 | {
13 | Items = new[] { new V1Pod() },
14 | };
15 |
16 | // ensure no sytax err
17 | foreach (var pod in pods)
18 | {
19 | Assert.NotNull(pod);
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/KubernetesClient.Tests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | false
4 | k8s.Tests
5 | net8.0;net9.0
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | runtime; build; native; contentfiles; analyzers; buildtransitive
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/Mock/MockWebSocketBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.ObjectModel;
4 | using System.Net.WebSockets;
5 | using System.Security.Cryptography.X509Certificates;
6 | using System.Threading;
7 | using System.Threading.Tasks;
8 |
9 | namespace k8s.Tests.Mock
10 | {
11 | public class MockWebSocketBuilder : WebSocketBuilder
12 | {
13 | public Dictionary RequestHeaders { get; }
14 | = new Dictionary();
15 |
16 | public Collection Certificates { get; }
17 | = new Collection();
18 |
19 | public Uri Uri { get; private set; }
20 |
21 | public WebSocket PublicWebSocket => this.WebSocket;
22 |
23 | public override WebSocketBuilder AddClientCertificate(X509Certificate2 certificate)
24 | {
25 | this.Certificates.Add(certificate);
26 | return this;
27 | }
28 |
29 | public override Task BuildAndConnectAsync(Uri uri, CancellationToken cancellationToken)
30 | {
31 | this.Uri
32 | = uri;
33 |
34 | return Task.FromResult(this.PublicWebSocket);
35 | }
36 |
37 | public override WebSocketBuilder SetRequestHeader(string headerName, string headerValue)
38 | {
39 | this.RequestHeaders.Add(headerName, headerValue);
40 | return this;
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/Mock/Server/Startup.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.AspNetCore.Builder;
2 | using Microsoft.Extensions.DependencyInjection;
3 | using Microsoft.Extensions.Logging;
4 | using System;
5 |
6 | namespace k8s.Tests.Mock.Server
7 | {
8 | ///
9 | /// Startup logic for the KubeClient WebSockets test server.
10 | ///
11 | public class Startup
12 | {
13 | ///
14 | /// Initializes a new instance of the class.
15 | /// Create a new .
16 | ///
17 | public Startup()
18 | {
19 | }
20 |
21 | ///
22 | /// Configure application services.
23 | ///
24 | ///
25 | /// The service collection to configure.
26 | ///
27 | public static void ConfigureServices(IServiceCollection services)
28 | {
29 | if (services == null)
30 | {
31 | throw new ArgumentNullException(nameof(services));
32 | }
33 |
34 | services.AddLogging(logging =>
35 | {
36 | logging.ClearProviders(); // Logger provider will be added by the calling test.
37 | });
38 | services.AddMvc(opt => opt.EnableEndpointRouting = false);
39 | }
40 |
41 | ///
42 | /// Configure the application pipeline.
43 | ///
44 | ///
45 | /// The application pipeline builder.
46 | ///
47 | public static void Configure(IApplicationBuilder app)
48 | {
49 | app.UseWebSockets(new WebSocketOptions
50 | {
51 | KeepAliveInterval = TimeSpan.FromSeconds(5),
52 | });
53 | app.UseMvc();
54 | }
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/OperatingSystemDependentFactAttribute.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 | using Xunit;
3 |
4 | namespace k8s.Tests
5 | {
6 | public class OperatingSystemDependentFactAttribute : FactAttribute
7 | {
8 | public OperatingSystems Include { get; set; } = OperatingSystems.Linux | OperatingSystems.Windows | OperatingSystems.OSX;
9 | public OperatingSystems Exclude { get; set; }
10 |
11 | public override string Skip
12 | {
13 | get => IsOS(Include) && !IsOS(Exclude) ? null : "Not compatible with current OS";
14 | set { }
15 | }
16 |
17 | private bool IsOS(OperatingSystems operatingSystems)
18 | {
19 | if (operatingSystems.HasFlag(OperatingSystems.Linux) && RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
20 | {
21 | return true;
22 | }
23 |
24 | if (operatingSystems.HasFlag(OperatingSystems.Windows) && RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
25 | {
26 | return true;
27 | }
28 |
29 | if (operatingSystems.HasFlag(OperatingSystems.OSX) && RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
30 | {
31 | return true;
32 | }
33 |
34 | return false;
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/OperatingSystems.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace k8s.Tests
4 | {
5 | [Flags]
6 | public enum OperatingSystems
7 | {
8 | /// Windows operating system.
9 | Windows = 1,
10 |
11 | /// Linux operating system.
12 | Linux = 2,
13 |
14 | /// OSX operating system.
15 | OSX = 4,
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/TaskAssert.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Threading.Tasks;
3 | using Xunit;
4 |
5 | namespace k8s.Tests
6 | {
7 | internal static class TaskAssert
8 | {
9 | public static void NotCompleted(Task task, string message = "Task should not be completed")
10 | {
11 | Assert.False(task.IsCompleted, message);
12 | }
13 |
14 | public static async Task Completed(Task task, TimeSpan timeout, string message = "Task timed out")
15 | {
16 | var timeoutTask = Task.Delay(
17 | TimeSpan.FromMilliseconds(1000));
18 |
19 | var completedTask = await Task.WhenAny(task, timeoutTask).ConfigureAwait(false);
20 | Assert.True(ReferenceEquals(task, completedTask), message);
21 |
22 | await completedTask.ConfigureAwait(false);
23 | }
24 |
25 | public static async Task Completed(Task task, TimeSpan timeout, string message = "Task timed out")
26 | {
27 | var timeoutTask = Task.Delay(TimeSpan.FromMilliseconds(1000)).ContinueWith(completedTimeoutTask => default(T));
28 |
29 | // Value is never returned, but we need a task of the same result type in order to use Task.WhenAny.
30 |
31 | var completedTask = await Task.WhenAny(task, timeoutTask).ConfigureAwait(false);
32 | Assert.True(ReferenceEquals(task, completedTask), message);
33 |
34 | return await completedTask.ConfigureAwait(false);
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/TokenFileAuthTests.cs:
--------------------------------------------------------------------------------
1 | using FluentAssertions;
2 | using k8s.Authentication;
3 | using System;
4 | using System.Threading;
5 | using System.Threading.Tasks;
6 | using Xunit;
7 |
8 | namespace k8s.Tests
9 | {
10 | public class TokenFileAuthTests
11 | {
12 | [Fact]
13 | public async Task TestToken()
14 | {
15 | var auth = new TokenFileAuth("assets/token1");
16 | var result = await auth.GetAuthenticationHeaderAsync(CancellationToken.None).ConfigureAwait(true);
17 | result.Scheme.Should().Be("Bearer");
18 | result.Parameter.Should().Be("token1");
19 |
20 | auth.TokenFile = "assets/token2";
21 | result = await auth.GetAuthenticationHeaderAsync(CancellationToken.None).ConfigureAwait(true);
22 | result.Scheme.Should().Be("Bearer");
23 | result.Parameter.Should().Be("token1");
24 |
25 | auth.TokenExpiresAt = DateTime.UtcNow.AddSeconds(-1);
26 | result = await auth.GetAuthenticationHeaderAsync(CancellationToken.None).ConfigureAwait(true);
27 | result.Scheme.Should().Be("Bearer");
28 | result.Parameter.Should().Be("token2");
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/UtilityTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using Xunit;
4 |
5 | namespace k8s.Tests
6 | {
7 | public class UtilityTests
8 | {
9 | [Fact]
10 | public void TestQueryStringUtilities()
11 | {
12 | var sb = new StringBuilder();
13 | Assert.Throws(() => Utilities.AddQueryParameter(null, "key", "value"));
14 | Assert.Throws(() => Utilities.AddQueryParameter(sb, null, "value"));
15 | Assert.Throws(() => Utilities.AddQueryParameter(sb, "", "value"));
16 |
17 | Utilities.AddQueryParameter(sb, "key", "value");
18 | Utilities.AddQueryParameter(sb, "key", "a=b");
19 | Utilities.AddQueryParameter(sb, "+key", null);
20 | Utilities.AddQueryParameter(sb, "ekey", "");
21 | Assert.Equal("?key=value&key=a%3Db&%2Bkey=&ekey=", sb.ToString());
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/ca-bundle-intermediate.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIDDTCCAfWgAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwFTETMBEGA1UEAwwKa3Vi
3 | ZXJuZXRlczAeFw0xOTAzMDMxNzA4MDlaFw0yOTAyMjgxNzA4MDlaMBYxFDASBgNV
4 | BAMMC2V0Y2hhbmctdWI1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA
5 | x1Tp7Da3NbjdHmYdYZ/GNpCRGvFFap7EG1pokhfILKSbPusqiO9wnKDE4Afdn/ZE
6 | CQV0Whwtox3jczBOIRy+P6FvlPyhApUpynVTwgCiuhTM+thgODgpe6GXmVlVJGvv
7 | AoLw7CMndB5sMs5HH+qA2U1q4VFI/csr3/yeKzWBik3dZVoh04sI9WTVL+bl/1X5
8 | 0dl5qrqkYiDx8ycAHyOnl8dhJW+RGl67HiliuUeSq6vwsfv9rh3TP9wHVF1PXFJp
9 | WfXy4WbLmuld5wxXnQVO2g51jqfqN9fD8FHIkae1IkO/PUTucloNlLiFsragQOTD
10 | RVSP+TV3gshATBs2MMVXMwIDAQABo2YwZDAdBgNVHQ4EFgQU/3w9AR2cnEepWH4E
11 | 8a1xLZAnjykwHwYDVR0jBBgwFoAULs/lzct8CGvVdIiq4t9T4idu5OwwEgYDVR0T
12 | AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQADggEB
13 | AKw741V1wszIthHBV8dvCyQoyozBJuAo4IHbiiFmzuiQuyshMcX+Qs9a+g6OG5d1
14 | UbwFfUlqzmZQcbcR/Jc6wMz3wO6Hoy5pS3w/FR2UMGR39o95/7XCkTIOwCqau6Pw
15 | dpgvbnaiqPFPqD3ohdUuVRcXG3va5AmKTsUn7m+lR/93/qptt+SUVp6jwnbGcwoB
16 | s3u2XXx5s1M7tqqj3tAEOPCKlohS6mQ4X3wulgpZ1XpJ0WTvcvoPXEtA56k7vX3a
17 | 4E6x66LZCFA2ZR/5COv5D055AhrihKL8kbAutxhfA27SJ/MGowzmTT7kVQha3Su3
18 | aoOYZgcUww+SkRSGVrtgMgQ=
19 | -----END CERTIFICATE-----
20 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/ca-bundle-root.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIDEDCCAfigAwIBAgIJAJpb9irKg2JjMA0GCSqGSIb3DQEBCwUAMBUxEzARBgNV
3 | BAMMCmt1YmVybmV0ZXMwHhcNMTkwMzAzMDAyMTI3WhcNMzkwMjI2MDAyMTI3WjAV
4 | MRMwEQYDVQQDDAprdWJlcm5ldGVzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
5 | CgKCAQEAuoK+Na+LyKIipmftBw4Y+Z19g8yv6Y+dYt6KlBg24XHNA0v1cMwtOCDF
6 | Mlm4rsD7Jd5UO6ugdk3fxEvGGhmzWTXSBRUWcTbScAM49mALBFkCvNTPK2vVhk7P
7 | im2QQl8a5vjYz8HLKJTb/O+0q+Kktpd7XTaU2U7ZebiLVs5bvNbb3ZDtIjAARY9S
8 | alZ4hOzuVNaSX9MBRqTWq3HuKwDiVTT3dan/ABoU8NdedPfIbyY48wiQgjEYb64g
9 | 3geYpArLQeffo8fmhUEPRR/1WrfvYvvm8sV8jT+rqxITKJ5Vo5kpZUpomDOtGVMS
10 | gGAle6mcTrqlrsCFc4gFRRoHiH1ODQIDAQABo2MwYTAdBgNVHQ4EFgQULs/lzct8
11 | CGvVdIiq4t9T4idu5OwwHwYDVR0jBBgwFoAULs/lzct8CGvVdIiq4t9T4idu5Oww
12 | DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQELBQAD
13 | ggEBAFMq5z4OoaIhqx/i/btpVLRnQDcpDwdUurE0iNPz3bgOI5QiIe95oUwXSFQL
14 | ciECvObfMmiVuz+p7ND5eNdxYR4hlq1W1PYcgRQgusXCC4Xd/XAGaLZXzH3SBrmp
15 | bs5sfokhXKNccsnQu5Ya3JRkALxxUJ+DcOn+vi9gmEAzi+nXbyqUjIhSD5nygClX
16 | 0aSKbvhUmXyaJpUH0i7dSxWP3LqCDjtru/5ejNtB097dNcyF8js3Yuk3hwqyegQx
17 | ELn4c/TKPL9L8vE7tJg/M78DPAvRCiuwl0HQcasBE2AX0wdpY0UeXsNDyzUf/2WF
18 | fHY4DnuBdeVdHtl1yPlXmQkMoQM=
19 | -----END CERTIFICATE-----
20 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/ca-data.txt:
--------------------------------------------------------------------------------
1 | LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURERENDQWZTZ0F3SUJBZ0lSQUo5ZCtLeThkTDJVSzRjdXplMmo2WnN3RFFZSktvWklodmNOQVFFTEJRQXcKTHpFdE1Dc0dBMVVFQXhNa1lXRTBZVFV3T0RZdE0yVm1aaTAwWWpCa0xUbGxORGt0WmpNeVpXWXpabUpqWWpNNApNQjRYRFRFM01ESXlOakExTURRek5Gb1hEVEl5TURJeU5UQTFNRFF6TkZvd0x6RXRNQ3NHQTFVRUF4TWtZV0UwCllUVXdPRFl0TTJWbVppMDBZakJrTFRsbE5Ea3Raak15WldZelptSmpZak00TUlJQklqQU5CZ2txaGtpRzl3MEIKQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBM2dkandhdHNsdCsvQVpqV3hmbkNQeGZqMzNHUUxlOU00VU42VmEwRQpKd0FYL2R3L1ZVa0dvVjlDc3NKRUZMdEdTUnM2K2h0RTEvOUN3ak1USDh2WExKcURHTE9KdFQ5dW9sR2c2Q2k1ClBKNDNKelVLWmJlYVE4Z3hhZndzQjdQU05vTTJOYzROVm9lZzBVTUw0bndGeEhXeTNYWHlFZ0QxTWxTUnVrb3oKTTNoRUVxUjJNVFdrNm9KK3VJNFF4WVZWMnZuWXdXaEJwUDlDR3RWUTlyUW9MVFowcmFpOCtDYURBMVltTWRhbQpRYUVPdURlSFRqU2FYM2dyR0FBVVFWNWl6MC9qVVBuK3lJNm1iV0trbzFzNytPY1dZR2F1aDFaMzFYSjJsc0RTCnU4a3F0d215UEcyUVl2aUQ4YjNOWFAyY0dRK2EwZlpRZnBrbTF0U3IxQnhhaXdJREFRQUJveU13SVRBT0JnTlYKSFE4QkFmOEVCQU1DQWdRd0R3WURWUjBUQVFIL0JBVXdBd0VCL3pBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQVFFQQpuVzFXVXlLbVJ0TlNzU1VzVFBSUnhFRzhhek9kdjdYeUhRL0R5VWNqWm9rUEJVVHY4VjdvNG96RHgyVHV6UEdYCmZ2YlMvT2g0VDd6ZlYxdjJadmU3dTBxelNiRTl5OGpsaDNxYXJEcEd5ZmlTamwycmhIOFBmay9sZGR0VFpVL04KSkVtYW5ReGl6R20xV2pCSklRSE5LZENneVIwN3A1c0MwNnR3K25YUytla1MxMlBUTG45WjBuRDBKVDdQSzRXQgpQc3ZXeDVXN0w5dnJIdVN5SGRSTkt5eEEvbWI1WHdXMDBkZUpmaHZub0p3ZWRYNDVKZVRiME5MczUzaURqVEU1CnRpdU03Z1RVSjlCcGZTL0gvYSt2SmovVWQ2bHM0QndrWmpUNHNhOTA1bnNzdnRqamlwZ1N5a0QzVkxCQ3VueTkKd1NnbE1vSnZNWmg0bC9FVFJPeFE3Zz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
2 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/ca.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIC5zCCAc+gAwIBAgIBATANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQDEwptaW5p
3 | a3ViZUNBMB4XDTE3MDcyNDA1NDExNloXDTI3MDcyMjA1NDExNlowFTETMBEGA1UE
4 | AxMKbWluaWt1YmVDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMfj
5 | J9bJarUsN5Ynt/sbDFQQLp6BeHPXOcUdbNan1YbXdFGN8qLKkkQz0YY1hcVGrXdj
6 | 3vd2s8x9XlOyQPZ1SX4vJa5x/67BzFdxbCLg6jBYAisGvYu0hV4jvhHYOZH8sWUp
7 | 6n+gPm5c3J8gjqAmM0VwpvtG9HBIr1MWQ4HSTCBVoPvuG9TkOyxrB9RCha16hG7j
8 | B3m9XNEkRVl1xvW6wkeTO4n5cFSoDG0bfCnnjf0oz+pf0yJoSHbl/f2jI/rggMft
9 | 0R0LJfqdGlNCKCuN4g0jMmf26313oe+7i8uU4ut9iM1OBv6vD+xy115DGYG7EQIy
10 | lC1rd+gNlGQSxDafAb8CAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgKkMB0GA1UdJQQW
11 | MBQGCCsGAQUFBwMCBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
12 | DQEBCwUAA4IBAQAnXDZUdfC22zyFpZ+Rez3tyk9SqpOeiN1xGirZ5obDgvOS9vSR
13 | GLrsdN4UtXfGpKeMNQJV4e9YDz1ehLd1MK1BoxDVZHB0Sm2QxuyA4EyPfpHH9zaY
14 | qoRgDeUKBmCteLLcY3ukOzGf915j+lWQHv+tk52gvHfxvRyEuawSxSnowkGGFY9R
15 | 6AQ2cFm7G3SdygRWVXT1hk5hVQXvBY9DNU1YNvN0qWE6ss5RHJ/cxHFWtrdcr86K
16 | DqW9Ylr1l2iwkWpnXR4OMK3ZFjwX/qi11Z8eMDOi+0FxZ/6BkGQxe7X6D2GjCZ3r
17 | Lfbj0HBpynkd6lfLmIWgEzGYxrQjvczbAKBD
18 | -----END CERTIFICATE-----
19 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/ca2.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIC3zCCAcegAwIBAgIQWNOfSGBRn4EUcsj7E1UN8zANBgkqhkiG9w0BAQsFADAZ
3 | MRcwFQYDVQQKEw5EYXZpZCBPcmJlbGlhbjAeFw0xODA2MDgxMjI2MDBaFw0yMTA1
4 | MjMxMjI2MDBaMBkxFzAVBgNVBAoTDkRhdmlkIE9yYmVsaWFuMIIBIjANBgkqhkiG
5 | 9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnXGK1ZHqF4fhO3WOtlo5kqVYHHYTasNmzbQh
6 | MJ0IHiFrCVNi6apohleHi0IlzVFCQY5+yab2Lz7J2qcadRVWLlfhskMx4hbSD+eX
7 | H9MDcnV1k4AyFz+9I+dL4rb5DPcK9vNQF0KXtdpaq4qVs+IoRR4Ck00yvzLmOMTs
8 | YvFVjW6XgKPR+y89y8iykW2puiJ/y6DLKlP+2HDGGEI07C+4Tkxps6uRkPz6ySVb
9 | 6mhJ6P/+8WmuMc0Ur1kNgA0GEUTFYlRNuF0nNjBvncGBUwOWAUNbsYQgElaqXJKe
10 | XZ6M44+oBvRsCsnf7j3hfKti4u/Qy9nDejJ/15R6I6A5JdYOxwIDAQABoyMwITAO
11 | BgNVHQ8BAf8EBAMCAqwwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC
12 | AQEAU2Rp4T7iWomEsCC8nrQPXh/6AlVnfb/vhC7aCq+g6CF+LvksfM3Uj+JLQ5rM
13 | QNavSXowqe11vNb1Qu7LcQT5ff76XEoK0dKA8uMs60wUkHttfPzXM522rdv+i8EF
14 | QwVirN85W5i2q669MQ2BeJ37gQ6vQAOLvHXTuspDo1qrfT3zkeGiLEXRM4k4d6OT
15 | BnZNYvfdTTZX7OlvHfw5hdcRtoOTBmTAh+UKJvOUIQ2g/Mp2VBxNNC5zhJHTwEXj
16 | ssHyR24e9+GODLviep2H1uB+mHZQ5Yvzxxlkz8NTDx+mUmBSF1gGuDNdmKrCrP92
17 | bJZY0LcRrXX0aqPymVZrINDvtA==
18 | -----END CERTIFICATE-----
19 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/client-certificate-data.txt:
--------------------------------------------------------------------------------
1 | LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURrVENDQW5tZ0F3SUJBZ0lVTzlVTkdpbHhmSHpMbVJXcWU2dVMyRVZ1NVhVd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1FURUxNQWtHQTFVRUJoTUNWVk14RURBT0JnTlZCQWdUQjFKbFpHMXZibVF4Q3pBSkJnTlZCQWNUQWxkQgpNUk13RVFZRFZRUURFd3ByZFdKbGNtNWxkR1Z6TUNBWERURTRNVEl3T0RBNU5URXdNRm9ZRHpJeE1UZ3hNVEUwCk1EazFNVEF3V2pCQk1Rc3dDUVlEVlFRR0V3SlZVekVRTUE0R0ExVUVDQk1IVW1Wa2JXOXVaREVMTUFrR0ExVUUKQnhNQ1YwRXhFekFSQmdOVkJBTVRDbXQxWW1WeWJtVjBaWE13Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQgpEd0F3Z2dFS0FvSUJBUUM4WkVRS296SE8zOExmRzRpcHFYWnRLTzNxSENjL1Z1WjUxWnZSeWJuTnpCYU5iMk9oClM0cU1nNDF6cFdzL3dMQnk4ZndPclpoOHpHb28wbHllQXVCSlBPWFc5SmswMmhOc1Y3ZHBqYXBZWFMrSXJvN04KcUxhWDB5amQxWWllSWFlb3NtV2xib2ZpcDVzS3dzVUI3bGREeXJpQklBYTEwNlhhTng5ZG82UEh1TDNibStldwpiaWRoRTlNUFRHY2V5WW9rZ3pNbGppanordk0yUnN5Z05ncmR4VDhROC9GRER2ZndTRmZUaEZlYXIzckQvRkJGCmVYb0Y5MHp6cG1aZlphTDlyZ2NjQ0pzQ2JSZlpiellVVERRVHo2dStaUVhUdGlrbVMvQ3d2d0hXa0w3bGhQNXYKQU0yVFpETEJhQXQwOU14dGlORFNWaFFTWVR2QWpKRmU4SzJoQWdNQkFBR2pmekI5TUE0R0ExVWREd0VCL3dRRQpBd0lGb0RBZEJnTlZIU1VFRmpBVUJnZ3JCZ0VGQlFjREFRWUlLd1lCQlFVSEF3SXdEQVlEVlIwVEFRSC9CQUl3CkFEQWRCZ05WSFE0RUZnUVVuQmo0T3Y3MnFlWWJ5YjVYSHJma1pkazd6VUF3SHdZRFZSMGpCQmd3Rm9BVUxwemQKRlplYkR6N0RmZUNkZkJqNmNkUWJmNk13RFFZSktvWklodmNOQVFFTEJRQURnZ0VCQU1CL1RDaElEbTNkeDA4SApJeXlFS2dYUHh1d3A1cTB5QkFoT0pUS1JOVXNpayt6ZVUyUGpibnV0M3B1WnBENkZoTGFKQUZPbTdsMHhkNU1ZCkFZOVloSy9wa1U3Rmw1TFg0MitxQzRqK05JdGhBbFM5clNtNkRvNlN1b3JRcjdNajErY0syTjFkZHBtRWZya3kKZXZnMm02aFB5YTFlV0hNanVCd250bkJmV2EzWHBWMWVGZVBvd21zY3R6UmRJYUh3WDM3Yit3c2JmbkppczRvTgo2bHk0THBQb2xtYld3ZTRnaEtPWXNuL3lMT3FrUGJMZVpLeU5yaWJpSGhSQTM0NUVHUGJleXNmSlNIWWFqMnBaCmE0VmRTRFhnT2JlM3Vtdk9keXVEaGl5RFJ3TFozbVJLWlpIR0lzZC9ORzRncWo3a0gzV2N2Wm5mSkVHMXY2cG0KQTZFYTJiRT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/client.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIIDbjCCAlagAwIBAgIJAJD2bN6nz4ieMA0GCSqGSIb3DQEBCwUAMEwxCzAJBgNV
3 | BAYTAlVTMQswCQYDVQQIDAJXQTENMAsGA1UEBwwEVGVzdDEhMB8GA1UECgwYSW50
4 | ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMB4XDTE3MDcyNzA0NTEyNloXDTE4MDcyNzA0
5 | NTEyNlowTDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMQ0wCwYDVQQHDARUZXN0
6 | MSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3
7 | DQEBAQUAA4IBDwAwggEKAoIBAQDG8khxm/q6ls7TTKlKtTJgiPh6Gh7w1dCJG04/
8 | hyKuXMpx1WM0i943/M51k/X9XTuHgCOB/s191yBpNa6pHYgtuQGnzoMdHbRayggH
9 | 3i9x9jwEaf6RXFIuedRANzih+pVlDkXJftebE/YJwoOWes9SBPKqPOaGrC2A0Nqc
10 | s0iiZ/4oil3cXQYyzakwKQ9Mhb6M3Uw5OlfUCJXfAjsg5AIgrtYy//tXu3Cz+zIn
11 | tGvA3iWRIJfpCOziR3mMQc9GnFSeUHZCu/bFPCbc5yQ2Jy5Pm1y0coo/iPTEOw10
12 | RYXocr54lr854rtihHvKat5c/bkJQjpr8Mgy8qeVbAXzVtgRAgMBAAGjUzBRMB0G
13 | A1UdDgQWBBR9trLzkcB5I17ZGBeGhcjX8Ae5GTAfBgNVHSMEGDAWgBR9trLzkcB5
14 | I17ZGBeGhcjX8Ae5GTAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IB
15 | AQCXmgQLziUsWh0jDX/LhqwQxIM2YZDm8+K60my9gnWFv9B6OEvj3gilB69B0tuP
16 | YaJcpWhhzO+/pE8vxOBGQz731M7Er3TGpTrmBD/5bj9NJ71u0FxYjVA8lwbaQced
17 | l8bskTBAAiEZTzEEfdBHcHJXvpzLcnRZ1uNin3EYyyfl5dsZyHfyHUtMiMqzuEFP
18 | 8gusgANC3s0to41mZ6S3YJB/TcVKarFAYBg7FYQbIn2+qQg6B6itcZ8FzquffPDO
19 | 7od/iwL7Chh/AkrGQcRlHPZTzsDlpat2+0zHBYAVYVbuQMNaCD3IRh80Ufi+DpxL
20 | osKY7Mkcwj1Nmoz4JPoL0wYI
21 | -----END CERTIFICATE-----
22 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/client.key:
--------------------------------------------------------------------------------
1 | -----BEGIN PRIVATE KEY-----
2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDG8khxm/q6ls7T
3 | TKlKtTJgiPh6Gh7w1dCJG04/hyKuXMpx1WM0i943/M51k/X9XTuHgCOB/s191yBp
4 | Na6pHYgtuQGnzoMdHbRayggH3i9x9jwEaf6RXFIuedRANzih+pVlDkXJftebE/YJ
5 | woOWes9SBPKqPOaGrC2A0Nqcs0iiZ/4oil3cXQYyzakwKQ9Mhb6M3Uw5OlfUCJXf
6 | Ajsg5AIgrtYy//tXu3Cz+zIntGvA3iWRIJfpCOziR3mMQc9GnFSeUHZCu/bFPCbc
7 | 5yQ2Jy5Pm1y0coo/iPTEOw10RYXocr54lr854rtihHvKat5c/bkJQjpr8Mgy8qeV
8 | bAXzVtgRAgMBAAECggEASrptPcdyOa42CCaOnJJNVvd8JhkzsBEQYL/R94jiHQ6b
9 | uICH4A/9q5gZUQ7/4min2LDoJYc5VuB8uyg/8CQ4p7wLhCXNGB21RjkHJTVvKuZs
10 | Cthpl95OvEhk0q4rZqSCg1AGJLaxc/3eeDIJTXfZ8hwLrqhriwCXowBQbXXmfaHa
11 | YiOodBFs+B55si2NiO971wiz7jeFYYs/tEiT9wS6nvq0t2omSi7e8ryL103Lb1ge
12 | SAelzS4ZMCf/Xt+kYz+UeC51RlCshHt9sif0Jgst84EVqX5by2PzSUrQu6YPNLrn
13 | 3WulO6a7oqHYfF8wV4ARD89SNRyWcF/Xh+vjPg538QKBgQDx5W/x+F/Nt+f0tlDl
14 | ZeSoB/wWo2yQx0gK98R66M3qUtnoeWC+SSj15z1WPT+MfD+B2haytiFP1+uAveI/
15 | hup1oJMddciTcLMfc13s7luXe+OLMCxCwJTrgaSZeD79dUKKzHv2yU4v01gJFlMq
16 | GnkAzUxolvb9sVzgFuCy7agHnQKBgQDSi8XxDoNhv9HAKHJDhQ1g3mmGIPPP4M72
17 | v8MxO5AXVCVcL3VFGj+7H6Z3CJuiE7diJVBSPMun/6q1xgMZNUe9EjIjCdmEKMOz
18 | Nm/5P6Dea1Gktd5gb6NB9GTpE3JqwxhxkM0VNv/k8rCp6+4Oz1d8uF+p6jPwNEC5
19 | Z9vlge/aBQKBgQCkv0nl9+5v8rAVF9Ky2hnIY1/Kn1VCqackaSk1OLd9vx3QWlKM
20 | ZtFx4SMCSEauzLSIINvSrX60nW80yJ59+8pVgJ6RsvV/jYNBiVZQFurkmikYVB/g
21 | +r6yQyKyr5XfE+zVEX3gT6xjoEJWNhFAHLWK2UgP97mSgSirKomw83G8dQKBgHWl
22 | fHlx7p/UG1QQRajM0+jo3nYAO7xQldTy2hLMgXtHnYihTBnMzQe2a8HfoXczJSlG
23 | SFdreTDqf20Ks/iF+QwA+trxSgW68X9WT8Mqdq1RslEi/ptMRiE4eppyL2DQmvv6
24 | OV49WUeJBIYuOtszqGMccvfy0grKZ9Ax5IGd1XQxAoGAW7DObS33nO9/arcEg+yK
25 | H0cOSP1h/8v4k4M4gorfuXfi6Xkegt5PaWUf7tJGDon5ArzZsCNRq5rdBMNtA4an
26 | NbMlanRzfBuBqHYo/X8OgqThhn8Uwg/oY778qHEH+WaJdSiNg5TboDPKUyEBNRKA
27 | suoE9MAZsAaIj4YP0RnMLk8=
28 | -----END PRIVATE KEY-----
29 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/elliptic-client.key:
--------------------------------------------------------------------------------
1 | -----BEGIN EC PRIVATE KEY-----
2 | MIHcAgEBBEIAgsWy6kCIIGCuedLfU0zqElm7H9VwpzKWK3ITjtG8QPEJfw0vEqVL
3 | Ly4aVsZ8dH7lP6Ykz90lAxLPwMJTL7fht9qgBwYFK4EEACOhgYkDgYYABADJVVPm
4 | PwRHH96uMREAJMrznGswswqMerCY8wqGjAMDHCWE/bvbGROhRzZM5WNuI/C7d5oV
5 | YpagbVVgIi3L4Jr+hgDuAmK4AExQYcZWVcPqLe/kv7i5xxAT2MJwuto7QJeR7ffh
6 | YzbpOXqgQBrJW2Fdgh/mTAKHrtP/nDOsioRWzxl2zQ==
7 | -----END EC PRIVATE KEY-----
8 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/elliptic.crt:
--------------------------------------------------------------------------------
1 | -----BEGIN CERTIFICATE-----
2 | MIICBTCCAWYCFDt3JLija7g4s9TNSFI8p9topHs4MAoGCCqGSM49BAMCMEExCzAJ
3 | BgNVBAYTAlVTMQswCQYDVQQIDAJXQTEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UE
4 | CgwKS3ViZXJuZXRlczAeFw0yMTEwMjAwMDA2MDdaFw0yMTExMTkwMDA2MDdaMEEx
5 | CzAJBgNVBAYTAlVTMQswCQYDVQQIDAJXQTEQMA4GA1UEBwwHU2VhdHRsZTETMBEG
6 | A1UECgwKS3ViZXJuZXRlczCBmzAQBgcqhkjOPQIBBgUrgQQAIwOBhgAEAMlVU+Y/
7 | BEcf3q4xEQAkyvOcazCzCox6sJjzCoaMAwMcJYT9u9sZE6FHNkzlY24j8Lt3mhVi
8 | lqBtVWAiLcvgmv6GAO4CYrgATFBhxlZVw+ot7+S/uLnHEBPYwnC62jtAl5Ht9+Fj
9 | Nuk5eqBAGslbYV2CH+ZMAoeu0/+cM6yKhFbPGXbNMAoGCCqGSM49BAMCA4GMADCB
10 | iAJCAL8VpSq+rs+h/BmNu/z0KCWsfQv7zOZOTOqYJ/5NzaBlEhejj8ktfvWTJ3SR
11 | jHIMWdK+SAJva1v1tzaTi5z7KiYuAkIApijJv9yr/Ex4okg6zB/LgsTio67fm4DG
12 | 9Yrw9KVtUbskcYjcpLVbT78cQjeDyDg1dYtHpdl7Z7p+jga/nPb/HKU=
13 | -----END CERTIFICATE-----
14 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/gcloud-config-helper.json:
--------------------------------------------------------------------------------
1 | {
2 | "configuration": {
3 | "active_configuration": "default",
4 | "properties": {
5 | "compute": {
6 | "region": "us-east1",
7 | "zone": "us-east1-b"
8 | },
9 | "core": {
10 | "account": "some@account.io",
11 | "disable_usage_reporting": "True",
12 | "project": "fe-astakhov"
13 | }
14 | }
15 | },
16 | "credential": {
17 | "access_token": "ACCESS-TOKEN",
18 | "token_expiry": "2020-03-20T07:09:20Z"
19 | },
20 | "sentinels": {
21 | "config_sentinel": "C:\\Users\\Andrew\\AppData\\Roaming\\gcloud\\config_sentinel"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/kubeconfig.as-user-extra.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | clusters:
3 | - cluster:
4 | certificate-authority: assets/ca.crt
5 | server: https://10.20.0.56:8443
6 | name: minikube
7 | contexts:
8 | - context:
9 | cluster: minikube
10 | user: minikube
11 | name: minikube
12 | current-context: minikube
13 | kind: Config
14 | preferences: {}
15 | users:
16 | - name: minikube
17 | user:
18 | as-user-extra: {}
19 | client-certificate: assets/client.crt
20 | client-key: assets/client.key
21 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/kubeconfig.cluster-extensions.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | clusters:
3 | - cluster:
4 | extensions:
5 | - extension:
6 | last-update: Wed, 27 Jan 2021 11:44:41 UTC
7 | provider: minikube.sigs.k8s.io
8 | version: v1.17.0
9 | name: cluster_info
10 | server: https://192.168.49.2:8443
11 | name: minikube
12 | contexts:
13 | - context:
14 | cluster: minikube
15 | extensions:
16 | - extension:
17 | last-update: Wed, 27 Jan 2021 11:44:41 UTC
18 | provider: minikube.sigs.k8s.io
19 | version: v1.17.0
20 | name: context_info
21 | namespace: default
22 | user: minikube
23 | name: minikube
24 | current-context: minikube
25 | kind: Config
26 | preferences: {}
27 | users:
28 | - name: minikube
29 | user:
30 | password: secret
31 | username: admin
32 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/kubeconfig.cluster-missmatch.yml:
--------------------------------------------------------------------------------
1 | # Sample file based on https://kubernetes.io/docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig/
2 | # WARNING: File includes minor fixes
3 | ---
4 | current-context: federal-context
5 | apiVersion: v1
6 | clusters:
7 | - cluster:
8 | certificate-authority: path/to/my/cafile
9 | server: https://horse.org:4443
10 | name: bad-name-cluster
11 | contexts:
12 | - context:
13 | cluster: horse-cluster
14 | namespace: chisel-ns
15 | user: green-user
16 | name: federal-context
17 | kind: Config
18 | users:
19 | - name: green-user
20 | user:
21 | password: secret
22 | username: admin
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/kubeconfig.no-cluster.yml:
--------------------------------------------------------------------------------
1 | # Sample file based on https://kubernetes.io/docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig/
2 | # WARNING: File includes minor fixes
3 | ---
4 | current-context: federal-context
5 | apiVersion: v1
6 | contexts:
7 | - context:
8 | cluster: horse-cluster
9 | namespace: chisel-ns
10 | user: green-user
11 | name: federal-context
12 | kind: Config
13 | users:
14 | - name: green-user
15 | user:
16 | password: secret
17 | username: admin
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/kubeconfig.no-context-details.yml:
--------------------------------------------------------------------------------
1 | # Sample file based on https://kubernetes.io/docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig/
2 | # WARNING: File includes minor fixes
3 | ---
4 | current-context: federal-context
5 | apiVersion: v1
6 | clusters:
7 | - cluster:
8 | server: http://cow.org:8080
9 | name: cow-cluster
10 | - cluster:
11 | certificate-authority: assets/ca.crt
12 | server: https://horse.org:4443
13 | name: horse-cluster
14 | - cluster:
15 | insecure-skip-tls-verify: true
16 | server: https://pig.org:443
17 | name: pig-cluster
18 | contexts:
19 | - name: federal-context
20 | kind: Config
21 | users:
22 | - name: blue-user
23 | user:
24 | token: blue-token
25 | - name: green-user
26 | user:
27 | client-certificate: assets/client.crt
28 | client-key: assets/client.key
29 | - name: black-user
30 | user:
31 | token: black-token
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/kubeconfig.no-context.yml:
--------------------------------------------------------------------------------
1 | # Sample file based on https://kubernetes.io/docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig/
2 | # WARNING: File includes minor fixes
3 | ---
4 | current-context: federal-context
5 | apiVersion: v1
6 | clusters:
7 | - cluster:
8 | server: http://cow.org:8080
9 | name: cow-cluster
10 | - cluster:
11 | certificate-authority: assets/ca.crt
12 | server: https://horse.org:4443
13 | name: horse-cluster
14 | - cluster:
15 | insecure-skip-tls-verify: true
16 | server: https://pig.org:443
17 | name: pig-cluster
18 | kind: Config
19 | users:
20 | - name: blue-user
21 | user:
22 | token: blue-token
23 | - name: green-user
24 | user:
25 | client-certificate: assets/client.crt
26 | client-key: assets/client.key
27 | - name: black-user
28 | user:
29 | token: black-token
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/kubeconfig.no-credentials.yml:
--------------------------------------------------------------------------------
1 | # Sample file based on https://kubernetes.io/docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig/
2 | # WARNING: File includes minor fixes
3 | ---
4 | current-context: federal-context
5 | apiVersion: v1
6 | clusters:
7 | - cluster:
8 | certificate-authority: assets/ca.crt
9 | server: https://horse.org:4443
10 | name: horse-cluster
11 | contexts:
12 | - context:
13 | cluster: horse-cluster
14 | namespace: chisel-ns
15 | user: green-user
16 | name: federal-context
17 | kind: Config
18 | users:
19 | - name: green-user
20 | user:
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/kubeconfig.no-current-context.yml:
--------------------------------------------------------------------------------
1 | ---
2 | apiVersion: v1
3 | clusters:
4 | - cluster:
5 | certificate-authority: assets/ca.crt
6 | server: https://horse.org:4443
7 | name: horse-cluster
8 | contexts:
9 | - context:
10 | cluster: horse-cluster
11 | namespace: chisel-ns
12 | user: green-user
13 | name: federal-context
14 | kind: Config
15 | users:
16 | - name: green-user
17 | user:
18 | password: secret
19 | username: admin
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/kubeconfig.no-server.yml:
--------------------------------------------------------------------------------
1 | # Sample file based on https://kubernetes.io/docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig/
2 | # WARNING: File includes minor fixes
3 | ---
4 | current-context: federal-context
5 | apiVersion: v1
6 | clusters:
7 | - cluster:
8 | certificate-authority: path/to/my/cafile
9 | name: horse-cluster
10 | contexts:
11 | - context:
12 | cluster: horse-cluster
13 | namespace: chisel-ns
14 | user: green-user
15 | name: federal-context
16 | kind: Config
17 | users:
18 | - name: green-user
19 | user:
20 | password: secret
21 | username: admin
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/kubeconfig.no-user.yml:
--------------------------------------------------------------------------------
1 | ---
2 | current-context: federal-context
3 | apiVersion: v1
4 | clusters:
5 | - cluster:
6 | certificate-authority: assets/ca.crt
7 | server: https://horse.org:4443
8 | name: horse-cluster
9 | contexts:
10 | - context:
11 | cluster: horse-cluster
12 | namespace: chisel-ns
13 | name: federal-context
14 | kind: Config
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/kubeconfig.preferences-extensions.yml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Config
3 | preferences:
4 | colors: true
5 | extensions:
6 | - name: foo
7 | extension:
8 | foo: bar
9 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/kubeconfig.tls-no-skip.yml:
--------------------------------------------------------------------------------
1 | # Sample file based on https://kubernetes.io/docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig/
2 | # WARNING: File includes minor fixes
3 | ---
4 | current-context: federal-context
5 | apiVersion: v1
6 | clusters:
7 | - cluster:
8 | insecure-skip-tls-verify: false
9 | server: https://horse.org:443
10 | name: horse-cluster
11 | contexts:
12 | - context:
13 | cluster: horse-cluster
14 | namespace: chisel-ns
15 | user: green-user
16 | name: federal-context
17 | kind: Config
18 | users:
19 | - name: green-user
20 | user:
21 | password: secret
22 | username: admin
23 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/kubeconfig.tls-servername.yml:
--------------------------------------------------------------------------------
1 | # Sample file based on https://kubernetes.io/docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig/
2 | # WARNING: File includes minor fixes
3 | ---
4 | current-context: federal-context
5 | apiVersion: v1
6 | clusters:
7 | - cluster:
8 | server: https://horse.org:443
9 | tls-server-name: pony
10 | name: horse-cluster
11 | contexts:
12 | - context:
13 | cluster: horse-cluster
14 | namespace: chisel-ns
15 | user: green-user
16 | name: federal-context
17 | kind: Config
18 | users:
19 | - name: green-user
20 | user:
21 | password: secret
22 | username: admin
23 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/kubeconfig.tls-skip-http.yml:
--------------------------------------------------------------------------------
1 | ---
2 | current-context: federal-context
3 | apiVersion: v1
4 | clusters:
5 | - cluster:
6 | server: http://horse.org
7 | name: horse-cluster
8 | contexts:
9 | - context:
10 | cluster: horse-cluster
11 | namespace: chisel-ns
12 | user: green-user
13 | name: federal-context
14 | kind: Config
15 | users:
16 | - name: green-user
17 | user:
18 | password: secret
19 | username: admin
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/kubeconfig.tls-skip.yml:
--------------------------------------------------------------------------------
1 | # Sample file based on https://kubernetes.io/docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig/
2 | # WARNING: File includes minor fixes
3 | ---
4 | current-context: federal-context
5 | apiVersion: v1
6 | clusters:
7 | - cluster:
8 | insecure-skip-tls-verify: true
9 | server: https://horse.org:443
10 | name: horse-cluster
11 | contexts:
12 | - context:
13 | cluster: horse-cluster
14 | namespace: chisel-ns
15 | user: green-user
16 | name: federal-context
17 | kind: Config
18 | users:
19 | - name: green-user
20 | user:
21 | password: secret
22 | username: admin
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/kubeconfig.user-not-found.yml:
--------------------------------------------------------------------------------
1 | ---
2 | current-context: federal-context
3 | apiVersion: v1
4 | clusters:
5 | - cluster:
6 | certificate-authority: assets/ca.crt
7 | server: https://horse.org:4443
8 | name: horse-cluster
9 | contexts:
10 | - context:
11 | cluster: horse-cluster
12 | namespace: chisel-ns
13 | user: green-user
14 | name: federal-context
15 | kind: Config
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/kubeconfig.user-oidc.yml:
--------------------------------------------------------------------------------
1 | # Sample file based on https://kubernetes.io/docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig/
2 | # WARNING: File includes minor fixes
3 | ---
4 | current-context: federal-context
5 | apiVersion: v1
6 | clusters:
7 | - cluster:
8 | certificate-authority: assets/ca.crt
9 | server: https://horse.org:4443
10 | name: horse-cluster
11 | contexts:
12 | - context:
13 | cluster: horse-cluster
14 | namespace: chisel-ns
15 | user: green-user
16 | name: federal-context
17 | kind: Config
18 | users:
19 | - name: green-user
20 | user:
21 | auth-provider:
22 | config:
23 | client-id: CLIENT_ID
24 | client-secret: CLIENT_SECRET
25 | id-token: ID_TOKEN
26 | idp-issuer-url: IDP_ISSUER_URL
27 | refresh-token: REFRESH_TOKEN
28 | name: oidc
29 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/kubeconfig.user-pass.yml:
--------------------------------------------------------------------------------
1 | # Sample file based on https://kubernetes.io/docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig/
2 | # WARNING: File includes minor fixes
3 | ---
4 | current-context: federal-context
5 | apiVersion: v1
6 | clusters:
7 | - cluster:
8 | certificate-authority: assets/ca.crt
9 | server: https://horse.org:4443
10 | name: horse-cluster
11 | contexts:
12 | - context:
13 | cluster: horse-cluster
14 | namespace: chisel-ns
15 | user: green-user
16 | name: federal-context
17 | kind: Config
18 | users:
19 | - name: green-user
20 | user:
21 | password: secret
22 | username: admin
23 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/kubeconfig.wildcard-ipv4.yml:
--------------------------------------------------------------------------------
1 | # Sample file based on https://kubernetes.io/docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig/
2 | # WARNING: File includes minor fixes
3 | ---
4 | current-context: federal-context
5 | apiVersion: v1
6 | clusters:
7 | - cluster:
8 | server: https://0.0.0.0:443
9 | name: horse-cluster
10 | contexts:
11 | - context:
12 | cluster: horse-cluster
13 | namespace: chisel-ns
14 | user: green-user
15 | name: federal-context
16 | kind: Config
17 | users:
18 | - name: green-user
19 | user:
20 | password: secret
21 | username: admin
22 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/kubeconfig.wildcard-ipv6.yml:
--------------------------------------------------------------------------------
1 | # Sample file based on https://kubernetes.io/docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig/
2 | # WARNING: File includes minor fixes
3 | ---
4 | current-context: federal-context
5 | apiVersion: v1
6 | clusters:
7 | - cluster:
8 | server: https://[::]:443
9 | name: horse-cluster
10 | contexts:
11 | - context:
12 | cluster: horse-cluster
13 | namespace: chisel-ns
14 | user: green-user
15 | name: federal-context
16 | kind: Config
17 | users:
18 | - name: green-user
19 | user:
20 | password: secret
21 | username: admin
22 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/kubeconfig.wildcard-ipv6_2.yml:
--------------------------------------------------------------------------------
1 | # Sample file based on https://kubernetes.io/docs/tasks/access-application-cluster/authenticate-across-clusters-kubeconfig/
2 | # WARNING: File includes minor fixes
3 | ---
4 | current-context: federal-context
5 | apiVersion: v1
6 | clusters:
7 | - cluster:
8 | server: https://[0:0:0:0:0:0:0:0]:443
9 | name: horse-cluster
10 | contexts:
11 | - context:
12 | cluster: horse-cluster
13 | namespace: chisel-ns
14 | user: green-user
15 | name: federal-context
16 | kind: Config
17 | users:
18 | - name: green-user
19 | user:
20 | password: secret
21 | username: admin
22 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/mock-gcloud.cmd:
--------------------------------------------------------------------------------
1 | @echo off
2 | type %~dp0\gcloud-config-helper.json
3 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/mock-gcloud.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | SCRIPT=$(readlink -f "$0")
3 | SCRIPTPATH=$(dirname "$SCRIPT")
4 | OUTPUT_JSON=$SCRIPTPATH/gcloud-config-helper.json
5 | cat $OUTPUT_JSON
6 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/token1:
--------------------------------------------------------------------------------
1 | token1
2 |
--------------------------------------------------------------------------------
/tests/KubernetesClient.Tests/assets/token2:
--------------------------------------------------------------------------------
1 | token2
2 |
--------------------------------------------------------------------------------
/tests/SkipTestLogger/SkipTestLogger.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.VisualStudio.TestPlatform.ObjectModel;
2 | using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.IO;
6 |
7 | namespace k8s.E2E
8 | {
9 | // This TestLogger is to log test cases skipped by accident
10 | // when E2E test runs in github action
11 |
12 | [FriendlyName("SkipTestLogger")]
13 | [ExtensionUri("logger://Microsoft/TestPlatform/SkipTestLogger/v1")]
14 | public class SkipTestLogger : ITestLoggerWithParameters
15 | {
16 | public void Initialize(TestLoggerEvents events, Dictionary parameters)
17 | {
18 | if (parameters != null && parameters.TryGetValue("file", out var file))
19 | {
20 | InnerInitialize(events, file);
21 | }
22 | else
23 | {
24 | throw new ArgumentNullException("file", "log file path must be set");
25 | }
26 | }
27 |
28 | private static void InnerInitialize(TestLoggerEvents events, string file)
29 | {
30 | if (events == null)
31 | {
32 | throw new ArgumentNullException(nameof(events));
33 | }
34 |
35 | Console.WriteLine($"using {file} for skipped test case log");
36 | events.TestResult += (sender, args) =>
37 | {
38 | using (var w = File.AppendText(file))
39 | {
40 | if (args.Result.Outcome == TestOutcome.Skipped)
41 | {
42 | w.WriteLine(args.Result.DisplayName);
43 | }
44 | }
45 | };
46 | }
47 |
48 | public void Initialize(TestLoggerEvents events, string testRunDirectory)
49 | {
50 | InnerInitialize(events, Path.Combine(testRunDirectory, "skip.log"));
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/tests/SkipTestLogger/SkipTestLogger.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/version.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
3 | "version": "17.0",
4 | "publicReleaseRefSpec": [
5 | "^refs/heads/master$",
6 | "^refs/tags/v\\d+\\.\\d+\\.\\d+"
7 | ],
8 | "cloudBuild": {
9 | "setVersionVariables": false
10 | }
11 | }
12 |
--------------------------------------------------------------------------------