zaws 0.0.1

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.
Files changed (89) hide show
  1. data/.gitignore +35 -0
  2. data/.travis.yml +20 -0
  3. data/Gemfile +5 -0
  4. data/Gemfile.lock +78 -0
  5. data/LICENSE +204 -0
  6. data/README.md +17 -0
  7. data/Rakefile +26 -0
  8. data/bin/zaws +20 -0
  9. data/feature/compute/assoc_security_group.feature +55 -0
  10. data/feature/compute/compute.feature +138 -0
  11. data/feature/compute/secondary_ip.feature +107 -0
  12. data/feature/compute/view.feature +23 -0
  13. data/feature/compute/view_images.feature +24 -0
  14. data/feature/elasticip/elasticip.feature +138 -0
  15. data/feature/elasticip/view.feature +18 -0
  16. data/feature/hosted_zone/view.feature +17 -0
  17. data/feature/hosted_zone/view_record.feature +29 -0
  18. data/feature/load_balancer/instance_registration.feature +120 -0
  19. data/feature/load_balancer/listener.feature +86 -0
  20. data/feature/load_balancer/load_balancer.feature +101 -0
  21. data/feature/load_balancer/view.feature +18 -0
  22. data/feature/route_table/assoc_subnet.feature +128 -0
  23. data/feature/route_table/route_propagation.feature +93 -0
  24. data/feature/route_table/route_table.feature +91 -0
  25. data/feature/route_table/route_to_gateway.feature +69 -0
  26. data/feature/route_table/route_to_instance.feature +115 -0
  27. data/feature/route_table/view.feature +25 -0
  28. data/feature/security_group/ingress.feature +184 -0
  29. data/feature/security_group/security_group.feature +107 -0
  30. data/feature/security_group/view.feature +23 -0
  31. data/feature/subnet/subnet.feature +92 -0
  32. data/feature/subnet/view.feature +24 -0
  33. data/feature/support/env.rb +14 -0
  34. data/feature/version.feature +6 -0
  35. data/lib/zaws/aws.rb +26 -0
  36. data/lib/zaws/command/compute.rb +100 -0
  37. data/lib/zaws/command/elasticip.rb +47 -0
  38. data/lib/zaws/command/hosted_zone.rb +26 -0
  39. data/lib/zaws/command/load_balancer.rb +113 -0
  40. data/lib/zaws/command/route_table.rb +134 -0
  41. data/lib/zaws/command/security_group.rb +69 -0
  42. data/lib/zaws/command/subnet.rb +65 -0
  43. data/lib/zaws/ec2/compute.rb +247 -0
  44. data/lib/zaws/ec2/elasticip.rb +85 -0
  45. data/lib/zaws/ec2/route_table.rb +202 -0
  46. data/lib/zaws/ec2/security_group.rb +116 -0
  47. data/lib/zaws/ec2/subnet.rb +108 -0
  48. data/lib/zaws/ec2.rb +40 -0
  49. data/lib/zaws/elb/load_balancer.rb +157 -0
  50. data/lib/zaws/elb.rb +20 -0
  51. data/lib/zaws/helper/file.rb +23 -0
  52. data/lib/zaws/helper/option.rb +24 -0
  53. data/lib/zaws/helper/output.rb +46 -0
  54. data/lib/zaws/helper/shell.rb +25 -0
  55. data/lib/zaws/route53/hosted_zone.rb +36 -0
  56. data/lib/zaws/route53.rb +20 -0
  57. data/lib/zaws/version.rb +3 -0
  58. data/lib/zaws.rb +57 -0
  59. data/spec/spec_helper.rb +4 -0
  60. data/spec/zaws/ec2/compute/add_volume_spec.rb +39 -0
  61. data/spec/zaws/ec2/compute/block_device_mapping_spec.rb +31 -0
  62. data/spec/zaws/ec2/compute/instance_id_by_external_id_spec.rb +23 -0
  63. data/spec/zaws/ec2/compute/instance_ping_spec.rb +34 -0
  64. data/spec/zaws/ec2/compute/instance_running_spec.rb +47 -0
  65. data/spec/zaws/ec2/compute/network_interface_json_spec.rb +57 -0
  66. data/spec/zaws/ec2/compute/nosdcheck_spec.rb +17 -0
  67. data/spec/zaws/ec2/compute/tag_instance_spec.rb +21 -0
  68. data/spec/zaws/ec2/security_group/id_by_name_spec.rb +32 -0
  69. data/spec/zaws/ec2/subnet/available_spec.rb +22 -0
  70. data/spec/zaws/ec2/subnet/declare_spec.rb +31 -0
  71. data/spec/zaws/ec2/subnet/exists_spec.rb +33 -0
  72. data/spec/zaws/ec2/subnet/id_array_by_cidrblock_array_spec.rb +48 -0
  73. data/spec/zaws/ec2/subnet/id_by_cidrblock_spec.rb +35 -0
  74. data/spec/zaws/ec2/subnet/id_by_ip_spec.rb +42 -0
  75. data/spec/zaws/ec2/subnet/view_spec.rb +34 -0
  76. data/spec/zaws/elb/load_balancer/calculated_listener_spec.rb +18 -0
  77. data/spec/zaws/helper/option/absent_spec.rb +14 -0
  78. data/spec/zaws/helper/option/exclusive_spec.rb +14 -0
  79. data/spec/zaws/helper/option/exists_spec.rb +18 -0
  80. data/spec/zaws/helper/option/minimum_spec.rb +14 -0
  81. data/spec/zaws/helper/output/binary_nagios_check_spec.rb +19 -0
  82. data/spec/zaws/helper/output/colorize_spec.rb +30 -0
  83. data/spec/zaws/helper/output/opt_exclusive_spec.rb +14 -0
  84. data/spec/zaws/helper/output/opt_minimum_spec.rb +15 -0
  85. data/spec/zaws/helper/output/opt_required_spec.rb +12 -0
  86. data/spec/zaws/helper/shell/cli_spec.rb +33 -0
  87. data/spec/zaws/helper/shell/if_then_spec.rb +24 -0
  88. data/zaws.gemspec +34 -0
  89. metadata +350 -0
@@ -0,0 +1,108 @@
1
+ require 'json'
2
+ require 'netaddr'
3
+ require 'timeout'
4
+
5
+ module ZAWS
6
+ module EC2Services
7
+ class Subnet
8
+
9
+ def initialize(shellout,aws)
10
+ @shellout=shellout
11
+ @aws=aws
12
+ end
13
+
14
+ def view(region,view,textout=nil,verbose=nil,vpcid=nil,cidrblock=nil)
15
+ comline="aws --output #{view} --region #{region} ec2 describe-subnets"
16
+ if vpcid || cidrblock
17
+ comline = comline + " --filter"
18
+ end
19
+ comline = comline + " 'Name=vpc-id,Values=#{vpcid}'" if vpcid
20
+ comline = comline + " 'Name=cidr,Values=#{cidrblock}'" if cidrblock
21
+ subnets=@shellout.cli(comline,verbose)
22
+ textout.puts(subnets) if textout
23
+ return subnets
24
+ end
25
+
26
+ def id_by_ip(region,textout=nil,verbose=nil,vpcid,ip)
27
+ subnets=JSON.parse(view(region,'json',nil,verbose,vpcid))
28
+ subnet_id=nil
29
+ subnets["Subnets"].each { |x| subnet_id = x["SubnetId"] if (NetAddr::CIDR.create(x["CidrBlock"])).contains?(ip) }
30
+ textout.puts subnet_id if textout
31
+ return subnet_id
32
+ end
33
+
34
+ def id_by_cidrblock(region,textout=nil,verbose=nil,vpcid,cidrblock)
35
+ subnets=JSON.parse(view(region,'json',nil,verbose,vpcid,cidrblock))
36
+ subnet_id= subnets["Subnets"].count == 1 ? subnets["Subnets"][0]["SubnetId"] : nil
37
+ textout.puts subnet_id if textout
38
+ return subnet_id
39
+ end
40
+
41
+ def id_array_by_cidrblock_array(region,textout=nil,verbose=nil,vpcid,cidrblock_array)
42
+ return cidrblock_array.map {|x| id_by_cidrblock(region,nil,verbose,vpcid,x)}
43
+ end
44
+
45
+ def exists(region,textout=nil,verbose=nil,vpcid,cidrblock)
46
+ val = id_by_cidrblock(region,nil,verbose,vpcid,cidrblock) ? true : false
47
+ textout.puts val.to_s if textout
48
+ return val
49
+ end
50
+
51
+ def declare(region,vpcid,cidrblock,availabilityzone,statetimeout,textout=nil,verbose=nil,nagios=false,ufile=nil)
52
+ if ufile
53
+ ZAWS::Helper::File.prepend("zaws subnet delete --region #{region} --cidrblock #{cidrblock} --vpcid #{vpcid} $XTRA_OPTS",'#Delete subnet',ufile)
54
+ end
55
+ if not exists(region,nil,verbose,vpcid,cidrblock)
56
+ if nagios
57
+ textout.puts "CRITICAL: Subnet Does Not Exist."
58
+ return 2
59
+ end
60
+ comline="aws --output json --region #{region} ec2 create-subnet --vpc-id #{vpcid} --cidr-block #{cidrblock} --availability-zone #{availabilityzone}"
61
+ subnet=@shellout.cli(comline,verbose)
62
+ begin
63
+ Timeout.timeout(statetimeout) do
64
+ until available(subnet,verbose)
65
+ sleep(1)
66
+ subnet=view(region,'json',nil,verbose,vpcid,cidrblock)
67
+ end
68
+ end
69
+ textout.puts "Subnet created."
70
+ rescue Timeout::Error
71
+ throw 'Timeout before Subnet made available.'
72
+ end
73
+ else
74
+ if nagios
75
+ textout.puts "OK: Subnet Exists."
76
+ return 0
77
+ end
78
+ textout.puts "No action needed. Subnet exists already."
79
+ end
80
+ end
81
+
82
+ def available(subnet,verbose)
83
+ #based on the structure of the return from create-subnet and describe-subnet determine if subnet is available
84
+ subnet_hash=JSON.parse(subnet)
85
+ if subnet_hash["Subnet"]
86
+ return (subnet_hash["Subnet"]["State"] == "available")
87
+ end
88
+ if subnet_hash["Subnets"] and subnet_hash["Subnets"].count == 1
89
+ return (subnet_hash["Subnets"][0]["State"] == "available")
90
+ end
91
+ return false
92
+ end
93
+
94
+ def delete(region,textout=nil,verbose=nil,vpcid,cidrblock)
95
+ subnetid=id_by_cidrblock(region,nil,verbose,vpcid,cidrblock)
96
+ if subnetid
97
+ comline="aws --region #{region} ec2 delete-subnet --subnet-id #{subnetid}"
98
+ val=JSON.parse(@shellout.cli(comline,verbose))
99
+ textout.puts "Subnet deleted." if val["return"] == "true"
100
+ else
101
+ textout.puts "Subnet does not exist. Skipping deletion."
102
+ end
103
+ end
104
+
105
+ end
106
+ end
107
+ end
108
+
data/lib/zaws/ec2.rb ADDED
@@ -0,0 +1,40 @@
1
+ require 'json'
2
+ require 'netaddr'
3
+ require 'timeout'
4
+
5
+ module ZAWS
6
+ class EC2
7
+
8
+ def initialize(shellout,aws)
9
+ @shellout=shellout
10
+ @aws=aws
11
+ end
12
+
13
+ def subnet
14
+ @_subnet ||= (ZAWS::EC2Services::Subnet.new(@shellout,@aws))
15
+ return @_subnet
16
+ end
17
+
18
+ def security_group
19
+ @_security_group ||= (ZAWS::EC2Services::SecurityGroup.new(@shellout,@aws))
20
+ return @_security_group
21
+ end
22
+
23
+ def route_table
24
+ @_route_table ||= (ZAWS::EC2Services::RouteTable.new(@shellout,@aws))
25
+ return @_route_table
26
+ end
27
+
28
+ def compute
29
+ @_compute ||= (ZAWS::EC2Services::Compute.new(@shellout,@aws))
30
+ return @_compute
31
+ end
32
+
33
+ def elasticip
34
+ @_elasticip ||= (ZAWS::EC2Services::Elasticip.new(@shellout,@aws))
35
+ return @_elasticip
36
+ end
37
+
38
+ end
39
+ end
40
+
@@ -0,0 +1,157 @@
1
+ require 'json'
2
+ require 'netaddr'
3
+ require 'timeout'
4
+
5
+ module ZAWS
6
+ module ELBServices
7
+ class LoadBalancer
8
+
9
+ def initialize(shellout,aws)
10
+ @shellout=shellout
11
+ @aws=aws
12
+ end
13
+
14
+ def view(region,view,textout=nil,verbose=nil)
15
+ comline="aws --output #{view} --region #{region} elb describe-load-balancers"
16
+ lbs=@shellout.cli(comline,verbose)
17
+ textout.puts(lbs) if textout
18
+ return lbs
19
+ end
20
+
21
+ def exists(region,lbname,textout=nil,verbose=nil)
22
+ lbs=JSON.parse(view(region,'json',nil,verbose))
23
+ val = lbs["LoadBalancerDescriptions"].any? { |x| x["LoadBalancerName"]=="#{lbname}" }
24
+ instances = val ? (lbs["LoadBalancerDescriptions"].select { |x| x["LoadBalancerName"]=="#{lbname}" })[0]["Instances"] : nil
25
+ ldescriptions = val ? (lbs["LoadBalancerDescriptions"].select { |x| x["LoadBalancerName"]=="#{lbname}" })[0]["ListenerDescriptions"] : nil
26
+ textout.puts(val) if textout
27
+ return val,instances,ldescriptions
28
+ end
29
+
30
+ def calculated_listener(lbprotocol,lbport,inprotocol,inport,sslcert=nil)
31
+ listeners = []
32
+ single_listener = {}
33
+ single_listener["Protocol"]="#{lbprotocol}"
34
+ single_listener["LoadBalancerPort"]=lbport.to_i
35
+ single_listener["InstanceProtocol"]="#{inprotocol}"
36
+ single_listener["InstancePort"]=inport.to_i
37
+ single_listener["SSLCertificateId"]="#{sslcert}" if sslcert
38
+ listeners << single_listener
39
+ return listeners.to_json
40
+ end
41
+
42
+ def create_in_subnet(region,lbname,lbprotocol,lbport,inprotocol,inport,securitygroup,cidrblocks,vpcid,nagios=false,textout=nil,verbose=nil,ufile=nil)
43
+ if ufile
44
+ ZAWS::Helper::File.prepend("zaws load_balancer delete #{lbname} --region #{region} $XTRA_OPTS",'#Delete load balancer',ufile)
45
+ end
46
+ lbexists,instances,ldescriptions=exists(region,lbname,nil,verbose)
47
+ return ZAWS::Helper::Output.binary_nagios_check(lbexists,"OK: Load Balancer Exists.","CRITICAL: Load Balancer does not exist.",textout) if nagios
48
+ if not lbexists
49
+ comline="aws --region #{region} elb create-load-balancer"
50
+ comline+=" --load-balancer-name #{lbname}"
51
+ comline+=" --listeners '#{calculated_listener(lbprotocol,lbport,inprotocol,inport)}'"
52
+ comline+=" --subnets #{@aws.ec2.subnet.id_array_by_cidrblock_array(region,nil,nil,vpcid,cidrblocks).join(" ")}"
53
+ sgroup_exists,sgroupid = @aws.ec2.security_group.exists(region,nil,nil,vpcid,securitygroup)
54
+ comline+=" --security-groups #{sgroupid}"
55
+ newlb=JSON.parse(@shellout.cli(comline,verbose))
56
+ textout.puts "Load balancer created." if newlb["DNSName"]
57
+ else
58
+ textout.puts "Load balancer already exists. Skipping creation."
59
+ end
60
+ end
61
+
62
+ def delete(region,lbname,textout=nil,verbose=nil)
63
+ lbexists,instances,ldescriptions=exists(region,lbname,nil,verbose)
64
+ if lbexists
65
+ comline="aws --region #{region} elb delete-load-balancer"
66
+ comline+=" --load-balancer-name #{lbname}"
67
+ deletelb=JSON.parse(@shellout.cli(comline,verbose))
68
+ textout.puts "Load balancer deleted." if deletelb["return"] == "true"
69
+ else
70
+ textout.puts "Load balancer does not exist. Skipping deletion."
71
+ end
72
+ end
73
+
74
+ def exists_instance(region,lbname,instance_external_id,vpcid,textout=nil,verbose=nil)
75
+ lbexists,instances,ldescriptions=exists(region,lbname,nil,verbose)
76
+ instance_exists,instance_id = @aws.ec2.compute.exists(region,nil,verbose,vpcid,instance_external_id)
77
+ val = (lbexists and instance_exists and (instances.any? { |x| x["InstanceId"]==instance_id }))
78
+ textout.puts(val) if textout
79
+ return val, instance_id
80
+ end
81
+
82
+ def register_instance(region,lbname,instance_external_id,vpcid,nagios=false,textout=nil,verbose=nil,ufile=nil)
83
+ if ufile
84
+ ZAWS::Helper::File.prepend("zaws load_balancer deregister_instance #{lbname} #{instance_external_id} --region #{region} --vpcid my_vpc_id $XTRA_OPTS",'#Deregister instance',ufile)
85
+ end
86
+ instance_registered,instance_id = exists_instance(region,lbname,instance_external_id,vpcid,nil,verbose)
87
+ return ZAWS::Helper::Output.binary_nagios_check(instance_registered,"OK: Instance registerd.","CRITICAL: Instance not registered.",textout) if nagios
88
+ if not instance_registered
89
+ comline="aws --region #{region} elb register-instances-with-load-balancer"
90
+ comline+=" --load-balancer-name #{lbname}"
91
+ comline+=" --instances #{instance_id}"
92
+ newinstance=JSON.parse(@shellout.cli(comline,verbose))
93
+ verbose.puts "DEBUG: newinstance=#{newinstance} TODO: need to know if it is returning a json object with a return key." if verbose
94
+ textout.puts "New instance registered." if newinstance["return"] == "true"
95
+ else
96
+ textout.puts "Instance already registered. Skipping registration."
97
+ end
98
+ end
99
+
100
+ def deregister_instance(region,lbname,instance_external_id,vpcid,textout=nil,verbose=nil)
101
+ instance_registered,instance_id = exists_instance(region,lbname,instance_external_id,vpcid,nil,verbose)
102
+ if instance_registered
103
+ comline="aws --region #{region} elb deregister-instances-with-load-balancer"
104
+ comline+=" --load-balancer-name #{lbname}"
105
+ comline+=" --instances #{instance_id}"
106
+ newinstance=JSON.parse(@shellout.cli(comline,verbose))
107
+ verbose.puts "DEBUG: newinstance=#{newinstance} TODO: need to know if it is returning a json object with a return key." if verbose
108
+ textout.puts "Instance deregistered." if newinstance["return"] == "true"
109
+ else
110
+ textout.puts "Instance not registered. Skipping deregistration."
111
+ end
112
+ end
113
+
114
+ def exists_listener(region,lbname,lbprotocol,lbport,inprotocol,inport,textout=nil,verbose=nil)
115
+ lbexists,instances,ldescriptions=exists(region,lbname,nil,verbose)
116
+ verbose.puts ldescriptions if verbose
117
+ val = (lbexists and (ldescriptions.any? { |x| x["Listener"]["LoadBalancerPort"]==(lbport.to_i) && x["Listener"]["Protocol"]==lbprotocol && x["Listener"]["InstancePort"]==(inport.to_i) && x["Listener"]["InstanceProtocol"]==inprotocol }))
118
+ textout.puts(val) if textout
119
+ return val
120
+ end
121
+
122
+ def declare_listener(region,lbname,lbprotocol,lbport,inprotocol,inport,nagios=false,textout=nil,verbose=nil,ufile=nil)
123
+ if ufile
124
+ ZAWS::Helper::File.prepend("zaws load_balancer delete_listener #{lbname} #{lbprotocol} #{lbport} #{inprotocol} #{inport} --region #{region} $XTRA_OPTS",'#Delete listener',ufile)
125
+ end
126
+ lexists=exists_listener(region,lbname,lbprotocol,lbport,inprotocol,inport,nil,verbose)
127
+ return ZAWS::Helper::Output.binary_nagios_check(lexists,"OK: Listerner exists.","CRITICAL: Listener does not exist.",textout) if nagios
128
+ if not lexists
129
+ comline="aws --region #{region} elb create-load-balancer-listeners"
130
+ comline+=" --load-balancer-name #{lbname}"
131
+ comline+=" --listeners '#{calculated_listener(lbprotocol,lbport,inprotocol,inport)}'"
132
+ newlistener=JSON.parse(@shellout.cli(comline,verbose))
133
+ verbose.puts "DEBUG: newinstance=#{newlistener} TODO: need to know if it is returning a json object with a return key." if verbose
134
+ textout.puts "Listener created." if newlistener["return"] == "true"
135
+ else
136
+ textout.puts "Listerner exists. Skipping creation."
137
+ end
138
+ end
139
+
140
+ def delete_listener(region,lbname,lbprotocol,lbport,inprotocol,inport,textout=nil,verbose=nil)
141
+ lexists=exists_listener(region,lbname,lbprotocol,lbport,inprotocol,inport,nil,verbose)
142
+ if lexists
143
+ comline="aws --region #{region} elb delete-load-balancer-listeners"
144
+ comline+=" --load-balancer-name #{lbname}"
145
+ comline+=" --load-balancer-ports '#{lbport}'"
146
+ dellistener=JSON.parse(@shellout.cli(comline,verbose))
147
+ verbose.puts "DEBUG: newinstance=#{dellistener} TODO: need to know if it is returning a json object with a return key." if verbose
148
+ textout.puts "Listerner deleted." if dellistener["return"] == "true"
149
+ else
150
+ textout.puts "Listener does not exist. Skipping deletion."
151
+ end
152
+ end
153
+
154
+ end
155
+ end
156
+ end
157
+
data/lib/zaws/elb.rb ADDED
@@ -0,0 +1,20 @@
1
+ require 'json'
2
+ require 'netaddr'
3
+ require 'timeout'
4
+
5
+ module ZAWS
6
+ class ELB
7
+
8
+ def initialize(shellout,aws)
9
+ @shellout=shellout
10
+ @aws=aws
11
+ end
12
+
13
+ def load_balancer
14
+ @_load_balancer ||= (ZAWS::ELBServices::LoadBalancer.new(@shellout,@aws))
15
+ return @_load_balancer
16
+ end
17
+
18
+ end
19
+ end
20
+
@@ -0,0 +1,23 @@
1
+ module ZAWS
2
+ module Helper
3
+ class File
4
+
5
+ # This prepend function not currently unit tested,
6
+ # see "thor/spec/actions/file_manipulation_spec"
7
+ # for ideas on how to accomplish this.
8
+ def self.prepend(command,description,filepath)
9
+ new_file=filepath + ".new"
10
+ IO::File.open(new_file, 'w') do |fo|
11
+ fo.puts description
12
+ fo.puts command
13
+ IO::File.foreach(filepath) do |li|
14
+ fo.puts li
15
+ end
16
+ end
17
+ IO::File.rename(new_file, filepath)
18
+ end
19
+
20
+ end
21
+ end
22
+ end
23
+
@@ -0,0 +1,24 @@
1
+
2
+ module ZAWS
3
+ module Helper
4
+ class Option
5
+
6
+ def self.exists?(optarr,opt_hash)
7
+ optarr.all? { |opt| opt_hash[opt] }
8
+ end
9
+
10
+ def self.absent(optarr,opt_hash)
11
+ optarr.inject([]) { |missing,opt| opt_hash[opt] ? missing : missing << opt }
12
+ end
13
+
14
+ def self.exclusive?(optarr,opt_hash)
15
+ (optarr.inject(0) { |total,opt| opt_hash[opt] ? total + 1 : total }) <= 1
16
+ end
17
+
18
+ def self.minimum?(min,optarr,opt_hash)
19
+ (optarr.inject(0) { |total,opt| opt_hash[opt] ? total + 1 : total }) >= min
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,46 @@
1
+
2
+ module AWS_consts
3
+ # Color codes http://kpumuk.info/ruby-on-rails/colorizing-console-ruby-script-output/
4
+ COLOR_RED=31
5
+ COLOR_GREEN=32
6
+ COLOR_YELLOW=33
7
+ COLOR_DEFAULT=39
8
+ COLOR_BLUE=34
9
+ COLOR_CYAN=36
10
+ end
11
+
12
+ module ZAWS
13
+ module Helper
14
+ class Output
15
+
16
+ def self.colorize(text, color_code)
17
+ "\e[#{color_code}m#{text}\e[0m"
18
+ end
19
+
20
+ def self.opt_required(output,opt_arr)
21
+ opt_arr.each { |opt| output.puts(" --#{opt} required!") }
22
+ end
23
+
24
+ def self.opt_exclusive(output,opt_arr)
25
+ output.puts(" These options cannot be combined:")
26
+ opt_arr.each { |opt| output.puts(" --#{opt}") }
27
+ end
28
+
29
+ def self.opt_minimum(output,min,opt_arr)
30
+ output.puts(" At mininum, #{min} of the following is required:")
31
+ opt_arr.each { |opt| output.puts(" --#{opt}") }
32
+ end
33
+
34
+ def self.binary_nagios_check(ok_condition,ok_msg,critical_msg,textout=nil)
35
+ if ok_condition
36
+ textout.puts ok_msg if textout
37
+ return 0
38
+ else
39
+ textout.puts critical_msg if textout
40
+ return 2
41
+ end
42
+ end
43
+
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,25 @@
1
+ require 'mixlib/shellout'
2
+
3
+ module ZAWS
4
+ module Helper
5
+ class Shell
6
+
7
+ def cli(command,output=nil)
8
+ output.puts ZAWS::Helper::Output.colorize(command,AWS_consts::COLOR_BLUE) if output
9
+ list = Mixlib::ShellOut.new(command)
10
+ list.run_command
11
+ list.error!
12
+ return list.stdout
13
+ end
14
+
15
+ def if_then(condition,command,output=nil)
16
+ if not condition
17
+ output.puts ZAWS::Helper::Output.colorize(command,AWS_consts::COLOR_BLUE) if output
18
+ return nil
19
+ end
20
+ return cli(command,output)
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,36 @@
1
+ require 'json'
2
+ require 'netaddr'
3
+ require 'timeout'
4
+
5
+ module ZAWS
6
+ module Route53Services
7
+ class HostedZone
8
+
9
+ def initialize(shellout,aws)
10
+ @shellout=shellout
11
+ @aws=aws
12
+ end
13
+
14
+ def view(viewtype,textout=nil,verbose=nil)
15
+ comline="aws --output #{viewtype} route53 list-hosted-zones"
16
+ zones=@shellout.cli(comline,verbose)
17
+ textout.puts(zones) if textout
18
+ return zones
19
+ end
20
+
21
+ def view_records(viewtype,textout=nil,verbose=nil,zonename)
22
+ zones=JSON.parse(view('json',nil,verbose))
23
+ zone_id=nil
24
+ zones["HostedZones"].each { |x| zone_id = ("#{x["Name"]}"=="#{zonename}") ? x["Id"] : nil }
25
+ if zone_id
26
+ comline="aws --output #{viewtype} route53 list-resource-record-sets --hosted-zone-id #{zone_id}"
27
+ records=@shellout.cli(comline,verbose)
28
+ textout.puts(records) if textout
29
+ return records
30
+ end
31
+ end
32
+
33
+ end
34
+ end
35
+ end
36
+
@@ -0,0 +1,20 @@
1
+ require 'json'
2
+ require 'netaddr'
3
+ require 'timeout'
4
+
5
+ module ZAWS
6
+ class Route53
7
+
8
+ def initialize(shellout,aws)
9
+ @shellout=shellout
10
+ @aws=aws
11
+ end
12
+
13
+ def hosted_zone
14
+ @_hosted_zone ||= (ZAWS::Route53Services::HostedZone.new(@shellout,@aws))
15
+ return @_hosted_zone
16
+ end
17
+
18
+ end
19
+ end
20
+
@@ -0,0 +1,3 @@
1
+ module ZAWS
2
+ VERSION = "0.0.1"
3
+ end
data/lib/zaws.rb ADDED
@@ -0,0 +1,57 @@
1
+ require "zaws/version"
2
+ require "zaws/helper/option"
3
+ require "zaws/helper/output"
4
+ require "zaws/helper/shell"
5
+ require "zaws/helper/file"
6
+ require "zaws/command/subnet"
7
+ require "zaws/command/security_group"
8
+ require "zaws/command/route_table"
9
+ require "zaws/command/compute"
10
+ require "zaws/command/elasticip"
11
+ require "zaws/command/load_balancer"
12
+ require "zaws/command/hosted_zone"
13
+ require "zaws/aws"
14
+ require "zaws/ec2"
15
+ require "zaws/elb"
16
+ require "zaws/route53"
17
+ require "zaws/ec2/subnet"
18
+ require "zaws/ec2/security_group"
19
+ require "zaws/ec2/route_table"
20
+ require "zaws/ec2/compute"
21
+ require "zaws/ec2/elasticip"
22
+ require "zaws/elb/load_balancer"
23
+ require "zaws/route53/hosted_zone"
24
+ require "thor"
25
+
26
+ module ZAWS
27
+ class ZAWSCLI < Thor
28
+
29
+ desc "subnet","ec2 subnet(s)"
30
+ subcommand "subnet",ZAWS::Command::Subnet
31
+
32
+ desc "security_group","ec2 security group(s)"
33
+ subcommand "security_group",ZAWS::Command::Security_Group
34
+
35
+ desc "route_table","ec2 route table(s)"
36
+ subcommand "route_table",ZAWS::Command::Route_Table
37
+
38
+ desc "compute","ec2 compute instance(s)"
39
+ subcommand "compute",ZAWS::Command::Compute
40
+
41
+ desc "elasticip","ec2 elasticip(s)"
42
+ subcommand "elasticip",ZAWS::Command::Elasticip
43
+
44
+ desc "load_balancer","elb load balancer(s)"
45
+ subcommand "load_balancer",ZAWS::Command::Load_Balancer
46
+
47
+ desc "hosted_zone","elb hosted_zone(s)"
48
+ subcommand "hosted_zone",ZAWS::Command::Hosted_Zone
49
+
50
+ desc "version","Get the version of the Zynx AWS Automation Tool."
51
+ def version
52
+ puts "zaws version #{ZAWS::VERSION}"
53
+ end
54
+
55
+ end
56
+ end
57
+
@@ -0,0 +1,4 @@
1
+ require 'coveralls'
2
+ Coveralls.wear_merged!
3
+ require 'zaws'
4
+
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+
3
+ describe ZAWS::EC2Services::Compute do
4
+
5
+ it "add volume to instance" do
6
+
7
+ volumes = <<-eos
8
+ { "VolumeId": "vol-1234abcd" }
9
+ eos
10
+
11
+ attachvolume = <<-eos
12
+ {
13
+ "AttachTime": "YYYY-MM-DDTHH:MM:SS.000Z",
14
+ "InstanceId": "id-X",
15
+ "VolumeId": "vol-1234abcd",
16
+ "State": "attaching",
17
+ "Device": "/dev/sda" }
18
+ eos
19
+
20
+ tag_created = <<-eos
21
+ { "return":"true" }
22
+ eos
23
+
24
+ textout=double('outout')
25
+ shellout=double('ZAWS::Helper::Shell')
26
+ expect(shellout).to receive(:cli).with("aws --output json --region us-west-1 ec2 create-volume --availability-zone us-west-1a --size 70",nil).and_return(volumes)
27
+ expect(shellout).to receive(:cli).with("aws --output json --region us-west-1 ec2 create-tags --resources vol-1234abcd --tags Key=externalid,Value=extername",nil).and_return(tag_created)
28
+ expect(shellout).to receive(:cli).with("aws --output json --region us-west-1 ec2 create-tags --resources vol-1234abcd --tags Key=Name,Value=extername",nil).and_return(tag_created)
29
+ expect(shellout).to receive(:cli).with('ping -q -c 2 0.0.0.0',nil).and_return(true)
30
+ expect(shellout).to receive(:cli).with("aws --output json ec2 attach-volume --region us-west-1 --volume-id vol-1234abcd --instance-id id-X --device /dev/sda",nil).and_return(attachvolume)
31
+ aws=ZAWS::AWS.new(shellout)
32
+ bdm = aws.ec2.compute.add_volume('us-west-1','id-X','extername','0.0.0.0','/dev/sda','us-west-1a',70,nil)
33
+
34
+ end
35
+
36
+ end
37
+
38
+
39
+
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe ZAWS::EC2Services::Compute do
4
+
5
+ it "provides a block device mapping overriding the root size" do
6
+
7
+ images = <<-eos
8
+ { "Images": [
9
+ { "RootDeviceName": "/dev/sda1",
10
+ "BlockDeviceMappings": [
11
+ { "DeviceName": "/dev/sda1",
12
+ "Ebs": {
13
+ "DeleteOnTermination": true,
14
+ "SnapshotId": "snap-XXX",
15
+ "VolumeSize": 7,
16
+ "VolumeType": "standard" } } ] } ] }
17
+ eos
18
+
19
+ textout=double('outout')
20
+ shellout=double('ZAWS::Helper::Shell')
21
+ expect(shellout).to receive(:cli).with("aws --output json --region us-west-1 ec2 describe-images --owner me --image-ids X",nil).and_return(images)
22
+ aws=ZAWS::AWS.new(shellout)
23
+ bdm = aws.ec2.compute.block_device_mapping('us-west-1','me',nil,70,'X')
24
+ expect(bdm).to eq('[{"DeviceName":"/dev/sda1","Ebs":{"DeleteOnTermination":true,"SnapshotId":"snap-XXX","VolumeSize":70,"VolumeType":"standard"}}]')
25
+
26
+ end
27
+
28
+ end
29
+
30
+
31
+
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe ZAWS::EC2Services::Compute do
4
+
5
+ it "provides an instance id when you give it a external id" do
6
+
7
+ compute_instances = <<-eos
8
+ { "Reservations": [
9
+ { "Instances" : [ {"InstanceId": "i-XXXXXXX","Tags": [ { "Value": "my_instance","Key": "externalid" } ] } ] }
10
+ ] }
11
+ eos
12
+
13
+ textout=double('outout')
14
+ shellout=double('ZAWS::Helper::Shell')
15
+ expect(shellout).to receive(:cli).with("aws --output json --region us-west-1 ec2 describe-instances --filter 'Name=vpc-id,Values=my_vpc_id' 'Name=tag:externalid,Values=my_instance'",nil).and_return(compute_instances)
16
+ aws=ZAWS::AWS.new(shellout)
17
+ instanceid = aws.ec2.compute.instance_id_by_external_id('us-west-1','my_instance','my_vpc_id',nil,nil)
18
+ expect(instanceid).to eq("i-XXXXXXX")
19
+ end
20
+
21
+ end
22
+
23
+