Giter VIP home page Giter VIP logo

kuber.jl's Introduction

Kuber

Build Status

A Julia Kubernetes Client.

An easy to use API to access Kubernetes clusters from Julia. The Kuber.ApiImpl.Kubernetes submodule has the complete set of low level APIs and entities.

Supported API Versions

Most of the low level APIs fit into a common usage pattern. Kuber.jl makes it possible to use all of them with only a few intuitive verb based APIs. Verbs act on entities. Entities can be identified by names or selector patterns, or otherwise can apply to all entities of that class. Verbs can take additional parameters, e.g. when creating or updating entities.

API and Entity naming convention follows the standard Kubernetes API and Model naming conventions.

Here are a few helpful resources:

  • Tutorial on using Kuber.jl.
  • Article on using metrics and custom metrics with Kuber.jl

Entities:

Any Kubernetes entity supported. APIs identify an entity by symbol named as per Kubernetes naming convention.

  • :Namespace
  • :Pod
  • :ReplicationController
  • :Service
  • :PersistentVolume
  • :Job
  • ...

Methods/Verbs:

Kubernetes APIs are mapped to these easy to use verbs, familiar to Julia users.

  • get: list or fetch entities
  • list: list entities
  • put!: create entities
  • update!: update existing entities
  • delete!: delete existing entities
  • sel: creates a label selector to use with other verbs

All verbs have the signature:

verb(ctx::KuberContext, T::Symbol, args...; kwargs...)

Kubernetes also provides efficient change notifications on resources via "watches". Certain entities have the special watch APIs defined for them and that can be invoked with the watch verb. The watch API accepts a Channel through which it streams events.

watch(ctx::KuberContext, T::Symbol, outstream::Channel, args...; kwargs...)

In addition, verbs like get and list also support watches, and those can be invoked as:

watch(ctx, verb, args...; kwargs...) do stream
    for event in stream
        # process event
    end
end

E.g.:

watch(ctx, list, :Pod; resource_version=19451) do stream
    for event in stream
        @info("got event", event)
    end
end

Helper methods:

A Kubernetes context can be manipulated with:

  • set_server: Set the API server location ("http://localhost:8001" if not set)
  • set_ns: Set the namespace to deal with (default namespace is not set)
  • set_retries: Set the number of times an API call should be retried on a retriable error (5 if not set) and whether all APIs should be retried (only non mutating APIs are retried by default)

Other convenience methods:

  • kuber_type: identify the Julia object corresponding to the Kubernetes specification
  • kuber_obj: instantiate a Julia object from for the supplied Kubernetes specification
  • Helper methods for accessing metrics

References:

kuber.jl's People

Contributors

krynju avatar logankilpatrick avatar mdpradeep avatar nkottary avatar omus avatar pankgeorg avatar tanmaykm avatar viralbshah avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kuber.jl's Issues

[Feature Request] Access to API in a pod

Hi, Thank you for developing this repo!

I'm wondering can I use Kuber.jl within a pod, and access the Kubernetes API? As far as I know, both Go and Python have client that can do so, like here.

This will be a great help!

Support watch APIs

Kuber.jl does not support invoking API watches that do long polling and return stream of events. It will be very useful to have a way to use those, instead of repeated polling. A related change is needed in Swagger.jl - JuliaComputing/Swagger.jl#41

Setting `PropagationPolicy`

We face the issue that deleting a Job does not delete the containing Pods.

We'd like to set the propagationPolicy to "Background". It seems that propagationPolicy is implemented in the ApiImpl, but I was not able to find a solution to set this Parameter by applying it to the ctx.client or so. What would be a possible way to do so?

Cannot re-use `KuberContext` after Internal Server Error

When the Kubernetes API server is not running KuberContext can get partially populated which can result in different error messages when retrying the same calls. This can be problematic in scenarios like the CI where a KuberContext could be re-used:

julia> using Kuber

julia> ctx = KuberContext()
Kubernetes namespace default at http://localhost:8001

julia> get(ctx, :Pod)
ERROR: Swagger.ApiException(500, "Internal Server Error", HTTP.Messages.Response:
"""
HTTP/1.1 500 Internal Server Error
Content-Type: text/plain; charset=utf-8
X-Content-Type-Options: nosniff
Date: Wed, 21 Apr 2021 13:53:44 GMT
Content-Length: 40
Connection: close

dial tcp 192.168.49.2:8443: i/o timeout
""")
Stacktrace:
 [1] exec(ctx::Swagger.Ctx)
   @ Swagger ~/.julia/packages/Swagger/4eKnR/src/client.jl:213
 [2] getCoreAPIVersions(_api::Kuber.Kubernetes.CoreApi; _mediaType::Nothing)
   @ Kuber.Kubernetes ~/.julia/packages/Kuber/UfXri/src/api/api_CoreApi.jl:17
 [3] getCoreAPIVersions
   @ ~/.julia/packages/Kuber/UfXri/src/api/api_CoreApi.jl:14 [inlined]
 [4] macro expansion
   @ ~/.julia/packages/Retry/vS1bg/src/repeat_try.jl:192 [inlined]
 [5] fetch_core_version(ctx::KuberContext; override::Nothing, verbose::Bool, max_tries::Int64)
   @ Kuber ~/.julia/packages/Kuber/UfXri/src/helpers.jl:162
 [6] set_api_versions!(ctx::KuberContext; override::Nothing, verbose::Bool, max_tries::Int64)
   @ Kuber ~/.julia/packages/Kuber/UfXri/src/helpers.jl:220
 [7] get(ctx::KuberContext, O::Symbol, apiversion::Nothing; label_selector::Nothing, namespace::String, max_tries::Int64)
   @ Kuber ~/.julia/packages/Kuber/UfXri/src/simpleapi.jl:90
 [8] get (repeats 2 times)
   @ ~/.julia/packages/Kuber/UfXri/src/simpleapi.jl:90 [inlined]
 [9] top-level scope
   @ REPL[3]:1

julia> get(ctx, :Pod)
ERROR: KeyError: key :Pod not found
Stacktrace:
 [1] getindex
   @ ./dict.jl:482 [inlined]
 [2] _get_apictx(ctx::KuberContext, O::Symbol, apiversion::Nothing)
   @ Kuber ~/.julia/packages/Kuber/UfXri/src/simpleapi.jl:17
 [3] get(ctx::KuberContext, O::Symbol, apiversion::Nothing; label_selector::Nothing, namespace::String, max_tries::Int64)
   @ Kuber ~/.julia/packages/Kuber/UfXri/src/simpleapi.jl:92
 [4] get (repeats 2 times)
   @ ~/.julia/packages/Kuber/UfXri/src/simpleapi.jl:90 [inlined]
 [5] top-level scope
   @ REPL[3]:1

Handle CRDs when generating code

Currently the following diff is required to successfully generate code when Custom Resource Definitions (CRDs) are present in swagger.json. Should we commit this diff or should we come up with a better way of handling these CRDs?

diff --git a/gen/gentypealiases.jl b/gen/gentypealiases.jl
index dd4f995..55bb219 100644
--- a/gen/gentypealiases.jl
+++ b/gen/gentypealiases.jl
@@ -9,6 +9,15 @@ const KuberTypeAliasesUnique = Dict{String,Vector{Pair{String,String}}}
 const BaseTypes = ("String", "Float64", "Float32", "Int", "Int64", "Int32", "Int16", "UInt", "UInt64", "UInt32", "UInt16", "DateTime", "Bool", "Nothing")
 const ModelPrefixes = ("IoK8sApimachineryPkgApis", "IoK8sApimachineryPkg", "IoK8sApi", "IoK8sKubeAggregatorPkgApis", "IoK8sApiextensionsApiserverPkgApis")
 
+const CrdModelnameApiMap = Dict{String,String}(
+    "OrgProjectcalicoCrdV1" => "CrdProjectcalicoOrgV1",
+    "ComJuliahubV1beta1" => "JuliahubComV1beta1",
+    "ComCoreosDatabaseEtcdV1beta2" => "EtcdDatabaseCoreosComV1beta2",
+    "ShKarpenterV1alpha5" => "KarpenterShV1alpha5",
+    "ComAmazonawsK8sCrdV1alpha1" => "CrdK8sAmazonawsComV1alpha1",
+    "AwsK8sVpcresourcesV1beta1" => "VpcresourcesK8sAwsV1beta1",
+)
+
 function get_swagger_ctx_call_return_type(fn_body)
     all_calls = findall(x->CSTParser.isbinarysyntax(x), fn_body.args)
     for nidx in all_calls
@@ -82,6 +91,14 @@ function kuberapitypes(file::String, aliases_set::KuberTypeAliasesSet)
 end
 
 function find_matching_api(sorted_apis::Vector{String}, model_name::String)
+    for modelpfx in keys(CrdModelnameApiMap)
+        if startswith(model_name, modelpfx)
+            api_pfx = CrdModelnameApiMap[modelpfx]
+            api_idx = findfirst(x->startswith(x, api_pfx), sorted_apis)
+            return (api_idx !== nothing) ? api_idx : nothing
+        end
+    end
+
     rbac_apis = map(x->startswith(x, "RbacAuthorization") ? replace(x, "Authorization"=>"") : x, sorted_apis)
     flowcontrol_apis = map(x->startswith(x, "FlowcontrolApiserver") ? replace(x, "Apiserver"=>"") : x, sorted_apis)
 
@@ -95,6 +112,12 @@ function find_matching_api(sorted_apis::Vector{String}, model_name::String)
 end
 
 function get_common_name(sorted_apis::Vector{String}, model_name::String)
+    for modelpfx in keys(CrdModelnameApiMap)
+        if startswith(model_name, modelpfx)
+            return replace(model_name, modelpfx=>"")
+        end
+    end
+
     rbac_apis = map(x->startswith(x, "RbacAuthorization") ? replace(x, "Authorization"=>"") : x, sorted_apis)
     flowcontrol_apis = map(x->startswith(x, "FlowcontrolApiserver") ? replace(x, "Apiserver"=>"") : x, sorted_apis)

Can not install on Windows

ERROR: Error when installing package Kuber:
AssertionError: length(dirs) == 1
Stacktrace:
 [1] install_archive(::Array{String,1}, ::Base.SHA1, ::String) at C:\cygwin\home\Administrator\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.1\Pkg\src\Operations.jl:482
 [2] macro expansion at C:\cygwin\home\Administrator\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.1\Pkg\src\Operations.jl:596 [inlined]
 [3] (::getfield(Pkg.Operations, Symbol("##26#29")){Symbol,Pkg.Types.Context,Dict{Base.UUID,Base.SHA1},Dict{Base.UUID,Array{String,1}}})() at .\task.jl:259

Use the updated Kubernetes specification

  • Kubernetes API specifiation has changed. The client stubs need to be regenerated.
  • Each API class has a separate specification file, instead of a single root_swagger.json
  • Some APIs have changed. Looks like we do not need some of the manual patches we made earlier. Also need to check if any of our API usage needs to be changed correspondingly.

`watch` does not work for cluster wide resources

Calling watch on cluster wide resources like Node or ClusterRole results in error:

julia> Kuber.watch(ctx.ctx, Kuber.get, :Node; namespace=nothing) do stream
       @show stream
       end
stream = Channel{Any}(1024)
ERROR: TaskFailedException

    nested task error: ArgumentError: No API functions could be located using Node
    Stacktrace:
     [1] get(ctx::Kuber.KuberWatchContext, O::Symbol; apiversion::Nothing, label_selector::Nothing, namespace::Nothing, max_tries::Int64, watch::Bool, resource_version::Nothing, kwargs::Base.Iterators.Pairs{Union{}, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
       @ Kuber ~/.julia/packages/Kuber/yHsvl/src/simpleapi.jl:204
     [2] macro expansion
       @ ~/.julia/packages/Kuber/yHsvl/src/simpleapi.jl:39 [inlined]
     [3] (::Kuber.var"#25#28"{Kuber.KuberWatchContext, Channel{Any}, Base.Iterators.Pairs{Symbol, Nothing, Tuple{Symbol}, NamedTuple{(:namespace,), Tuple{Nothing}}}, typeof(get), Tuple{Symbol}})()
       @ Kuber ./task.jl:411

TagBot trigger issue

This issue is used to trigger TagBot; feel free to unsubscribe.

If you haven't already, you should update your TagBot.yml to include issue comment triggers.
Please see this post on Discourse for instructions and more details.

If you'd like for me to do this for you, comment TagBot fix on this issue.
I'll open a PR within a few hours, please be patient!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.