kuby-linode 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 67b3964fc1ab77044195a89727a066b7439955087601e4df807ddc6641971367
4
+ data.tar.gz: f055e6159a6f1be6def44464664523f39b531e20f22af5c8765b1adffcaf02e5
5
+ SHA512:
6
+ metadata.gz: 0f00f8e48e27df72dfc2b2534169ffc7d64c23a2f78cbab3f42cd05fa2013167c1000da8b7e2f8be031280c03707d2be5423f50bd093acc80837c05d880f2577
7
+ data.tar.gz: 03530b38c6dcdc10850a47b85696e3526cb12e47055d7092f6571929abb01a41021803e4d3eedc21744e142f3677db72c27f61a100a8662e5939081e72d8d4ce
@@ -0,0 +1,2 @@
1
+ ## 0.1.0
2
+ * Birthday!
data/Gemfile ADDED
@@ -0,0 +1,14 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'kuby-core', path: '../kuby-core'
6
+
7
+ group :development, :test do
8
+ gem 'pry-byebug'
9
+ gem 'rake'
10
+ end
11
+
12
+ group :test do
13
+ gem 'rspec', '~> 3.0'
14
+ end
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 Cameron Dutro
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,14 @@
1
+ require 'bundler'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubygems/package_task'
4
+
5
+ require 'kuby/linode'
6
+
7
+ Bundler::GemHelper.install_tasks
8
+
9
+ task default: :spec
10
+
11
+ desc 'Run specs'
12
+ RSpec::Core::RakeTask.new do |t|
13
+ t.pattern = './spec/**/*_spec.rb'
14
+ end
@@ -0,0 +1,20 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), 'lib')
2
+ require 'kuby/linode/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'kuby-linode'
6
+ s.version = ::Kuby::Linode::VERSION
7
+ s.authors = ['Cameron Dutro']
8
+ s.email = ['camertron@gmail.com']
9
+ s.homepage = 'http://github.com/getkuby/kuby-linode'
10
+
11
+ s.description = s.summary = 'Linode provider for Kuby.'
12
+
13
+ s.platform = Gem::Platform::RUBY
14
+
15
+ s.add_dependency 'faraday', '~> 0.17'
16
+ s.add_dependency 'kube-dsl', '~> 0.1'
17
+
18
+ s.require_path = 'lib'
19
+ s.files = Dir['{lib,spec}/**/*', 'Gemfile', 'LICENSE', 'CHANGELOG.md', 'README.md', 'Rakefile', 'kuby-linode.gemspec']
20
+ end
@@ -0,0 +1,11 @@
1
+ require 'kuby'
2
+ require 'kuby/linode/provider'
3
+
4
+ module Kuby
5
+ module Linode
6
+ autoload :Client, 'kuby/linode/client'
7
+ autoload :Config, 'kuby/linode/config'
8
+ end
9
+ end
10
+
11
+ Kuby.register_provider(:linode, Kuby::Linode::Provider)
@@ -0,0 +1,98 @@
1
+ require 'base64'
2
+ require 'faraday'
3
+
4
+ module Kuby
5
+ module Linode
6
+ class ApiError < StandardError
7
+ attr_reader :status_code
8
+
9
+ def initialize(message, status_code)
10
+ super(message)
11
+ @status_code = status_code
12
+ end
13
+ end
14
+
15
+ class UnauthorizedError < ApiError
16
+ def initialize(message)
17
+ super(message, 401)
18
+ end
19
+ end
20
+
21
+ class NotFoundError < ApiError
22
+ def initialize(message)
23
+ super(message, 404)
24
+ end
25
+ end
26
+
27
+ class Client
28
+ API_URL = 'https://api.linode.com'.freeze
29
+ KUBECONFIG_PATH = '/v4/lke/clusters/%{cluster_id}/kubeconfig'.freeze
30
+
31
+ def self.create(access_token:)
32
+ options = {
33
+ url: API_URL,
34
+ headers: {
35
+ Accept: 'application/json',
36
+ Authorization: "Bearer #{access_token}"
37
+ }
38
+ }
39
+
40
+ new(
41
+ Faraday.new(options) do |faraday|
42
+ faraday.request(:retry, max: 3)
43
+ faraday.adapter(:net_http)
44
+ end
45
+ )
46
+ end
47
+
48
+ attr_reader :connection
49
+
50
+ def initialize(connection)
51
+ @connection = connection
52
+ end
53
+
54
+ def kubeconfig(cluster_id)
55
+ response = get_json(KUBECONFIG_PATH % { cluster_id: cluster_id })
56
+ Base64.decode64(response['kubeconfig'])
57
+ end
58
+
59
+ private
60
+
61
+ def get(url, params = {})
62
+ act(:get, url, params)
63
+ end
64
+
65
+ def get_json(url, params = {})
66
+ response = get(url, params)
67
+ JSON.parse(response.body)
68
+ end
69
+
70
+ def act(verb, *args)
71
+ connection.send(verb, *args).tap do |response|
72
+ potentially_raise_error!(response)
73
+ end
74
+ end
75
+
76
+ def potentially_raise_error!(response)
77
+ case response.status
78
+ when 401
79
+ raise UnauthorizedError, "401 Unauthorized: #{response.env.url}"
80
+ when 404
81
+ raise NotFoundError, "404 Not Found: #{response.env.url}"
82
+ else
83
+ if failure_response?(response)
84
+ raise ApiError.new(
85
+ "HTTP #{response.status}: #{response.env.url}, body: #{response.body}",
86
+ response.status
87
+ )
88
+ end
89
+ end
90
+ end
91
+
92
+ def failure_response?(response)
93
+ data = JSON.parse(response.body) rescue {}
94
+ (response.status / 100) != 2 || data['message'] == 'failure'
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,11 @@
1
+ require 'kube-dsl'
2
+
3
+ module Kuby
4
+ module Linode
5
+ class Config
6
+ extend ::KubeDSL::ValueFields
7
+
8
+ value_fields :access_token, :cluster_id
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,62 @@
1
+ require 'fileutils'
2
+
3
+ module Kuby
4
+ module Linode
5
+ class Provider < Kuby::Kubernetes::Provider
6
+ KUBECONFIG_EXPIRATION = 7 * 24 * 60 * 60 # 7 days
7
+ STORAGE_CLASS_NAME = 'linode-block-storage'.freeze
8
+
9
+ attr_reader :config
10
+
11
+ def configure(&block)
12
+ config.instance_eval(&block)
13
+ end
14
+
15
+ def kubeconfig_path
16
+ @kubeconfig_path ||= kubeconfig_dir.join(
17
+ "#{definition.app_name.downcase}-kubeconfig.yaml"
18
+ ).to_s
19
+ end
20
+
21
+ def after_configuration
22
+ refresh_kubeconfig
23
+ end
24
+
25
+ def storage_class_name
26
+ STORAGE_CLASS_NAME
27
+ end
28
+
29
+ private
30
+
31
+ def after_initialize
32
+ @config = Config.new
33
+ end
34
+
35
+ def client
36
+ @client ||= Client.create(
37
+ access_token: config.access_token
38
+ )
39
+ end
40
+
41
+ def refresh_kubeconfig
42
+ return unless should_refresh_kubeconfig?
43
+ FileUtils.mkdir_p(kubeconfig_dir)
44
+ Kuby.logger.info('Refreshing kubeconfig...')
45
+ kubeconfig = client.kubeconfig(config.cluster_id)
46
+ File.write(kubeconfig_path, kubeconfig)
47
+ Kuby.logger.info('Successfully refreshed kubeconfig!')
48
+ end
49
+
50
+ def should_refresh_kubeconfig?
51
+ !File.exist?(kubeconfig_path) ||
52
+ (Time.now - File.mtime(kubeconfig_path)) >= KUBECONFIG_EXPIRATION
53
+ end
54
+
55
+ def kubeconfig_dir
56
+ @kubeconfig_dir ||= definition.app.root.join(
57
+ 'tmp', 'kuby-linode'
58
+ )
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,5 @@
1
+ module Kuby
2
+ module Linode
3
+ VERSION = '0.1.0'.freeze
4
+ end
5
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kuby-linode
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Cameron Dutro
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-06-11 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.17'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.17'
27
+ - !ruby/object:Gem::Dependency
28
+ name: kube-dsl
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.1'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.1'
41
+ description: Linode provider for Kuby.
42
+ email:
43
+ - camertron@gmail.com
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - CHANGELOG.md
49
+ - Gemfile
50
+ - LICENSE
51
+ - Rakefile
52
+ - kuby-linode.gemspec
53
+ - lib/kuby/linode.rb
54
+ - lib/kuby/linode/client.rb
55
+ - lib/kuby/linode/config.rb
56
+ - lib/kuby/linode/provider.rb
57
+ - lib/kuby/linode/version.rb
58
+ homepage: http://github.com/getkuby/kuby-linode
59
+ licenses: []
60
+ metadata: {}
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ required_rubygems_version: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ requirements: []
76
+ rubygems_version: 3.0.6
77
+ signing_key:
78
+ specification_version: 4
79
+ summary: Linode provider for Kuby.
80
+ test_files: []