Class: HubClustersCreator::Kube

Inherits:
Object
  • Object
show all
Defined in:
lib/hub-clusters-creator/kube/kube.rb

Overview

Kube is a collection of methods for interacting with the kubernetes api rubocop:disable Metrics/LineLength,Metrics/MethodLength,Metrics/ParameterLists

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(endpoint, token: nil, client_certificate: nil, client_key: nil, certificate_authority: nil) ⇒ Kube

Returns a new instance of Kube.



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/hub-clusters-creator/kube/kube.rb', line 26

def initialize(endpoint, token: nil, client_certificate: nil, client_key: nil, certificate_authority: nil)
  options = {
    ssl_verify_peer: false
  }

  config = K8s::Config.new(
    clusters: [{
      name: 'default',
      cluster: { server: 'https://' + endpoint, certificate_authority_data: certificate_authority }
    }],
    users: [{
      name: 'default',
      user: {
        token: token,
        client_certificate_data: client_certificate,
        client_key_data: client_key
      }
    }],
    contexts: [{
      name: 'default',
      context: { cluster: 'default', user: 'default' }
    }],
    current_context: 'default'
  )

  @endpoint = "https://#{endpoint}" unless endpoint.start_with?('https')
  @client = K8s::Client.config(config, options)
end

Instance Attribute Details

#endpointObject

Returns the value of attribute endpoint.



24
25
26
# File 'lib/hub-clusters-creator/kube/kube.rb', line 24

def endpoint
  @endpoint
end

Instance Method Details

#account(name, namespace = 'kube-system') ⇒ Object

account returns the credentials for a service account



125
126
127
128
129
# File 'lib/hub-clusters-creator/kube/kube.rb', line 125

def (name, namespace = 'kube-system')
  sa = @client.api('v1').resource('serviceaccounts', namespace: namespace).get(name)
  secret = @client.api('v1').resource('secrets', namespace: namespace).get(sa.secrets.first.name)
  secret.data.token
end

#delete(name, kind, namespace, version: 'v1') ⇒ Object

delete removes a resource from the cluster



72
73
74
75
76
# File 'lib/hub-clusters-creator/kube/kube.rb', line 72

def delete(name, kind, namespace, version: 'v1')
  return unless exists?(name, kind, namespace, version)

  @client.api(version).resource(kind, namespace: namespace).delete_resource(name)
end

#exists?(name, kind, namespace = 'default', version = 'v1') ⇒ Boolean

exists? checks if the resource exists

Returns:

  • (Boolean)


56
57
58
59
60
61
62
63
64
# File 'lib/hub-clusters-creator/kube/kube.rb', line 56

def exists?(name, kind, namespace = 'default', version = 'v1')
  begin
    kind = "#{kind}s" unless kind.end_with?('s')
    @client.api(version).resource(kind, namespace: namespace).get(name)
  rescue K8s::Error::NotFound
    return false
  end
  true
end

#get(name, namespace, kind, version: 'v1') ⇒ Object

get retrieves a resource from the cluster



67
68
69
# File 'lib/hub-clusters-creator/kube/kube.rb', line 67

def get(name, namespace, kind, version: 'v1')
  @client.api(version).resource(kind, namespace: namespace).get(name)
end

#kubectl(manifest) ⇒ Object

kubectl is used to apply a manifest rubocop:disable Metrics/AbcSize

Raises:

  • (ArgumentError)


107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/hub-clusters-creator/kube/kube.rb', line 107

def kubectl(manifest)
  resource = K8s::Resource.from_json(YAML.safe_load(manifest).to_json)
  raise ArgumentError, 'no api version associated to resource' unless resource.apiVersion
  raise ArgumentError, 'no kind associated to resource' unless resource.kind
  raise ArgumentError, 'no metadata associated to resource' unless resource.
  raise ArgumentError, 'no name associated to resource' unless resource..name

  name = resource..name
  namespace = resource..namespace
  kind = resource.kind.downcase
  version = resource.apiVersion
  return if exists?(name, kind, namespace, version)

  @client.api(version).resource("#{kind}s", namespace: namespace).create_resource(resource)
end

#wait(name, namespace, kind, version: 'v1', max_retries: 50, timeout: 300, interval: 5, &block) ⇒ Object

wait is used to poll until a resource meets the needs of the consumer rubocop:disable Lint/RescueException,Metrics/CyclomaticComplexity,Metrics/AbcSize

Raises:

  • (Exception)


80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/hub-clusters-creator/kube/kube.rb', line 80

def wait(name, namespace, kind, version: 'v1', max_retries: 50, timeout: 300, interval: 5, &block)
  retries = counter = 0
  while counter < timeout
    begin
      unless block_given?
        return if exists?(name, kind, namespace, version)

        continue
      end

      resource = @client.api(version).resource(kind).get(name, namespace: namespace)
      return if block.call(resource)
    rescue Exception => e
      raise e if retries > max_retries

      retries += 1
    end
    sleep(interval)
    counter += interval
  end

  raise Exception, "operation waiting for #{name}/#{namespace}/#{kind} has failed"
end

#wait_for_kubeapi(max_attempts = 60, interval = 5) ⇒ Object

wait_for_kubeapi is responsible for waiting the api is available

Raises:

  • (Exception)


132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/hub-clusters-creator/kube/kube.rb', line 132

def wait_for_kubeapi(max_attempts = 60, interval = 5)
  attempts = 0
  while attempts < max_attempts
    begin
      return if @client.api('v1').resource('nodes').list
    rescue StandardError => e
      puts "bad: #{e}"
      attempts += 1
    end
    sleep(interval)
  end
  raise Exception, 'timed out waiting for the kube api'
end