cyoi 0.8.0 → 0.8.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a3fba8bd87ffbf411952d31cf1c8e9cabfcf8cd0
4
- data.tar.gz: 55688a09f5dba6f443ed83330eef6c0bc46349f1
3
+ metadata.gz: 36f61c51fee0e4ba9db53a34d0103b2fbf559c8d
4
+ data.tar.gz: a1695ed090fd51f46151b4d1515a6d7fc1797feb
5
5
  SHA512:
6
- metadata.gz: 6e5c897fccb38b5fb9ded020a03bd5bdb1b28346ec41945d5d63fb4d331b4f2fea8fc1d929a05b06c1484c748c1b83faaec41ee8c95568502174f6fa0fc988e8
7
- data.tar.gz: 08208b223d39521fa851a1767716c3e6c4b25242aa46917fb6438c1bc2aeb741217a4284d0121e6aef9630e7120e31d4b6169de04c2fc17f846a194407a9a53e
6
+ metadata.gz: 2db327e54b76daed99683367197ab66267e9b274b57564bd941559314eb47fa05744030aa1020732ae39222437b946745524ffc5c2cd847a6fad4d0bf11a3ade
7
+ data.tar.gz: bb1114b3ca410bf4084493448282f43b868ad37b6b57152030d66a5b7d83255d297c83353ca639b2484c9c17aadac729fbef24b1c1909424ef3570dadb5cd1b8
data/ChangeLog.md CHANGED
@@ -7,6 +7,8 @@ Cyoi (choose-your-own-infrastructure) is a library to ask an end-user to choose
7
7
  * openstack - detection of nova vs neutron networking
8
8
  * openstack nova - continues to provision a floating IP
9
9
  * openstack neutron - asks to select a subnet and then an available IP
10
+ * create_security_group can take a list of ports to open [v0.8.1]
11
+ * allow for legacy API usage of create_security_group [v0.8.2]
10
12
 
11
13
  ## v0.7
12
14
 
@@ -13,8 +13,8 @@ class Cyoi::Providers::Clients::FogProviderClient
13
13
  setup_fog_connection
14
14
  end
15
15
 
16
+ # Implement in subclasses
16
17
  def setup_fog_connection
17
- raise "must implement"
18
18
  end
19
19
 
20
20
  def create_key_pair(key_pair_name)
@@ -80,26 +80,21 @@ class Cyoi::Providers::Clients::FogProviderClient
80
80
  # Creates or reuses an security group and opens ports.
81
81
  #
82
82
  # +security_group_name+ is the name to be created or reused
83
- # +ports+ is a hash of name/port for ports to open, for example:
84
- # {
85
- # ssh: 22,
86
- # http: 80,
87
- # https: 443
88
- # }
83
+ # +ports+ is a hash of name/port for ports to open
84
+ #
89
85
  # protocol defaults to TCP
90
86
  # You can also use a more verbose +ports+ using the format:
91
- # {
92
- # ssh: 22,
93
- # http: { ports: (80..82) },
94
- # mosh: { protocol: "udp", ports: (60000..60050) }
95
- # mosh: { protocol: "rdp", ports: (3398..3398), ip_ranges: [ { cidrIp: "196.212.12.34/32" } ] }
96
- # }
87
+ # * 22,
88
+ # * { ports: (80..82) },
89
+ # * { protocol: "udp", ports: (60000..60050) }
90
+ # * { protocol: "rdp", ports: (3398..3398), ip_ranges: [ { cidrIp: "196.212.12.34/32" } ] }
91
+ #
97
92
  # In this example,
98
93
  # * TCP 22 will be opened for ssh from any ip_range,
99
94
  # * TCP ports 80, 81, 82 for http from any ip_range,
100
95
  # * UDP 60000 -> 60050 for mosh from any ip_range and
101
96
  # * TCP 3398 for RDP from ip range: 96.212.12.34/32
102
- def create_security_group(security_group_name, description, ports)
97
+ def create_security_group(security_group_name, description, defns)
103
98
  security_groups = fog_compute.security_groups
104
99
  unless sg = security_groups.find { |s| s.name == security_group_name }
105
100
  sg = fog_compute.security_groups.create(name: security_group_name, description: description)
@@ -109,12 +104,24 @@ class Cyoi::Providers::Clients::FogProviderClient
109
104
  end
110
105
  ip_permissions = ip_permissions(sg)
111
106
  ports_opened = 0
112
- ports.each do |name, port_defn|
113
- (protocol, port_range, ip_range) = extract_port_definition(port_defn)
114
- unless port_open?(ip_permissions, port_range, protocol, ip_range)
115
- authorize_port_range(sg, port_range, protocol, ip_range)
116
- puts " -> opened #{name} ports #{protocol.upcase} #{port_range.min}..#{port_range.max} from IP range #{ip_range}"
117
- ports_opened += 1
107
+
108
+ # Unnest { ports: 22 } and { ports: { ports: 22..22 }} legacy inputs
109
+ if defns.is_a?(Hash) && defns[:ports].is_a?(Hash)
110
+ defns = defns[:ports]
111
+ end
112
+
113
+ unless defns.is_a?(Array)
114
+ defns = [defns]
115
+ end
116
+ defns.each do |port_defn|
117
+ port_defns = port_defn.is_a?(Array) ? port_defn : [port_defn]
118
+ port_defns.each do |port_defn|
119
+ (protocol, port_range, ip_range) = extract_port_definition(port_defn)
120
+ unless port_open?(ip_permissions, port_range, protocol, ip_range)
121
+ authorize_port_range(sg, port_range, protocol, ip_range)
122
+ puts " -> opened #{security_group_name} ports #{protocol.upcase} #{port_range.min}..#{port_range.max} from IP range #{ip_range}"
123
+ ports_opened += 1
124
+ end
118
125
  end
119
126
  end
120
127
  puts " -> no additional ports opened" if ports_opened == 0
@@ -122,7 +129,7 @@ class Cyoi::Providers::Clients::FogProviderClient
122
129
  end
123
130
 
124
131
  def port_open?(ip_permissions, port_range, protocol, ip_range)
125
- ip_permissions && ip_permissions.find do |ip|
132
+ ip_permissions && ip_permissions.find do |ip|
126
133
  ip["ipProtocol"] == protocol \
127
134
  && ip["ipRanges"].detect { |range| range["cidrIp"] == ip_range } \
128
135
  && ip["fromPort"] <= port_range.min \
@@ -160,6 +167,9 @@ class Cyoi::Providers::Clients::FogProviderClient
160
167
  elsif port_defn.is_a? Hash
161
168
  protocol = port_defn[:protocol] if port_defn[:protocol]
162
169
  port_range = port_defn[:ports] if port_defn[:ports]
170
+ if port_range.is_a? Integer
171
+ port_range = (port_range..port_range)
172
+ end
163
173
  ip_range = port_defn[:ip_range] if port_defn[:ip_range]
164
174
  end
165
175
  [protocol, port_range, ip_range]
@@ -66,7 +66,7 @@ class Cyoi::Providers::Clients::OpenStackProviderClient < Cyoi::Providers::Clien
66
66
 
67
67
  # Hook method for FogProviderClient#create_security_group
68
68
  def ip_permissions(sg)
69
- sg.rules
69
+ sg.security_group_rules
70
70
  end
71
71
 
72
72
  # Hook method for FogProviderClient#create_security_group
data/lib/cyoi/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Cyoi
2
- VERSION = "0.8.0"
2
+ VERSION = "0.8.2"
3
3
  end
@@ -0,0 +1,121 @@
1
+ require "cyoi/providers/clients/fog_provider_client"
2
+ require "fog/openstack/models/compute/security_groups"
3
+
4
+ describe Cyoi::Providers::Clients::FogProviderClient do
5
+ let(:provider_attributes) do
6
+ {
7
+ "name" => "openstack",
8
+ "credentials" => {
9
+ "openstack_username" => "USERNAME",
10
+ "openstack_api_key" => "PASSWORD",
11
+ "openstack_tenant" => "TENANT",
12
+ "openstack_auth_url" => "http://someurl.com/v2/tokens",
13
+ "openstack_region" => "REGION"
14
+ }
15
+ }
16
+ end
17
+ let(:fog_compute) { instance_double("Fog::Compute::OpenStack::Real") }
18
+ let(:security_groups) { instance_double("Fog::Compute::OpenStack::SecurityGroups") }
19
+ let(:security_group) { instance_double("Fog::Compute::OpenStack::SecurityGroup") }
20
+ subject { Cyoi::Providers::Clients::FogProviderClient.new(provider_attributes) }
21
+
22
+ before do
23
+ expect(subject).to receive(:fog_compute).at_least(1).times.and_return(fog_compute)
24
+ end
25
+
26
+ describe "create_security_group" do
27
+ it "add new single port to new SecurityGroup" do
28
+ expect(fog_compute).to receive(:security_groups).twice.and_return(security_groups)
29
+ expect(security_groups).to receive(:find).and_return(nil)
30
+ expect(security_groups).to receive(:create).with(name: "foo", description: "foo").and_return(security_group)
31
+ expect(subject).to receive(:puts).with("Created security group foo")
32
+ expect(security_group).to receive(:ip_permissions)
33
+ expect(security_group).to receive(:authorize_port_range).with(22..22, {:ip_protocol=>"tcp", :cidr_ip=>"0.0.0.0/0"})
34
+ expect(subject).to receive(:puts).with(" -> opened foo ports TCP 22..22 from IP range 0.0.0.0/0")
35
+
36
+ subject.create_security_group("foo", "foo", 22)
37
+ end
38
+
39
+ it "add new single port by integer to existing SecurityGroup" do
40
+ expect(fog_compute).to receive(:security_groups).and_return(security_groups)
41
+ expect(security_groups).to receive(:find).and_return(security_group)
42
+ expect(subject).to receive(:puts).with("Reusing security group foo")
43
+ expect(security_group).to receive(:ip_permissions)
44
+ expect(security_group).to receive(:authorize_port_range).with(22..22, {:ip_protocol=>"tcp", :cidr_ip=>"0.0.0.0/0"})
45
+ expect(subject).to receive(:puts).with(" -> opened foo ports TCP 22..22 from IP range 0.0.0.0/0")
46
+
47
+ subject.create_security_group("foo", "foo", 22)
48
+ end
49
+
50
+ context 'legacy API used by old bosh-bootstrap - allow :ports key' do
51
+ it "add new single port by :ports key to existing SecurityGroup" do
52
+ expect(fog_compute).to receive(:security_groups).and_return(security_groups)
53
+ expect(security_groups).to receive(:find).and_return(security_group)
54
+ expect(subject).to receive(:puts).with("Reusing security group foo")
55
+ expect(security_group).to receive(:ip_permissions)
56
+ expect(security_group).to receive(:authorize_port_range).with(22..22, {:ip_protocol=>"tcp", :cidr_ip=>"0.0.0.0/0"})
57
+ expect(subject).to receive(:puts).with(" -> opened foo ports TCP 22..22 from IP range 0.0.0.0/0")
58
+
59
+ subject.create_security_group("foo", "foo", ports: 22)
60
+ end
61
+
62
+ it "add UDP ports by :ports key" do
63
+ expect(fog_compute).to receive(:security_groups).and_return(security_groups)
64
+ expect(security_groups).to receive(:find).and_return(security_group)
65
+ expect(subject).to receive(:puts).with("Reusing security group foo")
66
+ expect(security_group).to receive(:ip_permissions)
67
+ expect(security_group).to receive(:authorize_port_range).with(53..53, {:ip_protocol=>"udp", :cidr_ip=>"0.0.0.0/0"})
68
+ expect(subject).to receive(:puts).with(" -> opened foo ports UDP 53..53 from IP range 0.0.0.0/0")
69
+
70
+ subject.create_security_group("foo", "foo", ports: { protocol: "udp", ports: (53..53) })
71
+ end
72
+ end
73
+
74
+ it "add skip existing single port on existing SecurityGroup" do
75
+ expect(fog_compute).to receive(:security_groups).and_return(security_groups)
76
+ expect(security_groups).to receive(:find).and_return(security_group)
77
+ expect(subject).to receive(:puts).with("Reusing security group foo")
78
+ expect(security_group).to receive(:ip_permissions).and_return([{"fromPort"=>22, "toPort"=>22, "ipRanges"=>[{"cidrIp" => "0.0.0.0/0"}], "ipProtocol"=>"tcp"}])
79
+ expect(subject).to receive(:puts).with(" -> no additional ports opened")
80
+
81
+ subject.create_security_group("foo", "foo", 22)
82
+ end
83
+
84
+ it "add new range of ports" do
85
+ expect(fog_compute).to receive(:security_groups).and_return(security_groups)
86
+ expect(security_groups).to receive(:find).and_return(security_group)
87
+ expect(subject).to receive(:puts).with("Reusing security group foo")
88
+ expect(security_group).to receive(:ip_permissions)
89
+ expect(security_group).to receive(:authorize_port_range).with(60000..60050, {:ip_protocol=>"tcp", :cidr_ip=>"0.0.0.0/0"})
90
+ expect(subject).to receive(:puts).with(" -> opened foo ports TCP 60000..60050 from IP range 0.0.0.0/0")
91
+
92
+ subject.create_security_group("foo", "foo", ports: 60000..60050)
93
+ end
94
+
95
+ it "add UDP ports" do
96
+ expect(fog_compute).to receive(:security_groups).and_return(security_groups)
97
+ expect(security_groups).to receive(:find).and_return(security_group)
98
+ expect(subject).to receive(:puts).with("Reusing security group foo")
99
+ expect(security_group).to receive(:ip_permissions)
100
+ expect(security_group).to receive(:authorize_port_range).with(53..53, {:ip_protocol=>"udp", :cidr_ip=>"0.0.0.0/0"})
101
+ expect(subject).to receive(:puts).with(" -> opened foo ports UDP 53..53 from IP range 0.0.0.0/0")
102
+
103
+ subject.create_security_group("foo", "foo", { protocol: "udp", ports: (53..53) })
104
+ end
105
+
106
+ it "add list of unrelated ports" do
107
+ expect(fog_compute).to receive(:security_groups).and_return(security_groups)
108
+ expect(security_groups).to receive(:find).and_return(security_group)
109
+ expect(subject).to receive(:puts).with("Reusing security group foo")
110
+ expect(security_group).to receive(:ip_permissions)
111
+ expect(security_group).to receive(:authorize_port_range).with(22..22, {:ip_protocol=>"tcp", :cidr_ip=>"0.0.0.0/0"})
112
+ expect(security_group).to receive(:authorize_port_range).with(443..443, {:ip_protocol=>"tcp", :cidr_ip=>"0.0.0.0/0"})
113
+ expect(security_group).to receive(:authorize_port_range).with(4443..4443, {:ip_protocol=>"tcp", :cidr_ip=>"0.0.0.0/0"})
114
+ expect(subject).to receive(:puts).with(" -> opened foo ports TCP 22..22 from IP range 0.0.0.0/0")
115
+ expect(subject).to receive(:puts).with(" -> opened foo ports TCP 443..443 from IP range 0.0.0.0/0")
116
+ expect(subject).to receive(:puts).with(" -> opened foo ports TCP 4443..4443 from IP range 0.0.0.0/0")
117
+
118
+ subject.create_security_group("foo", "foo", [22, 443, 4443])
119
+ end
120
+ end
121
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cyoi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dr Nic Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-06 00:00:00.000000000 Z
11
+ date: 2014-02-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fog
@@ -192,6 +192,7 @@ files:
192
192
  - spec/unit/.gitkeep
193
193
  - spec/unit/cli/image_spec.rb
194
194
  - spec/unit/cli/key_pair_spec.rb
195
+ - spec/unit/providers/clients/fog_provider_client_spec.rb
195
196
  - spec/unit/providers/clients/openstack_provider_client_spec.rb
196
197
  homepage: https://github.com/drnic/cyoi
197
198
  licenses:
@@ -239,4 +240,5 @@ test_files:
239
240
  - spec/unit/.gitkeep
240
241
  - spec/unit/cli/image_spec.rb
241
242
  - spec/unit/cli/key_pair_spec.rb
243
+ - spec/unit/providers/clients/fog_provider_client_spec.rb
242
244
  - spec/unit/providers/clients/openstack_provider_client_spec.rb