biosphere 0.0.11 → 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/biosphere +67 -19
- data/lib/biosphere/kube.rb +1 -0
- data/lib/biosphere/s3.rb +82 -0
- data/lib/biosphere/version.rb +1 -1
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 347ecc8394215627d48fae451787d293607fdbad
|
4
|
+
data.tar.gz: 8f8e03cc288495d430e0477fa74b5eeb12a933fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8238bcfcc308dde2a1ee51d88cd6eed69f092f22cef45813b275219358811fd88c12e62c2063ddea6661c6a16c03085bb6b637a3765b896920ed4dbb37700f8c
|
7
|
+
data.tar.gz: a3d298603618dcd1163b7e46e8d9578873d471c0378b858be6afb343a8763f9db160e7ecd692e4cda45a703c9a7d0819ba3637d55bcb4d17f7ee15f86d99a58c
|
data/bin/biosphere
CHANGED
@@ -6,13 +6,21 @@ require 'ostruct'
|
|
6
6
|
require 'pp'
|
7
7
|
require "awesome_print"
|
8
8
|
require 'colorize'
|
9
|
+
require 'biosphere/s3.rb'
|
9
10
|
|
10
11
|
class BiosphereOpts
|
11
12
|
|
13
|
+
def self.normalize_path(path)
|
14
|
+
if path[-1] != '/'
|
15
|
+
path += '/'
|
16
|
+
end
|
17
|
+
return path
|
18
|
+
end
|
19
|
+
|
12
20
|
def self.parse(args)
|
13
21
|
|
14
22
|
options = OpenStruct.new
|
15
|
-
options.
|
23
|
+
options.build_dir = "build"
|
16
24
|
options.src = "./"
|
17
25
|
options.version = ::Biosphere::Version
|
18
26
|
|
@@ -23,8 +31,11 @@ class BiosphereOpts
|
|
23
31
|
|
24
32
|
opts.separator ""
|
25
33
|
opts.separator "Commands:"
|
34
|
+
opts.separator "\tbuild\tWrite tf files as json into build directory"
|
26
35
|
opts.separator "\tplan\tRun the planning phase"
|
27
|
-
opts.separator "\
|
36
|
+
opts.separator "\tcommit\tCommit changes and update the infrastructure"
|
37
|
+
opts.separator "\tlock\tAcquire lock for remote state"
|
38
|
+
opts.separator "\tunlock\tRelease lock for remote state"
|
28
39
|
opts.separator "\taction [action]\tCall an action defined in the application .rb files"
|
29
40
|
opts.separator ""
|
30
41
|
|
@@ -34,12 +45,11 @@ class BiosphereOpts
|
|
34
45
|
end
|
35
46
|
|
36
47
|
opts.on("--src PATH", "Directory where the application .rb files are") do |path|
|
37
|
-
options.src = path
|
48
|
+
options.src = normalize_path(path)
|
38
49
|
end
|
39
50
|
|
40
|
-
|
41
|
-
|
42
|
-
options.build = path
|
51
|
+
opts.on("--build-dir PATH", "Directory where to build json files") do |path|
|
52
|
+
options.build_dir = normalize_path(path)
|
43
53
|
end
|
44
54
|
|
45
55
|
end
|
@@ -62,7 +72,7 @@ if ARGV.length == 0
|
|
62
72
|
end
|
63
73
|
|
64
74
|
if !File.directory?(options.src)
|
65
|
-
STDERR.puts "Directory #{options.
|
75
|
+
STDERR.puts "Directory #{options.build_dir} is not a directory or it doesn't exists."
|
66
76
|
exit -1
|
67
77
|
end
|
68
78
|
|
@@ -76,40 +86,47 @@ if options.src
|
|
76
86
|
STDERR.puts "No files found. Are you in the right directory where your biosphere .rb files are?"
|
77
87
|
exit -1
|
78
88
|
end
|
79
|
-
end
|
80
89
|
|
81
|
-
if
|
82
|
-
|
83
|
-
|
84
|
-
Dir.mkdir(options.build)
|
90
|
+
if suite.node[:settings][:s3_bucket].nil? || suite.node[:settings][:s3_bucket].empty? || suite.node[:settings][:cluster_name].nil? || suite.node[:settings][:cluster_name].empty?
|
91
|
+
puts "\nNo S3 bucket or cluster name defined in configuration, can't continue"
|
92
|
+
exit 1
|
85
93
|
end
|
94
|
+
s3 = S3.new(suite.node[:settings][:s3_bucket], suite.node[:settings][:cluster_name])
|
86
95
|
end
|
87
96
|
|
97
|
+
if options.build_dir
|
98
|
+
if !File.directory?(options.build_dir)
|
99
|
+
STDERR.puts "Creating build directory #{options.build_dir} because it was missing"
|
100
|
+
Dir.mkdir(options.build_dir)
|
101
|
+
end
|
102
|
+
end
|
88
103
|
|
89
|
-
if ARGV[0] == "
|
104
|
+
if ARGV[0] == "build" && options.src
|
90
105
|
suite.evaluate_resources()
|
91
106
|
|
92
|
-
if !File.directory?(options.
|
93
|
-
STDERR.puts "Directory #{options.
|
107
|
+
if !File.directory?(options.build_dir)
|
108
|
+
STDERR.puts "Directory #{options.build_dir} is not a directory or it doesn't exists."
|
94
109
|
exit -1
|
95
110
|
end
|
96
111
|
|
97
112
|
count = 0
|
98
|
-
suite.write_json_to(options.
|
113
|
+
suite.write_json_to(options.build_dir) do |file_name, destination, str, proxy|
|
99
114
|
puts "Wrote #{str.length} bytes from #{file_name} to #{destination} (#{proxy.export["resource"].length} resources)"
|
100
115
|
count = count + 1
|
101
116
|
end
|
102
117
|
|
103
|
-
puts "Wrote #{count} files into #{options.
|
118
|
+
puts "Wrote #{count} files into #{options.build_dir}"
|
104
119
|
suite.save_node()
|
105
120
|
|
106
121
|
elsif ARGV[0] == "plan" && options.src
|
107
122
|
suite.evaluate_plans()
|
108
123
|
ap suite.node, :indent=>-4
|
124
|
+
|
109
125
|
elsif ARGV[0] == "action" && options.src
|
126
|
+
s3.retrieve("#{options.build_dir}terraform.tfstate")
|
127
|
+
s3.retrieve("#{options.build_dir}state.node")
|
110
128
|
context = Biosphere::ActionContext.new()
|
111
|
-
|
112
|
-
context.build_directory = options.build
|
129
|
+
context.build_directory = options.build_dir
|
113
130
|
|
114
131
|
if suite.call_action(ARGV[1], context)
|
115
132
|
STDERR.puts "Executing action #{ARGV[1]}"
|
@@ -118,6 +135,37 @@ elsif ARGV[0] == "action" && options.src
|
|
118
135
|
end
|
119
136
|
|
120
137
|
suite.save_node()
|
138
|
+
|
139
|
+
elsif ARGV[0] == "commit" && options.src
|
140
|
+
s3.set_lock()
|
141
|
+
s3.retrieve("#{options.build_dir}terraform.tfstate")
|
142
|
+
s3.retrieve("#{options.build_dir}state.node")
|
143
|
+
tf_plan = %x( terraform plan -state=#{options.build_dir}terraform.tfstate #{options.build_dir} )
|
144
|
+
puts "\n" + tf_plan
|
145
|
+
answer = ""
|
146
|
+
while answer.empty? || (answer != "y" && answer != "n")
|
147
|
+
print "\nDoes the plan look reasonable? (Answering yes will apply the changes) y/n: "
|
148
|
+
answer = STDIN.gets.chomp
|
149
|
+
end
|
150
|
+
|
151
|
+
if answer == "n"
|
152
|
+
puts "\nOk, will not proceed with commit"
|
153
|
+
elsif answer == "y"
|
154
|
+
puts "\nApplying the changes (this may take several minutes)"
|
155
|
+
tf_apply = %x( terraform apply -state=#{options.build_dir}terraform.tfstate #{options.build_dir})
|
156
|
+
puts "\n" + tf_apply
|
157
|
+
s3.save("#{options.build_dir}terraform.tfstate")
|
158
|
+
s3.save("#{options.src}state.node")
|
159
|
+
end
|
160
|
+
|
161
|
+
s3.release_lock()
|
162
|
+
|
163
|
+
elsif ARGV[0] == "lock"
|
164
|
+
s3.set_lock()
|
165
|
+
|
166
|
+
elsif ARGV[0] == "unlock"
|
167
|
+
s3.release_lock()
|
168
|
+
|
121
169
|
else
|
122
170
|
STDERR.puts "\nERROR: Unknown command #{ARGV[0]}. Maybe you wanted to do: \"biosphere action #{ARGV[0]}\"?"
|
123
171
|
exit -1
|
data/lib/biosphere/kube.rb
CHANGED
@@ -66,6 +66,7 @@ class Biosphere
|
|
66
66
|
end
|
67
67
|
|
68
68
|
ns_prefix = client.build_namespace_prefix(resource[:metadata][:namespace])
|
69
|
+
ns_prefix = ns_prefix.empty? ? "namespaces/default/" : ns_prefix
|
69
70
|
ret = client.rest_client[ns_prefix + resource_name].post(resource.to_h.to_json, { 'Content-Type' => 'application/json' }.merge(client.instance_variable_get("@headers")))
|
70
71
|
return {
|
71
72
|
action: :post,
|
data/lib/biosphere/s3.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'aws-sdk'
|
2
|
+
|
3
|
+
class S3
|
4
|
+
def initialize(bucket, main_key)
|
5
|
+
@client = Aws::S3::Client.new
|
6
|
+
@bucket_name = bucket
|
7
|
+
@main_key = main_key
|
8
|
+
end
|
9
|
+
|
10
|
+
def save(path_to_file)
|
11
|
+
puts "\nSaving #{path_to_file} to S3"
|
12
|
+
filename = path_to_file.split('/')[-1]
|
13
|
+
begin
|
14
|
+
File.open(path_to_file, 'rb') do |file|
|
15
|
+
@client.put_object({
|
16
|
+
:bucket => @bucket_name,
|
17
|
+
:key => "#{@main_key}/#{filename}",
|
18
|
+
:body => file
|
19
|
+
})
|
20
|
+
end
|
21
|
+
rescue
|
22
|
+
puts "\nError occurred while saving the remote state, can't continue"
|
23
|
+
puts "Error: #{$!}"
|
24
|
+
exit 1
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def retrieve(path_to_file)
|
29
|
+
filename = path_to_file.split('/')[-1]
|
30
|
+
puts "\nFetching #{filename} from S3"
|
31
|
+
begin
|
32
|
+
resp = @client.get_object({
|
33
|
+
:bucket => @bucket_name,
|
34
|
+
:key => "#{@main_key}/#{filename}"
|
35
|
+
})
|
36
|
+
File.open(path_to_file, 'w') do |f|
|
37
|
+
f.puts(resp.body.read)
|
38
|
+
end
|
39
|
+
rescue Aws::S3::Errors::NoSuchKey
|
40
|
+
puts "\nCouldn't find remote file #{filename} from S3."
|
41
|
+
rescue
|
42
|
+
puts "\nError occurred while fetching the remote state, can't continue."
|
43
|
+
puts "Error: #{$!}"
|
44
|
+
exit 1
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def set_lock()
|
49
|
+
begin
|
50
|
+
resp = @client.get_object({
|
51
|
+
:bucket => @bucket_name,
|
52
|
+
:key => "#{@main_key}/biosphere.lock"
|
53
|
+
})
|
54
|
+
puts "\nThe remote state is locked since #{resp.last_modified}\nCan't continue."
|
55
|
+
exit 1
|
56
|
+
rescue Aws::S3::Errors::NoSuchKey
|
57
|
+
puts "\nRemote state was not locked, adding the lockfile.\n"
|
58
|
+
@client.put_object({
|
59
|
+
:bucket => @bucket_name,
|
60
|
+
:key => "#{@main_key}/biosphere.lock"
|
61
|
+
})
|
62
|
+
rescue
|
63
|
+
puts "\There was an error while accessing the lock. Can't continue.'"
|
64
|
+
puts "Error: #{$!}"
|
65
|
+
exit 1
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def release_lock()
|
70
|
+
begin
|
71
|
+
@client.delete_object({
|
72
|
+
:bucket => @bucket_name,
|
73
|
+
:key => "#{@main_key}/biosphere.lock"
|
74
|
+
})
|
75
|
+
rescue
|
76
|
+
puts "\nCouldn't release the lock!"
|
77
|
+
puts "Error: #{$!}"
|
78
|
+
exit 1
|
79
|
+
end
|
80
|
+
puts "\nLock released successfully"
|
81
|
+
end
|
82
|
+
end
|
data/lib/biosphere/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: biosphere
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Juho Mäkinen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-02-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - '='
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: 0.8.1
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: aws-sdk
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '2'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '2'
|
97
111
|
description: "Terraform's HCL lacks quite many programming features like iterators,
|
98
112
|
true variables, advanced string manipulation, functions etc.\n\n This Ruby tool
|
99
113
|
provides an easy-to-use DSL to define Terraform compatible .json files which can
|
@@ -111,6 +125,7 @@ files:
|
|
111
125
|
- lib/biosphere/kube.rb
|
112
126
|
- lib/biosphere/mixing/from_file.rb
|
113
127
|
- lib/biosphere/node.rb
|
128
|
+
- lib/biosphere/s3.rb
|
114
129
|
- lib/biosphere/suite.rb
|
115
130
|
- lib/biosphere/terraformproxy.rb
|
116
131
|
- lib/biosphere/version.rb
|