github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/aws/resource_aws_security_group_rules_matching_test.go (about)

     1  package aws
     2  
     3  import (
     4  	"log"
     5  	"testing"
     6  
     7  	"github.com/hashicorp/terraform/helper/schema"
     8  )
     9  
    10  // testing rulesForGroupPermissions
    11  func TestRulesMixedMatching(t *testing.T) {
    12  	cases := []struct {
    13  		groupId string
    14  		local   []interface{}
    15  		remote  []map[string]interface{}
    16  		saves   []map[string]interface{}
    17  	}{
    18  		{
    19  			local: []interface{}{
    20  				map[string]interface{}{
    21  					"from_port":       80,
    22  					"to_port":         8000,
    23  					"protocol":        "tcp",
    24  					"cidr_blocks":     []interface{}{"172.8.0.0/16", "10.0.0.0/16"},
    25  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
    26  				},
    27  			},
    28  			remote: []map[string]interface{}{
    29  				map[string]interface{}{
    30  					"from_port":       int64(80),
    31  					"to_port":         int64(8000),
    32  					"protocol":        "tcp",
    33  					"cidr_blocks":     []string{"172.8.0.0/16", "10.0.0.0/16"},
    34  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
    35  				},
    36  			},
    37  			saves: []map[string]interface{}{
    38  				map[string]interface{}{
    39  					"from_port":       80,
    40  					"to_port":         8000,
    41  					"protocol":        "tcp",
    42  					"cidr_blocks":     []string{"172.8.0.0/16", "10.0.0.0/16"},
    43  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
    44  				},
    45  			},
    46  		},
    47  		{
    48  			local: []interface{}{
    49  				map[string]interface{}{
    50  					"from_port":       80,
    51  					"to_port":         8000,
    52  					"protocol":        "tcp",
    53  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
    54  				},
    55  			},
    56  			remote: []map[string]interface{}{
    57  				map[string]interface{}{
    58  					"from_port":       int64(80),
    59  					"to_port":         int64(8000),
    60  					"protocol":        "tcp",
    61  					"cidr_blocks":     []string{"172.8.0.0/16", "10.0.0.0/16"},
    62  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
    63  				},
    64  			},
    65  			saves: []map[string]interface{}{
    66  				map[string]interface{}{
    67  					"from_port":       80,
    68  					"to_port":         8000,
    69  					"protocol":        "tcp",
    70  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
    71  				},
    72  				map[string]interface{}{
    73  					"from_port":   int64(80),
    74  					"to_port":     int64(8000),
    75  					"protocol":    "tcp",
    76  					"cidr_blocks": []string{"172.8.0.0/16", "10.0.0.0/16"},
    77  				},
    78  			},
    79  		},
    80  		{
    81  			local: []interface{}{
    82  				map[string]interface{}{
    83  					"from_port":   80,
    84  					"to_port":     8000,
    85  					"protocol":    "tcp",
    86  					"cidr_blocks": []interface{}{"172.8.0.0/16", "10.0.0.0/16"},
    87  				},
    88  			},
    89  			remote: []map[string]interface{}{
    90  				map[string]interface{}{
    91  					"from_port":   int64(80),
    92  					"to_port":     int64(8000),
    93  					"protocol":    "tcp",
    94  					"cidr_blocks": []string{"172.8.0.0/16", "10.0.0.0/16"},
    95  				},
    96  			},
    97  			saves: []map[string]interface{}{
    98  				map[string]interface{}{
    99  					"from_port":   80,
   100  					"to_port":     8000,
   101  					"protocol":    "tcp",
   102  					"cidr_blocks": []string{"172.8.0.0/16", "10.0.0.0/16"},
   103  				},
   104  			},
   105  		},
   106  		{
   107  			local: []interface{}{
   108  				map[string]interface{}{
   109  					"from_port":       80,
   110  					"to_port":         8000,
   111  					"protocol":        "tcp",
   112  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
   113  				},
   114  			},
   115  			remote: []map[string]interface{}{
   116  				map[string]interface{}{
   117  					"from_port":       int64(80),
   118  					"to_port":         int64(8000),
   119  					"protocol":        "tcp",
   120  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
   121  				},
   122  			},
   123  			saves: []map[string]interface{}{
   124  				map[string]interface{}{
   125  					"from_port":       80,
   126  					"to_port":         8000,
   127  					"protocol":        "tcp",
   128  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
   129  				},
   130  			},
   131  		},
   132  		{
   133  			local: []interface{}{
   134  				map[string]interface{}{
   135  					"from_port":   80,
   136  					"to_port":     8000,
   137  					"protocol":    "tcp",
   138  					"cidr_blocks": []interface{}{"172.8.0.0/16"},
   139  				},
   140  				map[string]interface{}{
   141  					"from_port":   80,
   142  					"to_port":     8000,
   143  					"protocol":    "tcp",
   144  					"cidr_blocks": []interface{}{"192.168.0.0/16"},
   145  				},
   146  			},
   147  			remote: []map[string]interface{}{
   148  				map[string]interface{}{
   149  					"from_port":   int64(80),
   150  					"to_port":     int64(8000),
   151  					"protocol":    "tcp",
   152  					"cidr_blocks": []string{"172.8.0.0/16", "192.168.0.0/16"},
   153  				},
   154  			},
   155  			saves: []map[string]interface{}{
   156  				map[string]interface{}{
   157  					"from_port":   80,
   158  					"to_port":     8000,
   159  					"protocol":    "tcp",
   160  					"cidr_blocks": []string{"172.8.0.0/16"},
   161  				},
   162  				map[string]interface{}{
   163  					"from_port":   80,
   164  					"to_port":     8000,
   165  					"protocol":    "tcp",
   166  					"cidr_blocks": []string{"192.168.0.0/16"},
   167  				},
   168  			},
   169  		},
   170  		{
   171  			local: []interface{}{},
   172  			remote: []map[string]interface{}{
   173  				map[string]interface{}{
   174  					"from_port":   int64(80),
   175  					"to_port":     int64(8000),
   176  					"protocol":    "tcp",
   177  					"cidr_blocks": []string{"172.8.0.0/16", "10.0.0.0/16"},
   178  				},
   179  			},
   180  			saves: []map[string]interface{}{
   181  				map[string]interface{}{
   182  					"from_port":   int64(80),
   183  					"to_port":     int64(8000),
   184  					"protocol":    "tcp",
   185  					"cidr_blocks": []string{"172.8.0.0/16", "10.0.0.0/16"},
   186  				},
   187  			},
   188  		},
   189  		// test lower/ uppercase handling
   190  		{
   191  			local: []interface{}{
   192  				map[string]interface{}{
   193  					"from_port": 80,
   194  					"to_port":   8000,
   195  					"protocol":  "TCP",
   196  				},
   197  			},
   198  			remote: []map[string]interface{}{
   199  				map[string]interface{}{
   200  					"from_port": int64(80),
   201  					"to_port":   int64(8000),
   202  					"protocol":  "tcp",
   203  				},
   204  			},
   205  			saves: []map[string]interface{}{
   206  				map[string]interface{}{
   207  					"from_port": 80,
   208  					"to_port":   8000,
   209  					"protocol":  "tcp",
   210  				},
   211  			},
   212  		},
   213  		// local and remote differ
   214  		{
   215  			local: []interface{}{
   216  				map[string]interface{}{
   217  					"from_port":   80,
   218  					"to_port":     8000,
   219  					"protocol":    "tcp",
   220  					"cidr_blocks": []interface{}{"172.8.0.0/16"},
   221  				},
   222  			},
   223  			remote: []map[string]interface{}{
   224  				map[string]interface{}{
   225  					"from_port":   int64(80),
   226  					"to_port":     int64(8000),
   227  					"protocol":    "tcp",
   228  					"cidr_blocks": []string{"10.0.0.0/16"},
   229  				},
   230  			},
   231  			// Because this is the remote rule being saved, we need to check for int64
   232  			// encoding. We could convert this code, but ultimately Terraform doesn't
   233  			// care it's for the reflect.DeepEqual in this test
   234  			saves: []map[string]interface{}{
   235  				map[string]interface{}{
   236  					"from_port":   int64(80),
   237  					"to_port":     int64(8000),
   238  					"protocol":    "tcp",
   239  					"cidr_blocks": []string{"10.0.0.0/16"},
   240  				},
   241  			},
   242  		},
   243  		// local with more rules and the remote (the remote should then be saved)
   244  		{
   245  			local: []interface{}{
   246  				map[string]interface{}{
   247  					"from_port":   80,
   248  					"to_port":     8000,
   249  					"protocol":    "tcp",
   250  					"cidr_blocks": []interface{}{"172.8.0.0/16", "10.8.0.0/16", "192.168.0.0/16"},
   251  				},
   252  			},
   253  			remote: []map[string]interface{}{
   254  				map[string]interface{}{
   255  					"from_port":   int64(80),
   256  					"to_port":     int64(8000),
   257  					"protocol":    "tcp",
   258  					"cidr_blocks": []string{"172.8.0.0/16", "192.168.0.0/16"},
   259  				},
   260  			},
   261  			saves: []map[string]interface{}{
   262  				map[string]interface{}{
   263  					"from_port":   int64(80),
   264  					"to_port":     int64(8000),
   265  					"protocol":    "tcp",
   266  					"cidr_blocks": []string{"172.8.0.0/16", "192.168.0.0/16"},
   267  				},
   268  			},
   269  		},
   270  		// 3 local rules
   271  		// this should trigger a diff (not shown)
   272  		{
   273  			local: []interface{}{
   274  				map[string]interface{}{
   275  					"from_port":   80,
   276  					"to_port":     8000,
   277  					"protocol":    "tcp",
   278  					"cidr_blocks": []interface{}{"172.8.0.0/16"},
   279  				},
   280  				map[string]interface{}{
   281  					"from_port":   80,
   282  					"to_port":     8000,
   283  					"protocol":    "tcp",
   284  					"cidr_blocks": []interface{}{"10.8.0.0/16"},
   285  				},
   286  				map[string]interface{}{
   287  					"from_port":   80,
   288  					"to_port":     8000,
   289  					"protocol":    "tcp",
   290  					"cidr_blocks": []interface{}{"192.168.0.0/16"},
   291  				},
   292  			},
   293  			remote: []map[string]interface{}{
   294  				map[string]interface{}{
   295  					"from_port":   int64(80),
   296  					"to_port":     int64(8000),
   297  					"protocol":    "tcp",
   298  					"cidr_blocks": []string{"172.8.0.0/16", "192.168.0.0/16"},
   299  				},
   300  			},
   301  			saves: []map[string]interface{}{
   302  				map[string]interface{}{
   303  					"from_port":   80,
   304  					"to_port":     8000,
   305  					"protocol":    "tcp",
   306  					"cidr_blocks": []string{"172.8.0.0/16"},
   307  				},
   308  				map[string]interface{}{
   309  					"from_port":   80,
   310  					"to_port":     8000,
   311  					"protocol":    "tcp",
   312  					"cidr_blocks": []string{"192.168.0.0/16"},
   313  				},
   314  			},
   315  		},
   316  		// a local rule with 2 cidrs, remote has 4 cidrs, should be saved to match
   317  		// the local but also an extra rule found
   318  		{
   319  			local: []interface{}{
   320  				map[string]interface{}{
   321  					"from_port":   80,
   322  					"to_port":     8000,
   323  					"protocol":    "tcp",
   324  					"cidr_blocks": []interface{}{"172.8.0.0/16", "10.8.0.0/16"},
   325  				},
   326  			},
   327  			remote: []map[string]interface{}{
   328  				map[string]interface{}{
   329  					"from_port":   int64(80),
   330  					"to_port":     int64(8000),
   331  					"protocol":    "tcp",
   332  					"cidr_blocks": []string{"172.8.0.0/16", "192.168.0.0/16", "10.8.0.0/16", "206.8.0.0/16"},
   333  				},
   334  			},
   335  			saves: []map[string]interface{}{
   336  				map[string]interface{}{
   337  					"from_port":   80,
   338  					"to_port":     8000,
   339  					"protocol":    "tcp",
   340  					"cidr_blocks": []string{"172.8.0.0/16", "10.8.0.0/16"},
   341  				},
   342  				map[string]interface{}{
   343  					"from_port":   int64(80),
   344  					"to_port":     int64(8000),
   345  					"protocol":    "tcp",
   346  					"cidr_blocks": []string{"192.168.0.0/16", "206.8.0.0/16"},
   347  				},
   348  			},
   349  		},
   350  		// testing some SGS
   351  		{
   352  			local: []interface{}{},
   353  			remote: []map[string]interface{}{
   354  				map[string]interface{}{
   355  					"from_port":       int64(22),
   356  					"to_port":         int64(22),
   357  					"protocol":        "tcp",
   358  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876"}),
   359  				},
   360  			},
   361  			saves: []map[string]interface{}{
   362  				map[string]interface{}{
   363  					// we're saving the remote, so it will be int64 encoded
   364  					"from_port":       int64(22),
   365  					"to_port":         int64(22),
   366  					"protocol":        "tcp",
   367  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876"}),
   368  				},
   369  			},
   370  		},
   371  		// two local blocks that match a single remote group, but are saved as two
   372  		{
   373  			local: []interface{}{
   374  				map[string]interface{}{
   375  					"from_port":       22,
   376  					"to_port":         22,
   377  					"protocol":        "tcp",
   378  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876"}),
   379  				},
   380  				map[string]interface{}{
   381  					"from_port":       22,
   382  					"to_port":         22,
   383  					"protocol":        "tcp",
   384  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-4444"}),
   385  				},
   386  			},
   387  			remote: []map[string]interface{}{
   388  				map[string]interface{}{
   389  					"from_port": int64(22),
   390  					"to_port":   int64(22),
   391  					"protocol":  "tcp",
   392  					"security_groups": schema.NewSet(
   393  						schema.HashString,
   394  						[]interface{}{
   395  							"sg-9876",
   396  							"sg-4444",
   397  						},
   398  					),
   399  				},
   400  			},
   401  			saves: []map[string]interface{}{
   402  				map[string]interface{}{
   403  					"from_port": 22,
   404  					"to_port":   22,
   405  					"protocol":  "tcp",
   406  					"security_groups": schema.NewSet(
   407  						schema.HashString,
   408  						[]interface{}{
   409  							"sg-9876",
   410  						},
   411  					),
   412  				},
   413  				map[string]interface{}{
   414  					"from_port": 22,
   415  					"to_port":   22,
   416  					"protocol":  "tcp",
   417  					"security_groups": schema.NewSet(
   418  						schema.HashString,
   419  						[]interface{}{
   420  							"sg-4444",
   421  						},
   422  					),
   423  				},
   424  			},
   425  		},
   426  		// test self with other rules
   427  		{
   428  			local: []interface{}{
   429  				map[string]interface{}{
   430  					"from_port":       22,
   431  					"to_port":         22,
   432  					"protocol":        "tcp",
   433  					"self":            true,
   434  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
   435  				},
   436  			},
   437  			remote: []map[string]interface{}{
   438  				map[string]interface{}{
   439  					"from_port": int64(22),
   440  					"to_port":   int64(22),
   441  					"protocol":  "tcp",
   442  					"self":      true,
   443  				},
   444  			},
   445  			saves: []map[string]interface{}{
   446  				map[string]interface{}{
   447  					"from_port": int64(22),
   448  					"to_port":   int64(22),
   449  					"protocol":  "tcp",
   450  					"self":      true,
   451  				},
   452  			},
   453  		},
   454  		// test self
   455  		{
   456  			local: []interface{}{
   457  				map[string]interface{}{
   458  					"from_port": 22,
   459  					"to_port":   22,
   460  					"protocol":  "tcp",
   461  					"self":      true,
   462  				},
   463  			},
   464  			remote: []map[string]interface{}{
   465  				map[string]interface{}{
   466  					"from_port": int64(22),
   467  					"to_port":   int64(22),
   468  					"protocol":  "tcp",
   469  					"self":      true,
   470  				},
   471  			},
   472  			saves: []map[string]interface{}{
   473  				map[string]interface{}{
   474  					"from_port": int64(22),
   475  					"to_port":   int64(22),
   476  					"protocol":  "tcp",
   477  					"self":      true,
   478  				},
   479  			},
   480  		},
   481  		{
   482  			local: []interface{}{
   483  				map[string]interface{}{
   484  					"from_port":       22,
   485  					"to_port":         22,
   486  					"protocol":        "tcp",
   487  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
   488  				},
   489  			},
   490  			remote: []map[string]interface{}{
   491  				map[string]interface{}{
   492  					"from_port": int64(22),
   493  					"to_port":   int64(22),
   494  					"protocol":  "tcp",
   495  					"self":      true,
   496  				},
   497  			},
   498  			saves: []map[string]interface{}{
   499  				map[string]interface{}{
   500  					"from_port": int64(22),
   501  					"to_port":   int64(22),
   502  					"protocol":  "tcp",
   503  					"self":      true,
   504  				},
   505  			},
   506  		},
   507  		// mix of sgs and cidrs
   508  		{
   509  			local: []interface{}{
   510  				map[string]interface{}{
   511  					"from_port":   80,
   512  					"to_port":     8000,
   513  					"protocol":    "tcp",
   514  					"cidr_blocks": []interface{}{"172.8.0.0/16", "10.8.0.0/16", "192.168.0.0/16"},
   515  				},
   516  				map[string]interface{}{
   517  					"from_port":       80,
   518  					"to_port":         8000,
   519  					"protocol":        "tcp",
   520  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
   521  				},
   522  			},
   523  			remote: []map[string]interface{}{
   524  				map[string]interface{}{
   525  					"from_port":       int64(80),
   526  					"to_port":         int64(8000),
   527  					"protocol":        "tcp",
   528  					"cidr_blocks":     []string{"172.8.0.0/16", "192.168.0.0/16"},
   529  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
   530  				},
   531  			},
   532  			saves: []map[string]interface{}{
   533  				map[string]interface{}{
   534  					"from_port":   int64(80),
   535  					"to_port":     int64(8000),
   536  					"protocol":    "tcp",
   537  					"cidr_blocks": []string{"172.8.0.0/16", "192.168.0.0/16"},
   538  				},
   539  				map[string]interface{}{
   540  					"from_port":       int64(80),
   541  					"to_port":         int64(8000),
   542  					"protocol":        "tcp",
   543  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
   544  				},
   545  			},
   546  		},
   547  		{
   548  			local: []interface{}{
   549  				map[string]interface{}{
   550  					"from_port":   80,
   551  					"to_port":     8000,
   552  					"protocol":    "tcp",
   553  					"cidr_blocks": []interface{}{"172.8.0.0/16", "10.8.0.0/16", "192.168.0.0/16"},
   554  				},
   555  				map[string]interface{}{
   556  					"from_port": 80,
   557  					"to_port":   8000,
   558  					"protocol":  "tcp",
   559  					"self":      true,
   560  				},
   561  			},
   562  			remote: []map[string]interface{}{
   563  				map[string]interface{}{
   564  					"from_port":       int64(80),
   565  					"to_port":         int64(8000),
   566  					"protocol":        "tcp",
   567  					"cidr_blocks":     []string{"172.8.0.0/16", "192.168.0.0/16"},
   568  					"self":            true,
   569  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
   570  				},
   571  			},
   572  			saves: []map[string]interface{}{
   573  				map[string]interface{}{
   574  					"from_port": 80,
   575  					"to_port":   8000,
   576  					"protocol":  "tcp",
   577  					"self":      true,
   578  				},
   579  				map[string]interface{}{
   580  					"from_port":       int64(80),
   581  					"to_port":         int64(8000),
   582  					"protocol":        "tcp",
   583  					"cidr_blocks":     []string{"172.8.0.0/16", "192.168.0.0/16"},
   584  					"security_groups": schema.NewSet(schema.HashString, []interface{}{"sg-9876", "sg-4444"}),
   585  				},
   586  			},
   587  		},
   588  	}
   589  	for i, c := range cases {
   590  		saves := matchRules("ingress", c.local, c.remote)
   591  		log.Printf("\n======\n\nSaves:\n%#v\n\nCS Saves:\n%#v\n\n======\n", saves, c.saves)
   592  		log.Printf("\n\tTest %d:\n", i)
   593  
   594  		if len(saves) != len(c.saves) {
   595  			t.Fatalf("Expected %d saves, got %d", len(c.saves), len(saves))
   596  		}
   597  
   598  		shouldFind := len(c.saves)
   599  		var found int
   600  		for _, s := range saves {
   601  			for _, cs := range c.saves {
   602  				// deep equal cannot compare schema.Set's directly
   603  				// make sure we're not failing the reflect b/c of ports/type
   604  				for _, attr := range []string{"to_port", "from_port", "type"} {
   605  					if s[attr] != cs[attr] {
   606  						continue
   607  					}
   608  				}
   609  
   610  				var numExpectedCidrs, numExpectedSGs, numRemoteCidrs, numRemoteSGs int
   611  				// var matchingCidrs []string
   612  				// var matchingSGs []string
   613  
   614  				var cidrsMatch, sGsMatch bool
   615  
   616  				if _, ok := s["cidr_blocks"]; ok {
   617  					switch s["cidr_blocks"].(type) {
   618  					case []string:
   619  						numExpectedCidrs = len(s["cidr_blocks"].([]string))
   620  					default:
   621  						numExpectedCidrs = len(s["cidr_blocks"].([]interface{}))
   622  					}
   623  
   624  				}
   625  				if _, ok := s["security_groups"]; ok {
   626  					numExpectedSGs = len(s["security_groups"].(*schema.Set).List())
   627  				}
   628  
   629  				if _, ok := cs["cidr_blocks"]; ok {
   630  					numRemoteCidrs = len(cs["cidr_blocks"].([]string))
   631  				}
   632  
   633  				if _, ok := cs["security_groups"]; ok {
   634  					numRemoteSGs = len(cs["security_groups"].(*schema.Set).List())
   635  				}
   636  
   637  				// skip early
   638  				if numExpectedSGs != numRemoteSGs {
   639  					log.Printf("\n\ncontinuning on numRemoteSGs \n\n")
   640  					continue
   641  				}
   642  				if numExpectedCidrs != numRemoteCidrs {
   643  					log.Printf("\n\ncontinuning numRemoteCidrs\n\n")
   644  					continue
   645  				}
   646  
   647  				if numExpectedCidrs == 0 {
   648  					cidrsMatch = true
   649  				}
   650  				if numExpectedSGs == 0 {
   651  					sGsMatch = true
   652  				}
   653  
   654  				// convert save cidrs to set
   655  				var lcs []interface{}
   656  				if _, ok := s["cidr_blocks"]; ok {
   657  					switch s["cidr_blocks"].(type) {
   658  					case []string:
   659  						for _, c := range s["cidr_blocks"].([]string) {
   660  							lcs = append(lcs, c)
   661  						}
   662  					default:
   663  						for _, c := range s["cidr_blocks"].([]interface{}) {
   664  							lcs = append(lcs, c)
   665  						}
   666  					}
   667  				}
   668  				savesCidrs := schema.NewSet(schema.HashString, lcs)
   669  
   670  				// convert cs cidrs to set
   671  				var cslcs []interface{}
   672  				if _, ok := cs["cidr_blocks"]; ok {
   673  					for _, c := range cs["cidr_blocks"].([]string) {
   674  						cslcs = append(cslcs, c)
   675  					}
   676  				}
   677  				csCidrs := schema.NewSet(schema.HashString, cslcs)
   678  
   679  				if csCidrs.Equal(savesCidrs) {
   680  					log.Printf("\nmatched cidrs")
   681  					cidrsMatch = true
   682  				}
   683  
   684  				if rawS, ok := s["security_groups"]; ok {
   685  					outSet := rawS.(*schema.Set)
   686  					if rawL, ok := cs["security_groups"]; ok {
   687  						localSet := rawL.(*schema.Set)
   688  						if outSet.Equal(localSet) {
   689  							log.Printf("\nmatched sgs")
   690  							sGsMatch = true
   691  						}
   692  					}
   693  				}
   694  
   695  				var lSelf bool
   696  				var rSelf bool
   697  				if _, ok := s["self"]; ok {
   698  					lSelf = s["self"].(bool)
   699  				}
   700  				if _, ok := cs["self"]; ok {
   701  					rSelf = cs["self"].(bool)
   702  				}
   703  
   704  				if (sGsMatch && cidrsMatch) && (lSelf == rSelf) {
   705  					found++
   706  				}
   707  			}
   708  		}
   709  
   710  		if found != shouldFind {
   711  			t.Fatalf("Bad sg rule matches (%d / %d)", found, shouldFind)
   712  		}
   713  	}
   714  }