2017-12-14 14:28:29 +00:00
require 'helper'
# MESGSB = MockEc2SecurityGroupSingleBackend
# Abbreviation not used outside this file
#=============================================================================#
# Constructor Tests
#=============================================================================#
2018-02-08 04:23:05 +00:00
class AwsSGSConstructor < Minitest :: Test
2017-12-14 14:28:29 +00:00
def setup
2018-02-08 04:23:05 +00:00
AwsSecurityGroup :: BackendFactory . select ( AwsMESGSB :: Empty )
2017-12-14 14:28:29 +00:00
end
2019-01-21 21:05:46 +00:00
2017-12-14 14:28:29 +00:00
def test_constructor_no_args_raises
2018-02-08 04:23:05 +00:00
assert_raises ( ArgumentError ) { AwsSecurityGroup . new }
2017-12-14 14:28:29 +00:00
end
def test_constructor_accept_scalar_param
2018-02-08 04:23:05 +00:00
AwsSecurityGroup . new ( 'sg-12345678' )
2017-12-14 14:28:29 +00:00
end
def test_constructor_expected_well_formed_args
{
id : 'sg-1234abcd' ,
group_id : 'sg-1234abcd' ,
vpc_id : 'vpc-1234abcd' ,
group_name : 'some-group' ,
2019-01-21 21:05:46 +00:00
} . each do | param , value |
2018-02-08 04:23:05 +00:00
AwsSecurityGroup . new ( param = > value )
2017-12-14 14:28:29 +00:00
end
end
def test_constructor_reject_malformed_args
{
id : 'sg-xyz-123' ,
group_id : '1234abcd' ,
vpc_id : 'vpc_1234abcd' ,
2019-01-21 21:05:46 +00:00
} . each do | param , value |
2018-02-08 04:23:05 +00:00
assert_raises ( ArgumentError ) { AwsSecurityGroup . new ( param = > value ) }
2017-12-14 14:28:29 +00:00
end
end
def test_constructor_reject_unknown_resource_params
2018-02-08 04:23:05 +00:00
assert_raises ( ArgumentError ) { AwsSecurityGroup . new ( beep : 'boop' ) }
2017-12-14 14:28:29 +00:00
end
end
#=============================================================================#
# Properties
#=============================================================================#
2018-02-08 04:23:05 +00:00
class AwsSGSProperties < Minitest :: Test
2017-12-14 14:28:29 +00:00
def setup
2018-02-08 04:23:05 +00:00
AwsSecurityGroup :: BackendFactory . select ( AwsMESGSB :: Basic )
2017-12-14 14:28:29 +00:00
end
2019-01-21 21:05:46 +00:00
2017-12-14 14:28:29 +00:00
def test_property_group_id
2018-02-08 04:23:05 +00:00
assert_equal ( 'sg-12345678' , AwsSecurityGroup . new ( 'sg-12345678' ) . group_id )
assert_nil ( AwsSecurityGroup . new ( group_name : 'my-group' ) . group_id )
2017-12-14 14:28:29 +00:00
end
def test_property_group_name
2018-02-08 04:23:05 +00:00
assert_equal ( 'beta' , AwsSecurityGroup . new ( 'sg-12345678' ) . group_name )
assert_nil ( AwsSecurityGroup . new ( 'sg-87654321' ) . group_name )
2017-12-14 14:28:29 +00:00
end
def test_property_vpc_id
2018-02-08 04:23:05 +00:00
assert_equal ( 'vpc-aaaabbbb' , AwsSecurityGroup . new ( 'sg-aaaabbbb' ) . vpc_id )
assert_nil ( AwsSecurityGroup . new ( 'sg-87654321' ) . vpc_id )
2017-12-14 14:28:29 +00:00
end
def test_property_description
2018-02-08 04:23:05 +00:00
assert_equal ( 'Awesome Group' , AwsSecurityGroup . new ( 'sg-12345678' ) . description )
assert_nil ( AwsSecurityGroup . new ( 'sg-87654321' ) . description )
2017-12-14 14:28:29 +00:00
end
2018-04-06 18:22:25 +00:00
def test_property_inbound_rules
assert_empty ( AwsSecurityGroup . new ( 'sg-87654321' ) . inbound_rules )
rules = AwsSecurityGroup . new ( 'sg-12345678' ) . inbound_rules
assert_kind_of ( Array , rules )
assert_kind_of ( Hash , rules [ 0 ] )
end
def test_property_outbound_rules
assert_empty ( AwsSecurityGroup . new ( 'sg-87654321' ) . outbound_rules )
rules = AwsSecurityGroup . new ( 'sg-12345678' ) . outbound_rules
assert_kind_of ( Array , rules )
assert_kind_of ( Hash , rules [ 0 ] )
end
2018-09-18 20:21:41 +00:00
def test_property_inbound_rules_count
assert_equal ( 0 , AwsSecurityGroup . new ( 'sg-aaaabbbb' ) . inbound_rules_count )
count = AwsSecurityGroup . new ( 'sg-12345678' ) . inbound_rules_count
assert_equal ( 7 , count )
assert_kind_of ( Numeric , count )
end
def test_property_outbound_rules_count
assert_equal ( 0 , AwsSecurityGroup . new ( 'sg-aaaabbbb' ) . outbound_rules_count )
count = AwsSecurityGroup . new ( 'sg-12345678' ) . outbound_rules_count
assert_equal ( 2 , count )
assert_kind_of ( Numeric , count )
end
2017-12-14 14:28:29 +00:00
end
2018-04-06 18:22:25 +00:00
#=============================================================================#
# Matchers
#=============================================================================#
2019-01-21 21:05:46 +00:00
class AwsSGSMatchers < Minitest :: Test
2018-04-06 18:22:25 +00:00
def setup
AwsSecurityGroup :: BackendFactory . select ( AwsMESGSB :: Basic )
end
def test_matcher_allow_criteria_validation
sg = AwsSecurityGroup . new ( 'sg-aaaabbbb' )
rules = sg . inbound_rules
assert_raises ( ArgumentError , " allow should reject unrecognized criteria " ) { sg . allow_in? ( shoe_size : 9 ) }
[
:from_port ,
:ipv4_range ,
:port ,
:position ,
:protocol ,
:to_port ,
2018-11-13 18:25:33 +00:00
:security_group ,
2018-04-06 18:22:25 +00:00
] . each do | criterion |
# No errors here
sg . allow_in? ( criterion = > 'dummy' )
end
end
def test_matcher_allow_inbound_empty
sg = AwsSecurityGroup . new ( 'sg-aaaabbbb' )
rules = sg . inbound_rules
assert_equal ( 0 , rules . count )
2018-11-13 18:25:33 +00:00
refute ( sg . allow_in? ( ) ) # Should we test this - "open" criteria?
2018-04-06 18:22:25 +00:00
end
def test_matcher_allow_inbound_complex
sg = AwsSecurityGroup . new ( 'sg-12345678' )
assert_equal ( 3 , sg . inbound_rules . count , " count the number of rules for 3-rule group " )
# Position pinning
assert ( sg . allow_in? ( ipv4_range : " 10.1.4.0/24 " , position : 2 ) , " use numeric position " )
assert ( sg . allow_in? ( ipv4_range : " 10.1.4.0/24 " , position : " 2 " ) , " use string position " )
assert ( sg . allow_in? ( ipv4_range : " 10.2.0.0/16 " , position : :last ) , " use :last position " )
assert ( sg . allow_in? ( port : 22 , position : :first ) , " use :first position " )
# Port
assert ( sg . allow_in? ( port : 22 ) , " match on a numeric port " )
assert ( sg . allow_in? ( port : " 22 " ) , " match on a string port " )
assert ( sg . allow_in? ( to_port : " 22 " , from_port : " 22 " ) , " match on to/from port " )
assert ( sg . allow_in? ( port : 9002 , position : 3 ) , " range matching on port with allow_in " )
refute ( sg . allow_in_only? ( port : 9002 , position : 3 ) , " no range matching on port with allow_in_only " )
assert ( sg . allow_in_only? ( from_port : 9001 , to_port : 9003 , position : 3 ) , " exact range matching on port with allow_in_only " )
# Protocol
2019-01-21 21:05:46 +00:00
assert ( sg . allow_in? ( protocol : 'tcp' ) , " match on tcp protocol, unpinned " )
2018-04-06 18:22:25 +00:00
assert ( sg . allow_in? ( protocol : 'tcp' , position : 1 ) , " match on tcp protocol " )
assert ( sg . allow_in? ( protocol : 'any' , position : 2 ) , " match on our 'any' alias protocol " )
assert ( sg . allow_in? ( protocol : '-1' , position : 2 ) , " match on AWS spec '-1 for any' protocol " )
# IPv4 range testing
assert ( sg . allow_in? ( ipv4_range : [ " 10.1.4.0/24 " ] ) , " match on 1 ipv4 range as array " )
assert ( sg . allow_in? ( ipv4_range : [ " 10.1.4.33/32 " ] ) , " match on 1 ipv4 range subnet membership " )
assert ( sg . allow_in? ( ipv4_range : [ " 10.1.4.33/32 " , " 10.1.4.82/32 " ] ) , " match on 2 addrs ipv4 range subnet membership " )
assert ( sg . allow_in? ( ipv4_range : [ " 10.1.4.0/25 " , " 10.1.4.128/25 " ] ) , " match on 2 subnets ipv4 range subnet membership " )
assert ( sg . allow_in_only? ( ipv4_range : " 10.1.4.0/24 " , position : 2 ) , " exact match on 1 ipv4 range with _only " )
refute ( sg . allow_in_only? ( ipv4_range : " 10.1.4.33/32 " , position : 2 ) , " no range membership ipv4 range with _only " )
assert ( sg . allow_in? ( ipv4_range : " 10.1.2.0/24 " ) , " match on a list ipv4 range when providing only one value (first) " )
assert ( sg . allow_in? ( ipv4_range : " 10.1.3.0/24 " ) , " match on a list ipv4 range when providing only one value (last) " )
assert ( sg . allow_in? ( ipv4_range : [ " 10.1.2.33/32 " , " 10.1.3.33/32 " ] ) , " match on a list of single IPs against a list of subnets " )
assert ( sg . allow_in? ( ipv4_range : [ " 10.1.2.0/24 " , " 10.1.3.0/24 " ] ) )
refute ( sg . allow_in? ( ipv4_range : [ " 10.1.22.0/24 " , " 10.1.33.0/24 " ] ) )
assert ( sg . allow_in? ( ipv4_range : [ " 10.1.3.0/24 " , " 10.1.2.0/24 " ] ) ) # Order is ignored
assert ( sg . allow_in_only? ( ipv4_range : [ " 10.1.2.0/24 " , " 10.1.3.0/24 " ] , position : 1 ) )
refute ( sg . allow_in_only? ( ipv4_range : [ " 10.1.2.0/24 " ] , position : 1 ) )
refute ( sg . allow_in_only? ( ipv4_range : [ " 10.1.3.0/24 " ] , position : 1 ) )
2018-09-18 20:21:41 +00:00
# IPv6 range testing
assert ( sg . allow_in? ( ipv6_range : [ " 2001:db8::/122 " ] ) , " match on 1 ipv6 range as array " )
assert ( sg . allow_in? ( ipv6_range : [ " 2001:db8::20/128 " ] ) , " match on 1 ipv6 range subnet membership " )
assert ( sg . allow_in? ( ipv6_range : [ " 2001:db8::20/128 " , " 2001:db8::3f/128 " ] ) , " match on 2 addrs ipv6 range subnet membership " )
assert ( sg . allow_in? ( ipv6_range : [ " 2001:db8::/128 " , " 1968:db8::/124 " ] ) , " match on 2 subnets ipv6 range subnet membership " )
assert ( sg . allow_in_only? ( ipv6_range : " 2018:db8::/122 " , position : 2 ) , " exact match on 1 ipv6 range with _only " )
refute ( sg . allow_in_only? ( ipv6_range : " 2001:db8::20/128 " , position : 2 ) , " no range membership ipv6 range with _only " )
2018-04-06 18:22:25 +00:00
# Test _only with a 3-rule group, but omitting position
refute ( sg . allow_in_only? ( port : 22 ) , " _only will fail a multi-rule SG even if it has matching criteria " )
refute ( sg . allow_in_only? ( ) , " _only will fail a multi-rule SG even if it has match-any criteria " )
# Test _only with a single rule group (ie, omitting position)
sg = AwsSecurityGroup . new ( 'sg-22223333' )
assert_equal ( 1 , sg . inbound_rules . count , " count the number of rules for 1-rule group " )
2018-09-18 20:21:41 +00:00
assert_equal ( 1 , sg . inbound_rules_count , " Count the number of rule variants for 1-rule group " )
2018-04-06 18:22:25 +00:00
assert ( sg . allow_in_only? ( ipv4_range : " 0.0.0.0/0 " ) , " Match IP range using _only on 1-rule group " )
assert ( sg . allow_in_only? ( protocol : 'any' ) , " Match protocol using _only on 1-rule group " )
refute ( sg . allow_in_only? ( port : 22 ) , " no match port using _only on 1-rule group " )
2018-09-18 20:21:41 +00:00
# Test _only with a single rule group for IPv6
sg = AwsSecurityGroup . new ( 'sg-33334444' )
assert_equal ( 1 , sg . inbound_rules . count , " count the number of rules for 1-rule ipv6 group " )
2018-11-13 18:25:33 +00:00
assert_equal ( 1 , sg . inbound_rules_count , " Count the number of rule variants for 1-rule ipv6 group " )
2018-09-18 20:21:41 +00:00
assert ( sg . allow_in_only? ( ipv6_range : " ::/0 " ) , " Match IP range using _only on 1-rule ipv6 group " )
assert ( sg . allow_in_only? ( protocol : 'any' ) , " Match protocol using _only on 1-rule ipv6 group " )
refute ( sg . allow_in_only? ( port : 22 ) , " no match port using _only on 1-rule ipv6 group " )
2018-11-13 18:25:33 +00:00
# security-group
sg = AwsSecurityGroup . new ( 'sg-55556666' )
assert ( sg . allow_in? ( security_group : " sg-33334441 " ) , " match on group-id " )
assert ( sg . allow_in? ( security_group : " sg-33334441 " , port : 22 ) , " match on group-id, numeric port " )
assert ( sg . allow_in? ( security_group : " sg-33334441 " , port : " 22 " ) , " match on group-id, string port " )
assert ( sg . allow_in? ( security_group : " sg-33334441 " , to_port : " 22 " , from_port : " 22 " ) , " match on group-id, to/from port " )
assert ( sg . allow_in? ( port : 9002 , position : 3 ) , " range matching on port with allow_in " )
refute ( sg . allow_in_only? ( port : 9002 , position : 3 ) , " no range matching on port with allow_in_only " )
refute ( sg . allow_in_only? ( security_group : " sg-33334441 " , ) , " no matching on group with allow_in_only when multiple group rules " )
assert ( sg . allow_in_only? ( from_port : 9001 , to_port : 9003 , position : 3 ) , " exact range matching on port with allow_in_only " )
# Test _only with a single rule group for security-group
sg = AwsSecurityGroup . new ( 'sg-33334441' )
assert_equal ( 1 , sg . inbound_rules . count , " count the number of rules for 1-rule security-group " )
assert_equal ( 1 , sg . inbound_rules_count , " Count the number of rule variants for 1-rule security-group " )
assert ( sg . allow_in_only? ( security_group : " sg-33334444 " ) , " Match security-group using _only on 1-rule security-group " )
assert ( sg . allow_in_only? ( protocol : 'any' , security_group : " sg-33334444 " ) , " Match protocol using _only on 1-rule security-group " )
refute ( sg . allow_in_only? ( port : 22 , security_group : " sg-33334444 " ) , " no match port using _only on 1-rule security-group " )
# Test _only with a single rule group for security-group with position pinning
sg = AwsSecurityGroup . new ( 'sg-33334442' )
assert ( sg . allow_in_only? ( security_group : " sg-33334444 " , position : 2 ) , " Match security-group using _only with numerical position " )
assert ( sg . allow_in_only? ( protocol : 'any' , security_group : " sg-33334444 " , position : 2 ) , " Match protocol using _only on 1-rule security-group with numerical position " )
refute ( sg . allow_in_only? ( port : 22 , security_group : " sg-33334444 " , position : 2 ) , " no match port using _only on 1-rule security-group with numerical position " )
assert ( sg . allow_in_only? ( security_group : " sg-33334444 " , position : " 2 " ) , " Match security-group using _only with string position " )
assert ( sg . allow_in_only? ( security_group : " sg-33334444 " , position : :last ) , " Match security-group using _only with last position " )
2018-04-06 18:22:25 +00:00
end
end
2017-12-14 14:28:29 +00:00
#=============================================================================#
# Test Fixtures
#=============================================================================#
module AwsMESGSB
2018-02-08 04:26:37 +00:00
class Empty < AwsBackendBase
2017-12-14 14:28:29 +00:00
def describe_security_groups ( _query )
OpenStruct . new ( {
security_groups : [ ] ,
} )
end
end
2018-02-08 04:26:37 +00:00
class Basic < AwsBackendBase
2017-12-14 14:28:29 +00:00
def describe_security_groups ( query )
fixtures = [
OpenStruct . new ( {
description : 'Some Group' ,
group_id : 'sg-aaaabbbb' ,
group_name : 'alpha' ,
vpc_id : 'vpc-aaaabbbb' ,
2018-04-06 18:22:25 +00:00
ip_permissions : [ ] ,
ip_permissions_egress : [ ] ,
2017-12-14 14:28:29 +00:00
} ) ,
OpenStruct . new ( {
2018-04-06 18:22:25 +00:00
description : 'Awesome Group' ,
2017-12-14 14:28:29 +00:00
group_id : 'sg-12345678' ,
group_name : 'beta' ,
vpc_id : 'vpc-12345678' ,
2018-04-06 18:22:25 +00:00
ip_permissions : [
OpenStruct . new ( {
from_port : 22 ,
to_port : 22 ,
ip_protocol : 'tcp' ,
ip_ranges : [
2019-01-21 21:05:46 +00:00
# Apparently AWS returns these as plain hashes,
2018-04-06 18:22:25 +00:00
# nested in two levels of Structs.
{ cidr_ip : " 10.1.2.0/24 " } ,
{ cidr_ip : " 10.1.3.0/24 " } ,
2018-09-18 20:21:41 +00:00
] ,
ipv_6_ranges : [
{ cidr_ipv_6 : " 2001:db8::/122 " } ,
{ cidr_ipv_6 : " 1968:db8::/124 " } ,
] ,
2018-04-06 18:22:25 +00:00
} ) ,
OpenStruct . new ( {
from_port : nil ,
to_port : nil ,
ip_protocol : " -1 " ,
ip_ranges : [
{ cidr_ip : " 10.1.4.0/24 " } ,
2018-09-18 20:21:41 +00:00
] ,
ipv_6_ranges : [
{ cidr_ipv_6 : " 2018:db8::/122 " }
2018-04-06 18:22:25 +00:00
]
} ) ,
OpenStruct . new ( {
from_port : 9001 ,
to_port : 9003 ,
ip_protocol : " udp " ,
ip_ranges : [
{ cidr_ip : " 10.2.0.0/16 " } ,
]
} ) ,
] ,
ip_permissions_egress : [
OpenStruct . new ( {
from_port : 123 ,
to_port : 123 ,
ip_protocol : " udp " ,
ip_ranges : [
{ cidr_ip : " 128.138.140.44/32 " } ,
2018-09-18 20:21:41 +00:00
] ,
ipv_6_ranges : [
{ cidr_ipv_6 : " 2001:db8::/122 " }
2018-04-06 18:22:25 +00:00
]
} ) ,
2019-01-21 21:05:46 +00:00
] ,
2018-04-06 18:22:25 +00:00
} ) ,
OpenStruct . new ( {
description : 'Open Group' ,
group_id : 'sg-22223333' ,
group_name : 'gamma' ,
vpc_id : 'vpc-12345678' ,
ip_permissions : [
OpenStruct . new ( {
from_port : nil ,
to_port : nil ,
ip_protocol : " -1 " ,
ip_ranges : [
{ cidr_ip : " 0.0.0.0/0 " } ,
]
} ) ,
] ,
2019-01-21 21:05:46 +00:00
ip_permissions_egress : [ ] ,
2017-12-14 14:28:29 +00:00
} ) ,
2018-09-18 20:21:41 +00:00
OpenStruct . new ( {
description : 'Open Group' ,
group_id : 'sg-33334444' ,
group_name : 'delta' ,
vpc_id : 'vpc-12345678' ,
ip_permissions : [
OpenStruct . new ( {
from_port : nil ,
to_port : nil ,
ip_protocol : " -1 " ,
ipv_6_ranges : [
{ cidr_ipv_6 : " ::/0 " } ,
]
} ) ,
] ,
ip_permissions_egress : [ ] ,
2018-11-13 18:25:33 +00:00
} ) ,
OpenStruct . new ( {
description : 'Open for group one group rule second position' ,
group_id : 'sg-33334442' ,
group_name : 'etha' ,
vpc_id : 'vpc-12345678' ,
ip_permissions : [
OpenStruct . new ( {
from_port : nil ,
to_port : nil ,
ip_protocol : " -1 " ,
ipv_6_ranges : [
{ cidr_ipv_6 : " ::/0 " } ,
]
} ) ,
OpenStruct . new ( {
from_port : nil ,
to_port : nil ,
ip_protocol : " -1 " ,
user_id_group_pairs : [
OpenStruct . new ( {
description : 'Open for group one rule second position' ,
group_id : 'sg-33334444' ,
group_name : 'delta' ,
peering_status : " " ,
user_id : " 123456789012 " ,
vpc_id : " " ,
vpc_peering_connection_id : " "
} ) ,
]
} ) ,
] ,
ip_permissions_egress : [ ] ,
} ) ,
OpenStruct . new ( {
description : 'Open for group one rule' ,
group_id : 'sg-33334441' ,
group_name : 'zeta' ,
vpc_id : 'vpc-12345678' ,
ip_permissions : [
OpenStruct . new ( {
from_port : nil ,
to_port : nil ,
ip_protocol : " -1 " ,
user_id_group_pairs : [
OpenStruct . new ( {
description : 'Open for group one rule' ,
group_id : 'sg-33334444' ,
group_name : 'delta' ,
peering_status : " " ,
user_id : '123456789012' ,
vpc_id : " " ,
vpc_peering_connection_id : " "
} ) ,
]
} ) ,
] ,
ip_permissions_egress : [ ] ,
} ) ,
OpenStruct . new ( {
description : 'Open for group' ,
group_id : 'sg-55556666' ,
group_name : 'epsilon' ,
vpc_id : 'vpc-12345678' ,
ip_permissions : [
OpenStruct . new ( {
from_port : 80 ,
to_port : 443 ,
ip_protocol : " -1 " ,
ip_ranges : [
{ cidr_ip : " 0.0.0.0/0 " } ,
]
} ) ,
OpenStruct . new ( {
from_port : 22 ,
to_port : 22 ,
ip_protocol : " -1 " ,
user_id_group_pairs : [
OpenStruct . new ( {
description : 'Open for group rule 2' ,
group_id : 'sg-33334441' ,
group_name : 'zeta' ,
peering_status : " " ,
user_id : '123456789012' ,
vpc_id : " " ,
vpc_peering_connection_id : " "
} ) ,
]
} ) ,
OpenStruct . new ( {
from_port : 9001 ,
to_port : 9003 ,
ip_protocol : " -1 " ,
user_id_group_pairs : [
OpenStruct . new ( {
description : 'Open for group rule 3' ,
group_id : 'sg-33334441' ,
group_name : 'zeta' ,
peering_status : " " ,
user_id : '123456789012' ,
vpc_id : " " ,
vpc_peering_connection_id : " "
} ) ,
]
} ) ,
OpenStruct . new ( {
from_port : nil ,
to_port : nil ,
ip_protocol : " -1 " ,
user_id_group_pairs : [
OpenStruct . new ( {
description : 'allow all from multiple sg' ,
group_id : 'sg-33334441' ,
group_name : 'zeta' ,
peering_status : " " ,
user_id : '123456789012' ,
vpc_id : " " ,
vpc_peering_connection_id : " "
} ) ,
OpenStruct . new ( {
description : 'allow all from multiple sg[2]' ,
group_id : 'sg-33334442' ,
group_name : 'etha' ,
peering_status : " " ,
user_id : '123456789012' ,
vpc_id : " " ,
vpc_peering_connection_id : " "
} ) ,
OpenStruct . new ( {
description : 'allow all from multiple sg[3]' ,
group_id : 'sg-11112222' ,
group_name : 'theta' ,
peering_status : " " ,
user_id : '123456789012' ,
vpc_id : " " ,
vpc_peering_connection_id : " "
} ) ,
]
} ) ,
] ,
ip_permissions_egress : [ ] ,
2018-09-18 20:21:41 +00:00
} ) , ]
2017-12-14 14:28:29 +00:00
selected = fixtures . select do | sg |
query [ :filters ] . all? do | filter |
filter [ :values ] . include? ( sg [ filter [ :name ] . tr ( '-' , '_' ) ] )
end
end
OpenStruct . new ( { security_groups : selected } )
end
end
end