Module: Biosphere::Kube

Included in:
TerraformProxy
Defined in:
lib/biosphere/kube.rb

Defined Under Namespace

Classes: Client, KubeResource, KubeResourceERBBinding

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.find_manifest_files(dir) ⇒ Object



339
340
341
342
343
344
345
# File 'lib/biosphere/kube.rb', line 339

def self.find_manifest_files(dir)
    files = []
    files += Dir[dir + "/**/*.erb"]

    files += Dir[dir + "/**/*.yaml"]
    files
end

.load_resources(file, context = {}) ⇒ Object



347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
# File 'lib/biosphere/kube.rb', line 347

def self.load_resources(file, context={})
    resources = []
    puts "Loading file #{File.absolute_path(file)}"

    # Let's wrap the context into an OpenStruct based class so that context["foo"]
    # can be accessed as contextstruct.foo
    #
    # This is required for two reasons:
    #  1) The ERB template evaluation requires a binding object so that
    #     we can pass variables to the template (from the context object)
    #  2) We want to push some metadata from the ERB template to back here
    #     such as the preserve_current_value
    contextstruct = KubeResourceERBBinding.new(context)

    # Read the file in. A single .yaml can contain multiple documents
    data = IO.read(file)

    # First phase: Evaluate ERB templating. We'll use the context to pass
    # all the template variables into the erb.
    # Handle all ERB error reporting with the rescue clauses,
    # so that user gets as good error message as possible.
    begin
        str = ERB.new(data).result(contextstruct.instance_eval { binding })
    rescue NoMethodError => e
        puts "Error evaluating erb templating for #{file}. Error: #{e}"
        m = /\(erb\):([0-9]+):/.match(e.backtrace.first)
        if m
            puts "Error at line #{m[1]}. This is before ERB templating. Remember to run biosphere build if you changed settings."
            linenumber = m[1].to_i
            lines = data.split("\n")
            start_line = [0, linenumber - 4].max
            end_line = [lines.length - 1, linenumber + 2].min

            # Lines is the full .yaml file, one line in each index
            # the [start_line..end_line] slices the subset of the lines
            # which we want to display
            lines[start_line..end_line].each_with_index do |line, num|

                # num is the current line number from the subset of the lines
                # We need to add start_line + 1 to it so that it shows
                # the current line number when we print it out
                num += start_line + 1
                if num == linenumber
                    STDERR.printf("%04d>  %s\n".red, num, line)
                else
                    STDERR.printf("%04d|  %s\n", num, line)
                end
            end
        end
        raise e
    end

    # Second phase: Parse YAML into an array of KubeResource.
    # Again handle error reporting on the rescue clause.
    begin
        Psych.load_stream(str) do |document|
            kind = document["kind"]
            resource = KubeResource.new(document, file)

            # The preserve_current_values is a metadata field which is used later
            # when merging the updated resource with the current object from apiserver.
            resource.preserve_current_values = contextstruct.preserve_current_values

            resources << resource
        end
    rescue Psych::SyntaxError => e
        STDERR.puts "\n"
        STDERR.puts "YAML syntax error while parsing file #{file}. Notice this happens after ERB templating, so line numbers might not match."
        STDERR.puts "Here are the relevant lines. Error '#{e.problem}' occured at line #{e.line}"
        STDERR.puts "Notice that yaml is very picky about indentation when you have arrays and maps. Check those first."
        lines = str.split("\n")
        linenumber = e.line
        start_line = [0, linenumber - 4].max
        end_line = [lines.length - 1, linenumber + 2].min
        lines[start_line..end_line].each_with_index do |line, num|
            # num is the current line number from the subset of the lines
            # We need to add start_line + 1 to it so that it shows
            # the current line number when we print it out
            num += start_line + 1
            if num == linenumber
                STDERR.printf("%04d>  %s\n".red, num, line)
            else
                STDERR.printf("%04d|  %s\n", num, line)
            end

        end
        STDERR.puts "\n"
        raise e
    end
    return resources
end

Instance Method Details

#kube_create_resource(client, resource) ⇒ Object



439
440
441
442
443
444
445
446
447
# File 'lib/biosphere/kube.rb', line 439

def kube_create_resource(client, resource)
    name = resource[:metadata][:name]
    resource_name = client.instance_variable_get("@entities")[resource[:kind].downcase].resource_name
    ns_prefix = client.build_namespace_prefix(resource[:metadata][:namespace])
    client.handle_exception do
        client.rest_client[ns_prefix + resource_name]
        .post(resource.to_h.to_json, { 'Content-Type' => 'application/json' }.merge(client.instance_variable_get("@headers")))
    end
end

#kube_get_client(hostname, ssl_options) ⇒ Object



335
336
337
# File 'lib/biosphere/kube.rb', line 335

def kube_get_client(hostname, ssl_options)
    return Client.new(hostname, ssl_options)
end

#kube_test(str) ⇒ Object

end of class Client



331
332
333
# File 'lib/biosphere/kube.rb', line 331

def kube_test(str)
    return str
end