github.com/lukasheimann/cloudfoundrycli@v7.1.0+incompatible/actor/v7action/security_group_test.go (about)

     1  package v7action_test
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"os"
     9  
    10  	"code.cloudfoundry.org/cli/actor/actionerror"
    11  	. "code.cloudfoundry.org/cli/actor/v7action"
    12  	"code.cloudfoundry.org/cli/actor/v7action/v7actionfakes"
    13  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccerror"
    14  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3"
    15  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant"
    16  	"code.cloudfoundry.org/cli/resources"
    17  	. "github.com/onsi/ginkgo"
    18  	. "github.com/onsi/gomega"
    19  )
    20  
    21  var _ = Describe("Security Group Actions", func() {
    22  	var (
    23  		actor                     *Actor
    24  		fakeCloudControllerClient *v7actionfakes.FakeCloudControllerClient
    25  		warnings                  Warnings
    26  		executeErr                error
    27  	)
    28  
    29  	BeforeEach(func() {
    30  		fakeCloudControllerClient = new(v7actionfakes.FakeCloudControllerClient)
    31  		actor = NewActor(fakeCloudControllerClient, nil, nil, nil, nil, nil)
    32  
    33  	})
    34  
    35  	Describe("BindSecurityGroupToSpaces", func() {
    36  		var (
    37  			lifecycle constant.SecurityGroupLifecycle
    38  			spaces    []resources.Space
    39  			err       error
    40  			warnings  []string
    41  		)
    42  
    43  		BeforeEach(func() {
    44  			spaces = []resources.Space{{GUID: "some-space-guid"}, {GUID: "other-space-guid"}}
    45  		})
    46  
    47  		JustBeforeEach(func() {
    48  			warnings, err = actor.BindSecurityGroupToSpaces("some-security-group-guid", spaces, lifecycle)
    49  		})
    50  
    51  		When("the lifecycle is neither running nor staging", func() {
    52  			BeforeEach(func() {
    53  				lifecycle = "bill & ted"
    54  			})
    55  
    56  			It("returns and appropriate error", func() {
    57  				Expect(err).To(MatchError(fmt.Sprintf("Invalid lifecycle: %s", lifecycle)))
    58  			})
    59  		})
    60  
    61  		When("the lifecycle is running", func() {
    62  			BeforeEach(func() {
    63  				lifecycle = constant.SecurityGroupLifecycleRunning
    64  			})
    65  
    66  			When("binding the space does not return an error", func() {
    67  				BeforeEach(func() {
    68  					fakeCloudControllerClient.UpdateSecurityGroupRunningSpaceReturns(
    69  						ccv3.Warnings{"warning-1"},
    70  						nil,
    71  					)
    72  				})
    73  
    74  				It("returns warnings and no error", func() {
    75  					Expect(err).ToNot(HaveOccurred())
    76  					Expect(warnings).To(ConsistOf("warning-1"))
    77  					Expect(fakeCloudControllerClient.UpdateSecurityGroupRunningSpaceCallCount()).To(Equal(1))
    78  					securityGroupGUID, spaceGUID := fakeCloudControllerClient.UpdateSecurityGroupRunningSpaceArgsForCall(0)
    79  					Expect(securityGroupGUID).To(Equal("some-security-group-guid"))
    80  					Expect(spaceGUID).To(Equal([]string{"some-space-guid", "other-space-guid"}))
    81  				})
    82  			})
    83  
    84  			When("binding the space returns an error", func() {
    85  				var returnedError error
    86  				BeforeEach(func() {
    87  					returnedError = errors.New("associate-space-error")
    88  					fakeCloudControllerClient.UpdateSecurityGroupRunningSpaceReturns(
    89  						ccv3.Warnings{"warning-1", "warning-2"},
    90  						returnedError,
    91  					)
    92  				})
    93  
    94  				It("returns the error and warnings", func() {
    95  					Expect(err).To(Equal(returnedError))
    96  					Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
    97  				})
    98  			})
    99  		})
   100  
   101  		When("the lifecycle is staging", func() {
   102  			BeforeEach(func() {
   103  				lifecycle = constant.SecurityGroupLifecycleStaging
   104  			})
   105  
   106  			When("binding the space does not return an error", func() {
   107  				BeforeEach(func() {
   108  					fakeCloudControllerClient.UpdateSecurityGroupStagingSpaceReturns(
   109  						ccv3.Warnings{"warning-1", "warning-2"},
   110  						nil,
   111  					)
   112  				})
   113  
   114  				It("returns warnings and no error", func() {
   115  					Expect(err).ToNot(HaveOccurred())
   116  					Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
   117  					Expect(fakeCloudControllerClient.UpdateSecurityGroupStagingSpaceCallCount()).To(Equal(1))
   118  					securityGroupGUID, spaceGUID := fakeCloudControllerClient.UpdateSecurityGroupStagingSpaceArgsForCall(0)
   119  					Expect(securityGroupGUID).To(Equal("some-security-group-guid"))
   120  					Expect(spaceGUID).To(Equal([]string{"some-space-guid", "other-space-guid"}))
   121  				})
   122  			})
   123  
   124  			When("binding the space returns an error", func() {
   125  				var returnedError error
   126  				BeforeEach(func() {
   127  					returnedError = errors.New("associate-space-error")
   128  					fakeCloudControllerClient.UpdateSecurityGroupStagingSpaceReturns(
   129  						ccv3.Warnings{"warning-1", "warning-2"},
   130  						returnedError,
   131  					)
   132  				})
   133  
   134  				It("returns the error and warnings", func() {
   135  					Expect(err).To(Equal(returnedError))
   136  					Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
   137  				})
   138  			})
   139  		})
   140  	})
   141  
   142  	Describe("CreateSecurityGroup", func() {
   143  		const securityGroupName = "security-group-name"
   144  		var (
   145  			filePath              string
   146  			fileContents          []byte
   147  			tempFile              *os.File
   148  			returnedSecurityGroup resources.SecurityGroup
   149  			secGrpPorts           string
   150  			secGrpType            int
   151  			secGrpCode            int
   152  			secGrpDescription     string
   153  			secGrpLog             bool
   154  		)
   155  
   156  		BeforeEach(func() {
   157  			fileContents = []byte(`[
   158  	{
   159  		"protocol":"all",
   160  		"destination":"some-destination",
   161  		"ports":"some-ports",
   162  		"type":1,
   163  		"code":0,
   164  		"description":"some-description",
   165  		"log":false
   166  	},
   167  	{
   168        "protocol": "tcp",
   169        "destination": "10.10.10.0/24"
   170      }
   171  ]`)
   172  			secGrpPorts = "some-ports"
   173  			secGrpType = 1
   174  			secGrpCode = 0
   175  			secGrpDescription = "some-description"
   176  			secGrpLog = false
   177  			returnedSecurityGroup = resources.SecurityGroup{
   178  				Name: securityGroupName,
   179  				GUID: "some-sec-grp-guid",
   180  				Rules: []resources.Rule{
   181  					{
   182  						Protocol:    "all",
   183  						Destination: "some-destination",
   184  						Ports:       &secGrpPorts,
   185  						Type:        &secGrpType,
   186  						Code:        &secGrpCode,
   187  						Description: &secGrpDescription,
   188  						Log:         &secGrpLog,
   189  					},
   190  					{
   191  						Protocol:    "tcp",
   192  						Destination: "10.10.10.0/24",
   193  					},
   194  				},
   195  			}
   196  			tempFile, executeErr = ioutil.TempFile("", "")
   197  			Expect(executeErr).ToNot(HaveOccurred())
   198  			filePath = tempFile.Name()
   199  
   200  			fakeCloudControllerClient.CreateSecurityGroupReturns(returnedSecurityGroup, ccv3.Warnings{"create-sec-grp-warning"}, nil)
   201  		})
   202  
   203  		JustBeforeEach(func() {
   204  			_, err := tempFile.Write(fileContents)
   205  			Expect(err).ToNot(HaveOccurred())
   206  
   207  			warnings, executeErr = actor.CreateSecurityGroup(securityGroupName, filePath)
   208  		})
   209  
   210  		AfterEach(func() {
   211  			os.Remove(filePath)
   212  		})
   213  
   214  		When("the path does not exist", func() {
   215  			BeforeEach(func() {
   216  				filePath = "does-not-exist"
   217  			})
   218  			It("returns an error", func() {
   219  				Expect(executeErr).To(HaveOccurred())
   220  				_, ok := executeErr.(*os.PathError)
   221  				Expect(ok).To(BeTrue())
   222  				Expect(warnings).To(Equal(Warnings{}))
   223  			})
   224  		})
   225  
   226  		When("the json does not contain the required fields", func() {
   227  			BeforeEach(func() {
   228  				fileContents = []byte(`{"blah": "blah"}`)
   229  			})
   230  			It("returns an error", func() {
   231  				Expect(executeErr).To(HaveOccurred())
   232  				_, ok := executeErr.(*json.UnmarshalTypeError)
   233  				Expect(ok).To(BeTrue())
   234  				Expect(warnings).To(Equal(Warnings{}))
   235  			})
   236  		})
   237  		When("the json is invalid", func() {
   238  			BeforeEach(func() {
   239  				fileContents = []byte("not-valid-json")
   240  			})
   241  			It("returns an error", func() {
   242  				Expect(executeErr).To(HaveOccurred())
   243  				_, ok := executeErr.(*json.SyntaxError)
   244  				Expect(ok).To(BeTrue())
   245  				Expect(warnings).To(Equal(Warnings{}))
   246  			})
   247  		})
   248  
   249  		It("calls the API with the generated security group resource and returns all warnings", func() {
   250  			Expect(executeErr).ToNot(HaveOccurred())
   251  			Expect(warnings).To(Equal(Warnings{"create-sec-grp-warning"}))
   252  
   253  			givenSecurityGroup := fakeCloudControllerClient.CreateSecurityGroupArgsForCall(0)
   254  
   255  			returnedSecurityGroup.GUID = ""
   256  			Expect(givenSecurityGroup).To(Equal(returnedSecurityGroup))
   257  
   258  		})
   259  
   260  		When("the security group can't be created", func() {
   261  			BeforeEach(func() {
   262  				fakeCloudControllerClient.CreateSecurityGroupReturns(resources.SecurityGroup{}, ccv3.Warnings{"a-warning"}, errors.New("create-sec-group-error"))
   263  			})
   264  			It("returns the error and warnings", func() {
   265  				Expect(executeErr).To(HaveOccurred())
   266  				Expect(executeErr).To(MatchError("create-sec-group-error"))
   267  				Expect(warnings).To(Equal(Warnings{"a-warning"}))
   268  			})
   269  
   270  		})
   271  	})
   272  
   273  	Describe("GetSecurityGroupSummary", func() {
   274  		const securityGroupName = "security-group-name"
   275  		var (
   276  			securityGroupSummary SecurityGroupSummary
   277  			description          string
   278  			port                 string
   279  		)
   280  
   281  		BeforeEach(func() {
   282  			description = "Top 8 Friends Only"
   283  			port = "9000"
   284  		})
   285  
   286  		When("the request succeeds", func() {
   287  			JustBeforeEach(func() {
   288  				securityGroupSummary, warnings, executeErr = actor.GetSecurityGroupSummary(securityGroupName)
   289  				Expect(executeErr).ToNot(HaveOccurred())
   290  			})
   291  
   292  			When("the security group is not associated with spaces or rules", func() {
   293  				BeforeEach(func() {
   294  					fakeCloudControllerClient.GetSecurityGroupsReturns(
   295  						[]resources.SecurityGroup{
   296  							{
   297  								GUID:  "some-security-group-guid-1",
   298  								Name:  "some-security-group-1",
   299  								Rules: []resources.Rule{},
   300  							},
   301  						},
   302  						ccv3.Warnings{"warning-1"},
   303  						nil,
   304  					)
   305  
   306  					fakeCloudControllerClient.GetSpacesReturns(
   307  						[]resources.Space{},
   308  						ccv3.IncludedResources{},
   309  						ccv3.Warnings{"warning-2"},
   310  						nil,
   311  					)
   312  				})
   313  
   314  				It("returns the security group summary and warnings", func() {
   315  					Expect(securityGroupSummary).To(Equal(
   316  						SecurityGroupSummary{
   317  							Name:                "security-group-name",
   318  							Rules:               []resources.Rule{},
   319  							SecurityGroupSpaces: []SecurityGroupSpace{},
   320  						},
   321  					))
   322  					Expect(warnings).To(ConsistOf("warning-1"))
   323  
   324  					Expect(fakeCloudControllerClient.GetSecurityGroupsCallCount()).To(Equal(1))
   325  					Expect(fakeCloudControllerClient.GetSecurityGroupsArgsForCall(0)).To(ConsistOf(
   326  						ccv3.Query{Key: ccv3.NameFilter, Values: []string{"security-group-name"}},
   327  					))
   328  
   329  					Expect(fakeCloudControllerClient.GetSpacesCallCount()).To(Equal(0))
   330  				})
   331  			})
   332  
   333  			When("the security group is associated with spaces and rules", func() {
   334  				BeforeEach(func() {
   335  					fakeCloudControllerClient.GetSecurityGroupsReturns(
   336  						[]resources.SecurityGroup{
   337  							{
   338  								GUID: "some-security-group-guid-1",
   339  								Name: "some-security-group-1",
   340  								Rules: []resources.Rule{{
   341  									Destination: "127.0.0.1",
   342  									Description: &description,
   343  									Ports:       &port,
   344  									Protocol:    "tcp",
   345  								}},
   346  								RunningSpaceGUIDs: []string{"space-guid-1"},
   347  								StagingSpaceGUIDs: []string{"space-guid-2"},
   348  							},
   349  						},
   350  						ccv3.Warnings{"warning-1"},
   351  						nil,
   352  					)
   353  
   354  					fakeCloudControllerClient.GetSpacesReturns(
   355  						[]resources.Space{{
   356  							Name: "my-space",
   357  							GUID: "space-guid-1",
   358  							Relationships: resources.Relationships{
   359  								constant.RelationshipTypeOrganization: resources.Relationship{GUID: "org-guid-1"},
   360  							},
   361  						}, {
   362  							Name: "your-space",
   363  							GUID: "space-guid-2",
   364  							Relationships: resources.Relationships{
   365  								constant.RelationshipTypeOrganization: resources.Relationship{GUID: "org-guid-2"},
   366  							},
   367  						}},
   368  						ccv3.IncludedResources{Organizations: []resources.Organization{{
   369  							Name: "obsolete-social-networks",
   370  							GUID: "org-guid-1",
   371  						}, {
   372  							Name: "revived-social-networks",
   373  							GUID: "org-guid-2",
   374  						}}},
   375  						ccv3.Warnings{"warning-2"},
   376  						nil,
   377  					)
   378  				})
   379  
   380  				It("returns the security group summary and warnings", func() {
   381  					Expect(securityGroupSummary).To(Equal(
   382  						SecurityGroupSummary{
   383  							Name: "security-group-name",
   384  							Rules: []resources.Rule{{
   385  								Destination: "127.0.0.1",
   386  								Description: &description,
   387  								Ports:       &port,
   388  								Protocol:    "tcp",
   389  							}},
   390  							SecurityGroupSpaces: []SecurityGroupSpace{{
   391  								SpaceName: "my-space",
   392  								OrgName:   "obsolete-social-networks",
   393  								Lifecycle: "running",
   394  							}, {
   395  								SpaceName: "your-space",
   396  								OrgName:   "revived-social-networks",
   397  								Lifecycle: "staging",
   398  							}},
   399  						},
   400  					))
   401  					Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
   402  
   403  					Expect(fakeCloudControllerClient.GetSecurityGroupsCallCount()).To(Equal(1))
   404  					Expect(fakeCloudControllerClient.GetSecurityGroupsArgsForCall(0)).To(ConsistOf(
   405  						ccv3.Query{Key: ccv3.NameFilter, Values: []string{"security-group-name"}},
   406  					))
   407  
   408  					Expect(fakeCloudControllerClient.GetSpacesCallCount()).To(Equal(1))
   409  					Expect(fakeCloudControllerClient.GetSpacesArgsForCall(0)).To(ConsistOf(
   410  						ccv3.Query{Key: ccv3.GUIDFilter, Values: []string{"space-guid-1", "space-guid-2"}},
   411  						ccv3.Query{Key: ccv3.Include, Values: []string{"organization"}},
   412  					))
   413  				})
   414  			})
   415  		})
   416  
   417  		When("the request errors", func() {
   418  			var expectedError error
   419  			JustBeforeEach(func() {
   420  				securityGroupSummary, warnings, executeErr = actor.GetSecurityGroupSummary(securityGroupName)
   421  			})
   422  
   423  			When("the security group does not exist", func() {
   424  				BeforeEach(func() {
   425  					fakeCloudControllerClient.GetSecurityGroupsReturns(
   426  						[]resources.SecurityGroup{},
   427  						ccv3.Warnings{"some-warning"},
   428  						nil,
   429  					)
   430  				})
   431  
   432  				It("returns the error and warnings", func() {
   433  					Expect(warnings).To(ConsistOf("some-warning"))
   434  					Expect(executeErr).To(MatchError(actionerror.SecurityGroupNotFoundError{Name: securityGroupName}))
   435  				})
   436  			})
   437  
   438  			When("the cloud controller client errors", func() {
   439  				BeforeEach(func() {
   440  					expectedError = errors.New("I am a CloudControllerClient Error")
   441  					fakeCloudControllerClient.GetSecurityGroupsReturns(
   442  						nil,
   443  						ccv3.Warnings{"some-warning"},
   444  						expectedError,
   445  					)
   446  				})
   447  
   448  				It("returns the error and warnings", func() {
   449  					Expect(warnings).To(ConsistOf("some-warning"))
   450  					Expect(executeErr).To(MatchError(expectedError))
   451  				})
   452  			})
   453  		})
   454  	})
   455  
   456  	Describe("GetSecurityGroups", func() {
   457  		var (
   458  			securityGroupSummaries []SecurityGroupSummary
   459  			description            string
   460  			port                   string
   461  			trueVal                bool
   462  			falseVal               bool
   463  		)
   464  
   465  		BeforeEach(func() {
   466  			description = "Top 8 Friends Only"
   467  			port = "9000"
   468  			trueVal = true
   469  			falseVal = false
   470  		})
   471  
   472  		When("the request succeeds", func() {
   473  			JustBeforeEach(func() {
   474  				securityGroupSummaries, warnings, executeErr = actor.GetSecurityGroups()
   475  				Expect(executeErr).ToNot(HaveOccurred())
   476  			})
   477  
   478  			BeforeEach(func() {
   479  				fakeCloudControllerClient.GetSecurityGroupsReturns(
   480  					[]resources.SecurityGroup{
   481  						{
   482  							GUID: "some-security-group-guid-1",
   483  							Name: "some-security-group-1",
   484  							Rules: []resources.Rule{{
   485  								Destination: "127.0.0.1",
   486  								Description: &description,
   487  								Ports:       &port,
   488  								Protocol:    "tcp",
   489  							}},
   490  							RunningGloballyEnabled: &trueVal,
   491  							StagingGloballyEnabled: &falseVal,
   492  							RunningSpaceGUIDs:      []string{"space-guid-1"},
   493  							StagingSpaceGUIDs:      []string{"space-guid-2"},
   494  						},
   495  						{
   496  							GUID: "some-security-group-guid-2",
   497  							Name: "some-security-group-2",
   498  							Rules: []resources.Rule{{
   499  								Destination: "127.0.0.1",
   500  								Description: &description,
   501  								Ports:       &port,
   502  								Protocol:    "udp",
   503  							}},
   504  							RunningGloballyEnabled: &falseVal,
   505  							StagingGloballyEnabled: &trueVal,
   506  							RunningSpaceGUIDs:      []string{"space-guid-2"},
   507  							StagingSpaceGUIDs:      []string{"space-guid-1"},
   508  						},
   509  					},
   510  					ccv3.Warnings{"warning-1"},
   511  					nil,
   512  				)
   513  
   514  				fakeCloudControllerClient.GetSpacesReturns(
   515  					[]resources.Space{{
   516  						Name: "my-space",
   517  						GUID: "space-guid-1",
   518  						Relationships: resources.Relationships{
   519  							constant.RelationshipTypeOrganization: resources.Relationship{GUID: "org-guid-1"},
   520  						},
   521  					}, {
   522  						Name: "your-space",
   523  						GUID: "space-guid-2",
   524  						Relationships: resources.Relationships{
   525  							constant.RelationshipTypeOrganization: resources.Relationship{GUID: "org-guid-2"},
   526  						},
   527  					}},
   528  					ccv3.IncludedResources{Organizations: []resources.Organization{{
   529  						Name: "obsolete-social-networks",
   530  						GUID: "org-guid-1",
   531  					}, {
   532  						Name: "revived-social-networks",
   533  						GUID: "org-guid-2",
   534  					}}},
   535  					ccv3.Warnings{"warning-2"},
   536  					nil,
   537  				)
   538  			})
   539  
   540  			It("returns the security group summary and warnings", func() {
   541  				Expect(securityGroupSummaries).To(Equal(
   542  					[]SecurityGroupSummary{{
   543  						Name: "some-security-group-1",
   544  						Rules: []resources.Rule{{
   545  							Destination: "127.0.0.1",
   546  							Description: &description,
   547  							Ports:       &port,
   548  							Protocol:    "tcp",
   549  						}},
   550  						SecurityGroupSpaces: []SecurityGroupSpace{{
   551  							SpaceName: "<all>",
   552  							OrgName:   "<all>",
   553  							Lifecycle: "running",
   554  						}, {
   555  							SpaceName: "my-space",
   556  							OrgName:   "obsolete-social-networks",
   557  							Lifecycle: "running",
   558  						}, {
   559  							SpaceName: "your-space",
   560  							OrgName:   "revived-social-networks",
   561  							Lifecycle: "staging",
   562  						}},
   563  					}, {
   564  						Name: "some-security-group-2",
   565  						Rules: []resources.Rule{{
   566  							Destination: "127.0.0.1",
   567  							Description: &description,
   568  							Ports:       &port,
   569  							Protocol:    "udp",
   570  						}},
   571  						SecurityGroupSpaces: []SecurityGroupSpace{{
   572  							SpaceName: "<all>",
   573  							OrgName:   "<all>",
   574  							Lifecycle: "staging",
   575  						}, {
   576  							SpaceName: "your-space",
   577  							OrgName:   "revived-social-networks",
   578  							Lifecycle: "running",
   579  						}, {
   580  							SpaceName: "my-space",
   581  							OrgName:   "obsolete-social-networks",
   582  							Lifecycle: "staging",
   583  						}},
   584  					}},
   585  				))
   586  				Expect(warnings).To(ConsistOf("warning-1", "warning-2", "warning-2"))
   587  
   588  				Expect(fakeCloudControllerClient.GetSecurityGroupsCallCount()).To(Equal(1))
   589  				Expect(fakeCloudControllerClient.GetSpacesCallCount()).To(Equal(2))
   590  				Expect(fakeCloudControllerClient.GetSpacesArgsForCall(0)).To(ConsistOf(
   591  					ccv3.Query{Key: ccv3.GUIDFilter, Values: []string{"space-guid-1", "space-guid-2"}},
   592  					ccv3.Query{Key: ccv3.Include, Values: []string{"organization"}},
   593  				))
   594  				Expect(fakeCloudControllerClient.GetSpacesArgsForCall(1)).To(ConsistOf(
   595  					ccv3.Query{Key: ccv3.GUIDFilter, Values: []string{"space-guid-2", "space-guid-1"}},
   596  					ccv3.Query{Key: ccv3.Include, Values: []string{"organization"}},
   597  				))
   598  			})
   599  		})
   600  
   601  		When("the request errors", func() {
   602  			var expectedError error
   603  			JustBeforeEach(func() {
   604  				securityGroupSummaries, warnings, executeErr = actor.GetSecurityGroups()
   605  			})
   606  
   607  			When("there are no security groups", func() {
   608  				BeforeEach(func() {
   609  					fakeCloudControllerClient.GetSecurityGroupsReturns(
   610  						[]resources.SecurityGroup{},
   611  						ccv3.Warnings{"warning-1"},
   612  						nil,
   613  					)
   614  				})
   615  
   616  				It("returns an empty list of security group summaries and warnings", func() {
   617  					Expect(securityGroupSummaries).To(Equal(
   618  						[]SecurityGroupSummary{},
   619  					))
   620  					Expect(warnings).To(ConsistOf("warning-1"))
   621  
   622  					Expect(fakeCloudControllerClient.GetSecurityGroupsCallCount()).To(Equal(1))
   623  					Expect(fakeCloudControllerClient.GetSpacesCallCount()).To(Equal(0))
   624  				})
   625  			})
   626  
   627  			When("the cloud controller client errors", func() {
   628  				BeforeEach(func() {
   629  					expectedError = errors.New("I am a CloudControllerClient Error")
   630  					fakeCloudControllerClient.GetSecurityGroupsReturns(
   631  						nil,
   632  						ccv3.Warnings{"some-warning"},
   633  						expectedError,
   634  					)
   635  				})
   636  
   637  				It("returns the error and warnings", func() {
   638  					Expect(warnings).To(ConsistOf("some-warning"))
   639  					Expect(executeErr).To(MatchError(expectedError))
   640  				})
   641  			})
   642  		})
   643  	})
   644  
   645  	Describe("GetSecurityGroup", func() {
   646  		var (
   647  			securityGroupName = "tom"
   648  			securityGroup     resources.SecurityGroup
   649  		)
   650  
   651  		When("the request succeeds", func() {
   652  			JustBeforeEach(func() {
   653  				securityGroup, warnings, executeErr = actor.GetSecurityGroup(securityGroupName)
   654  				Expect(executeErr).ToNot(HaveOccurred())
   655  			})
   656  
   657  			BeforeEach(func() {
   658  				fakeCloudControllerClient.GetSecurityGroupsReturns(
   659  					[]resources.SecurityGroup{
   660  						{
   661  							GUID: "some-security-group-guid-1",
   662  							Name: "some-security-group-1",
   663  						},
   664  					},
   665  					ccv3.Warnings{"warning-1"},
   666  					nil,
   667  				)
   668  			})
   669  
   670  			It("returns the security group and warnings", func() {
   671  				Expect(securityGroup).To(Equal(
   672  					resources.SecurityGroup{
   673  						Name: "some-security-group-1",
   674  						GUID: "some-security-group-guid-1",
   675  					},
   676  				))
   677  				Expect(warnings).To(ConsistOf("warning-1"))
   678  
   679  				Expect(fakeCloudControllerClient.GetSecurityGroupsCallCount()).To(Equal(1))
   680  			})
   681  		})
   682  
   683  		When("the request errors", func() {
   684  			var expectedError error
   685  
   686  			JustBeforeEach(func() {
   687  				securityGroup, warnings, executeErr = actor.GetSecurityGroup(securityGroupName)
   688  			})
   689  
   690  			When("there are no security groups", func() {
   691  				BeforeEach(func() {
   692  					fakeCloudControllerClient.GetSecurityGroupsReturns(
   693  						[]resources.SecurityGroup{},
   694  						ccv3.Warnings{"warning-1"},
   695  						nil,
   696  					)
   697  				})
   698  
   699  				It("returns an empty security group and warnings", func() {
   700  					Expect(securityGroup).To(Equal(resources.SecurityGroup{}))
   701  					Expect(warnings).To(ConsistOf("warning-1"))
   702  
   703  					Expect(fakeCloudControllerClient.GetSecurityGroupsCallCount()).To(Equal(1))
   704  				})
   705  			})
   706  
   707  			When("the cloud controller client errors", func() {
   708  				BeforeEach(func() {
   709  					expectedError = errors.New("I am a CloudControllerClient Error")
   710  					fakeCloudControllerClient.GetSecurityGroupsReturns(
   711  						nil,
   712  						ccv3.Warnings{"some-warning"},
   713  						expectedError,
   714  					)
   715  				})
   716  
   717  				It("returns the error and warnings", func() {
   718  					Expect(warnings).To(ConsistOf("some-warning"))
   719  					Expect(executeErr).To(MatchError(expectedError))
   720  				})
   721  			})
   722  		})
   723  	})
   724  
   725  	Describe("GetGlobalStagingSecurityGroups", func() {
   726  		var (
   727  			securityGroups []resources.SecurityGroup
   728  		)
   729  
   730  		When("the request succeeds", func() {
   731  			BeforeEach(func() {
   732  				fakeCloudControllerClient.GetSecurityGroupsReturns(
   733  					[]resources.SecurityGroup{{
   734  						Name: "security-group-name-1",
   735  						GUID: "security-group-guid-1",
   736  					}, {
   737  						Name: "security-group-name-2",
   738  						GUID: "security-group-guid-2",
   739  					}},
   740  					ccv3.Warnings{"security-group-warning"},
   741  					nil,
   742  				)
   743  			})
   744  
   745  			JustBeforeEach(func() {
   746  				securityGroups, warnings, executeErr = actor.GetGlobalStagingSecurityGroups()
   747  				Expect(executeErr).ToNot(HaveOccurred())
   748  			})
   749  
   750  			It("returns the security groups and warnings", func() {
   751  				Expect(securityGroups).To(Equal(
   752  					[]resources.SecurityGroup{{
   753  						Name: "security-group-name-1",
   754  						GUID: "security-group-guid-1",
   755  					}, {
   756  						Name: "security-group-name-2",
   757  						GUID: "security-group-guid-2",
   758  					}},
   759  				))
   760  				Expect(warnings).To(ConsistOf("security-group-warning"))
   761  
   762  				Expect(fakeCloudControllerClient.GetSecurityGroupsCallCount()).To(Equal(1))
   763  				Expect(fakeCloudControllerClient.GetSecurityGroupsArgsForCall(0)).To(ConsistOf(
   764  					ccv3.Query{Key: ccv3.GloballyEnabledStaging, Values: []string{"true"}},
   765  				))
   766  			})
   767  		})
   768  
   769  		When("the request errors", func() {
   770  			var expectedError error
   771  			JustBeforeEach(func() {
   772  				securityGroups, warnings, executeErr = actor.GetGlobalStagingSecurityGroups()
   773  			})
   774  
   775  			When("there are no security groups", func() {
   776  				BeforeEach(func() {
   777  					fakeCloudControllerClient.GetSecurityGroupsReturns(
   778  						[]resources.SecurityGroup{},
   779  						ccv3.Warnings{"security-group-warning"},
   780  						nil,
   781  					)
   782  				})
   783  
   784  				It("returns an empty list of security group summaries and warnings", func() {
   785  					Expect(securityGroups).To(Equal(
   786  						[]resources.SecurityGroup{},
   787  					))
   788  					Expect(warnings).To(ConsistOf("security-group-warning"))
   789  
   790  					Expect(fakeCloudControllerClient.GetSecurityGroupsCallCount()).To(Equal(1))
   791  					Expect(fakeCloudControllerClient.GetSecurityGroupsArgsForCall(0)).To(ConsistOf(
   792  						ccv3.Query{Key: ccv3.GloballyEnabledStaging, Values: []string{"true"}},
   793  					))
   794  				})
   795  			})
   796  
   797  			When("the cloud controller client errors", func() {
   798  				BeforeEach(func() {
   799  					expectedError = errors.New("I am a CloudControllerClient Error")
   800  					fakeCloudControllerClient.GetSecurityGroupsReturns(
   801  						nil,
   802  						ccv3.Warnings{"security-group-warning"},
   803  						expectedError,
   804  					)
   805  				})
   806  
   807  				It("returns the error and warnings", func() {
   808  					Expect(warnings).To(ConsistOf("security-group-warning"))
   809  					Expect(executeErr).To(MatchError(expectedError))
   810  				})
   811  			})
   812  		})
   813  	})
   814  
   815  	Describe("GetGlobalRunningingSecurityGroups", func() {
   816  		var (
   817  			securityGroups []resources.SecurityGroup
   818  		)
   819  
   820  		When("the request succeeds", func() {
   821  			BeforeEach(func() {
   822  				fakeCloudControllerClient.GetSecurityGroupsReturns(
   823  					[]resources.SecurityGroup{{
   824  						Name: "security-group-name-1",
   825  						GUID: "security-group-guid-1",
   826  					}, {
   827  						Name: "security-group-name-2",
   828  						GUID: "security-group-guid-2",
   829  					}},
   830  					ccv3.Warnings{"security-group-warning"},
   831  					nil,
   832  				)
   833  			})
   834  
   835  			JustBeforeEach(func() {
   836  				securityGroups, warnings, executeErr = actor.GetGlobalRunningSecurityGroups()
   837  				Expect(executeErr).ToNot(HaveOccurred())
   838  			})
   839  
   840  			It("returns the security groups and warnings", func() {
   841  				Expect(securityGroups).To(Equal(
   842  					[]resources.SecurityGroup{{
   843  						Name: "security-group-name-1",
   844  						GUID: "security-group-guid-1",
   845  					}, {
   846  						Name: "security-group-name-2",
   847  						GUID: "security-group-guid-2",
   848  					}},
   849  				))
   850  				Expect(warnings).To(ConsistOf("security-group-warning"))
   851  
   852  				Expect(fakeCloudControllerClient.GetSecurityGroupsCallCount()).To(Equal(1))
   853  				Expect(fakeCloudControllerClient.GetSecurityGroupsArgsForCall(0)).To(ConsistOf(
   854  					ccv3.Query{Key: ccv3.GloballyEnabledRunning, Values: []string{"true"}},
   855  				))
   856  			})
   857  		})
   858  
   859  		When("the request errors", func() {
   860  			var expectedError error
   861  			JustBeforeEach(func() {
   862  				securityGroups, warnings, executeErr = actor.GetGlobalRunningSecurityGroups()
   863  			})
   864  
   865  			When("there are no security groups", func() {
   866  				BeforeEach(func() {
   867  					fakeCloudControllerClient.GetSecurityGroupsReturns(
   868  						[]resources.SecurityGroup{},
   869  						ccv3.Warnings{"security-group-warning"},
   870  						nil,
   871  					)
   872  				})
   873  
   874  				It("returns an empty list of security group summaries and warnings", func() {
   875  					Expect(securityGroups).To(Equal(
   876  						[]resources.SecurityGroup{},
   877  					))
   878  					Expect(warnings).To(ConsistOf("security-group-warning"))
   879  
   880  					Expect(fakeCloudControllerClient.GetSecurityGroupsCallCount()).To(Equal(1))
   881  					Expect(fakeCloudControllerClient.GetSecurityGroupsArgsForCall(0)).To(ConsistOf(
   882  						ccv3.Query{Key: ccv3.GloballyEnabledRunning, Values: []string{"true"}},
   883  					))
   884  				})
   885  			})
   886  
   887  			When("the cloud controller client errors", func() {
   888  				BeforeEach(func() {
   889  					expectedError = errors.New("I am a CloudControllerClient Error")
   890  					fakeCloudControllerClient.GetSecurityGroupsReturns(
   891  						nil,
   892  						ccv3.Warnings{"security-group-warning"},
   893  						expectedError,
   894  					)
   895  				})
   896  
   897  				It("returns the error and warnings", func() {
   898  					Expect(warnings).To(ConsistOf("security-group-warning"))
   899  					Expect(executeErr).To(MatchError(expectedError))
   900  				})
   901  			})
   902  		})
   903  	})
   904  
   905  	Describe("UnbindSecurityGroup", func() {
   906  		var (
   907  			securityGroupName = "some-security-group"
   908  			orgName           = "some-org"
   909  			spaceName         = "some-space"
   910  			lifecycle         = constant.SecurityGroupLifecycleStaging
   911  			warnings          Warnings
   912  			executeErr        error
   913  		)
   914  
   915  		JustBeforeEach(func() {
   916  			warnings, executeErr = actor.UnbindSecurityGroup(securityGroupName, orgName, spaceName, lifecycle)
   917  		})
   918  
   919  		BeforeEach(func() {
   920  			fakeCloudControllerClient.GetOrganizationsReturns(
   921  				[]resources.Organization{{GUID: "some-org-guid"}},
   922  				ccv3.Warnings{"get-org-warning"},
   923  				nil,
   924  			)
   925  
   926  			fakeCloudControllerClient.GetSpacesReturns(
   927  				[]resources.Space{{GUID: "some-space-guid"}},
   928  				ccv3.IncludedResources{},
   929  				ccv3.Warnings{"get-space-warning"},
   930  				nil,
   931  			)
   932  
   933  			fakeCloudControllerClient.GetSecurityGroupsReturns(
   934  				[]resources.SecurityGroup{{GUID: "some-security-group-guid"}},
   935  				ccv3.Warnings{"get-security-group-warning"},
   936  				nil,
   937  			)
   938  
   939  			fakeCloudControllerClient.UnbindSecurityGroupStagingSpaceReturns(
   940  				ccv3.Warnings{"unbind-security-group-warning"},
   941  				nil,
   942  			)
   943  		})
   944  
   945  		When("all requests succeed", func() {
   946  			It("returns warnings and no error", func() {
   947  				Expect(executeErr).NotTo(HaveOccurred())
   948  				Expect(warnings).To(ConsistOf("get-org-warning", "get-space-warning", "get-security-group-warning", "unbind-security-group-warning"))
   949  
   950  				Expect(fakeCloudControllerClient.GetOrganizationsCallCount()).To(Equal(1))
   951  				orgsQuery := fakeCloudControllerClient.GetOrganizationsArgsForCall(0)
   952  				Expect(orgsQuery).To(Equal([]ccv3.Query{
   953  					{Key: ccv3.NameFilter, Values: []string{orgName}},
   954  				}))
   955  
   956  				Expect(fakeCloudControllerClient.GetSpacesCallCount()).To(Equal(1))
   957  				spacesQuery := fakeCloudControllerClient.GetSpacesArgsForCall(0)
   958  				Expect(spacesQuery).To(Equal([]ccv3.Query{
   959  					{Key: ccv3.NameFilter, Values: []string{spaceName}},
   960  					{Key: ccv3.OrganizationGUIDFilter, Values: []string{"some-org-guid"}},
   961  				}))
   962  
   963  				Expect(fakeCloudControllerClient.GetSecurityGroupsCallCount()).To(Equal(1))
   964  				securityGroupsQuery := fakeCloudControllerClient.GetSecurityGroupsArgsForCall(0)
   965  				Expect(securityGroupsQuery).To(Equal([]ccv3.Query{
   966  					{Key: ccv3.NameFilter, Values: []string{securityGroupName}},
   967  				}))
   968  
   969  				Expect(fakeCloudControllerClient.UnbindSecurityGroupStagingSpaceCallCount()).To(Equal(1))
   970  				givenSecurityGroupGUID, givenSpaceGUID := fakeCloudControllerClient.UnbindSecurityGroupStagingSpaceArgsForCall(0)
   971  				Expect(givenSecurityGroupGUID).To(Equal("some-security-group-guid"))
   972  				Expect(givenSpaceGUID).To(Equal("some-space-guid"))
   973  			})
   974  		})
   975  
   976  		When("the seurity group is not bound to the space", func() {
   977  			BeforeEach(func() {
   978  				fakeCloudControllerClient.UnbindSecurityGroupStagingSpaceReturns(
   979  					ccv3.Warnings{"get-security-group-warning"},
   980  					ccerror.SecurityGroupNotBound{},
   981  				)
   982  			})
   983  
   984  			It("returns warnings and an appropriate error", func() {
   985  				Expect(executeErr).To(MatchError(actionerror.SecurityGroupNotBoundToSpaceError{
   986  					Name:      securityGroupName,
   987  					Space:     spaceName,
   988  					Lifecycle: lifecycle,
   989  				}))
   990  			})
   991  		})
   992  
   993  		When("getting the org fails", func() {
   994  			BeforeEach(func() {
   995  				fakeCloudControllerClient.GetOrganizationsReturns(
   996  					[]resources.Organization{{}},
   997  					ccv3.Warnings{"get-org-warning"},
   998  					errors.New("org error"),
   999  				)
  1000  			})
  1001  			It("returns warnings and error", func() {
  1002  				Expect(executeErr).To(MatchError("org error"))
  1003  			})
  1004  		})
  1005  
  1006  		When("getting the space fails", func() {
  1007  			BeforeEach(func() {
  1008  				fakeCloudControllerClient.GetSpacesReturns(
  1009  					[]resources.Space{{}},
  1010  					ccv3.IncludedResources{},
  1011  					ccv3.Warnings{"get-space-warning"},
  1012  					errors.New("space error"),
  1013  				)
  1014  			})
  1015  			It("returns warnings and error", func() {
  1016  				Expect(executeErr).To(MatchError("space error"))
  1017  			})
  1018  		})
  1019  
  1020  		When("getting the security group fails", func() {
  1021  			BeforeEach(func() {
  1022  				fakeCloudControllerClient.GetSecurityGroupsReturns(
  1023  					[]resources.SecurityGroup{{}},
  1024  					ccv3.Warnings{"get-security-group-warning"},
  1025  					errors.New("security group error"),
  1026  				)
  1027  			})
  1028  			It("returns warnings and error", func() {
  1029  				Expect(executeErr).To(MatchError("security group error"))
  1030  			})
  1031  		})
  1032  
  1033  		When("binding the security group fails", func() {
  1034  			BeforeEach(func() {
  1035  				fakeCloudControllerClient.UnbindSecurityGroupStagingSpaceReturns(
  1036  					ccv3.Warnings{"get-security-group-warning"},
  1037  					errors.New("security group unbind error"),
  1038  				)
  1039  			})
  1040  			It("returns warnings and error", func() {
  1041  				Expect(executeErr).To(MatchError("security group unbind error"))
  1042  			})
  1043  		})
  1044  	})
  1045  
  1046  	Describe("UpdateSecurityGroup", func() {
  1047  		const securityGroupName = "security-group-name"
  1048  		var (
  1049  			filePath              string
  1050  			fileContents          []byte
  1051  			tempFile              *os.File
  1052  			originalSecurityGroup resources.SecurityGroup
  1053  			updatedSecurityGroup  resources.SecurityGroup
  1054  		)
  1055  
  1056  		BeforeEach(func() {
  1057  			originalSecurityGroup = resources.SecurityGroup{
  1058  				Name:  securityGroupName,
  1059  				GUID:  "some-sec-grp-guid",
  1060  				Rules: []resources.Rule{},
  1061  			}
  1062  			fakeCloudControllerClient.GetSecurityGroupsReturns(
  1063  				[]resources.SecurityGroup{originalSecurityGroup},
  1064  				ccv3.Warnings{"get-security-group-warning"},
  1065  				nil,
  1066  			)
  1067  
  1068  			fileContents = []byte(`[
  1069  	{
  1070        "protocol": "tcp",
  1071        "destination": "10.10.10.0/24"
  1072      }
  1073  ]`)
  1074  			tempFile, executeErr = ioutil.TempFile("", "")
  1075  			Expect(executeErr).ToNot(HaveOccurred())
  1076  			filePath = tempFile.Name()
  1077  
  1078  			updatedSecurityGroup = resources.SecurityGroup{
  1079  				Name: securityGroupName,
  1080  				GUID: "some-sec-grp-guid",
  1081  				Rules: []resources.Rule{
  1082  					{
  1083  						Protocol:    "tcp",
  1084  						Destination: "10.10.10.0/24",
  1085  					},
  1086  				},
  1087  			}
  1088  			fakeCloudControllerClient.UpdateSecurityGroupReturns(updatedSecurityGroup, ccv3.Warnings{"update-warning"}, nil)
  1089  		})
  1090  
  1091  		JustBeforeEach(func() {
  1092  			_, err := tempFile.Write(fileContents)
  1093  			Expect(err).ToNot(HaveOccurred())
  1094  
  1095  			warnings, executeErr = actor.UpdateSecurityGroup(securityGroupName, filePath)
  1096  		})
  1097  
  1098  		AfterEach(func() {
  1099  			os.Remove(filePath)
  1100  		})
  1101  
  1102  		It("parses the input file, finds the requested security group, and updates it", func() {
  1103  			Expect(executeErr).ToNot(HaveOccurred())
  1104  			Expect(warnings).To(Equal(Warnings{"get-security-group-warning", "update-warning"}))
  1105  
  1106  			givenQuery := fakeCloudControllerClient.GetSecurityGroupsArgsForCall(0)
  1107  			Expect(givenQuery).To(ConsistOf(
  1108  				ccv3.Query{Key: ccv3.NameFilter, Values: []string{securityGroupName}},
  1109  			))
  1110  
  1111  			givenSecurityGroup := fakeCloudControllerClient.UpdateSecurityGroupArgsForCall(0)
  1112  			Expect(givenSecurityGroup).To(Equal(updatedSecurityGroup))
  1113  		})
  1114  
  1115  		When("the path does not exist", func() {
  1116  			BeforeEach(func() {
  1117  				filePath = "does-not-exist"
  1118  			})
  1119  
  1120  			It("returns an error", func() {
  1121  				Expect(executeErr).To(HaveOccurred())
  1122  				_, ok := executeErr.(*os.PathError)
  1123  				Expect(ok).To(BeTrue())
  1124  				Expect(warnings).To(Equal(Warnings{}))
  1125  			})
  1126  		})
  1127  
  1128  		When("Unmarshaling fails", func() {
  1129  			BeforeEach(func() {
  1130  				fileContents = []byte("not-valid-json")
  1131  			})
  1132  
  1133  			It("returns an error", func() {
  1134  				Expect(executeErr).To(HaveOccurred())
  1135  				_, ok := executeErr.(*json.SyntaxError)
  1136  				Expect(ok).To(BeTrue())
  1137  				Expect(warnings).To(Equal(Warnings{}))
  1138  			})
  1139  		})
  1140  
  1141  		When("the security group does not exist", func() {
  1142  			BeforeEach(func() {
  1143  				fakeCloudControllerClient.GetSecurityGroupsReturns(
  1144  					[]resources.SecurityGroup{},
  1145  					ccv3.Warnings{"get-security-group-warning"},
  1146  					nil,
  1147  				)
  1148  			})
  1149  
  1150  			It("returns a security group not found error and warnings", func() {
  1151  				Expect(executeErr).To(HaveOccurred())
  1152  				Expect(executeErr).To(MatchError(actionerror.SecurityGroupNotFoundError{Name: securityGroupName}))
  1153  				Expect(warnings).To(Equal(Warnings{"get-security-group-warning"}))
  1154  			})
  1155  		})
  1156  
  1157  		When("the security group can't be updated", func() {
  1158  			BeforeEach(func() {
  1159  				fakeCloudControllerClient.UpdateSecurityGroupReturns(
  1160  					resources.SecurityGroup{},
  1161  					ccv3.Warnings{"a-warning"},
  1162  					errors.New("update-error"),
  1163  				)
  1164  			})
  1165  
  1166  			It("returns the error and warnings", func() {
  1167  				Expect(executeErr).To(HaveOccurred())
  1168  				Expect(executeErr).To(MatchError("update-error"))
  1169  				Expect(warnings).To(Equal(Warnings{"get-security-group-warning", "a-warning"}))
  1170  			})
  1171  		})
  1172  	})
  1173  
  1174  	Describe("UpdateSecurityGroupGloballyEnabled", func() {
  1175  		var (
  1176  			securityGroupName = "tom"
  1177  			globallyEnabled   bool
  1178  			lifeycle          constant.SecurityGroupLifecycle
  1179  			executeErr        error
  1180  
  1181  			trueValue  = true
  1182  			falseValue = false
  1183  		)
  1184  
  1185  		JustBeforeEach(func() {
  1186  			warnings, executeErr = actor.UpdateSecurityGroupGloballyEnabled(securityGroupName, lifeycle, globallyEnabled)
  1187  		})
  1188  
  1189  		When("the request succeeds", func() {
  1190  			BeforeEach(func() {
  1191  				fakeCloudControllerClient.GetSecurityGroupsReturns(
  1192  					[]resources.SecurityGroup{
  1193  						{
  1194  							GUID: "some-security-group-guid",
  1195  							Name: securityGroupName,
  1196  						},
  1197  					},
  1198  					ccv3.Warnings{"warning-1"},
  1199  					nil,
  1200  				)
  1201  
  1202  				fakeCloudControllerClient.UpdateSecurityGroupReturns(
  1203  					resources.SecurityGroup{},
  1204  					ccv3.Warnings{"warning-2"},
  1205  					nil,
  1206  				)
  1207  			})
  1208  
  1209  			When("updating staging to true", func() {
  1210  				BeforeEach(func() {
  1211  					lifeycle = constant.SecurityGroupLifecycleStaging
  1212  					globallyEnabled = true
  1213  				})
  1214  
  1215  				It("returns the warnings", func() {
  1216  					Expect(fakeCloudControllerClient.GetSecurityGroupsCallCount()).To(Equal(1))
  1217  					query := fakeCloudControllerClient.GetSecurityGroupsArgsForCall(0)
  1218  					Expect(query).To(Equal([]ccv3.Query{
  1219  						{Key: ccv3.NameFilter, Values: []string{securityGroupName}},
  1220  					}))
  1221  
  1222  					Expect(fakeCloudControllerClient.UpdateSecurityGroupCallCount()).To(Equal(1))
  1223  					args := fakeCloudControllerClient.UpdateSecurityGroupArgsForCall(0)
  1224  					Expect(args).To(Equal(resources.SecurityGroup{
  1225  						GUID:                   "some-security-group-guid",
  1226  						StagingGloballyEnabled: &trueValue,
  1227  					}))
  1228  
  1229  					Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
  1230  					Expect(executeErr).NotTo(HaveOccurred())
  1231  				})
  1232  			})
  1233  
  1234  			When("updating staging to false", func() {
  1235  				BeforeEach(func() {
  1236  					lifeycle = constant.SecurityGroupLifecycleStaging
  1237  					globallyEnabled = false
  1238  				})
  1239  
  1240  				It("returns the warnings", func() {
  1241  					Expect(fakeCloudControllerClient.GetSecurityGroupsCallCount()).To(Equal(1))
  1242  					query := fakeCloudControllerClient.GetSecurityGroupsArgsForCall(0)
  1243  					Expect(query).To(Equal([]ccv3.Query{
  1244  						{Key: ccv3.NameFilter, Values: []string{securityGroupName}},
  1245  					}))
  1246  
  1247  					Expect(fakeCloudControllerClient.UpdateSecurityGroupCallCount()).To(Equal(1))
  1248  					args := fakeCloudControllerClient.UpdateSecurityGroupArgsForCall(0)
  1249  					Expect(args).To(Equal(resources.SecurityGroup{
  1250  						GUID:                   "some-security-group-guid",
  1251  						StagingGloballyEnabled: &falseValue,
  1252  					}))
  1253  
  1254  					Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
  1255  					Expect(executeErr).NotTo(HaveOccurred())
  1256  				})
  1257  			})
  1258  
  1259  			When("updating running to true", func() {
  1260  				BeforeEach(func() {
  1261  					lifeycle = constant.SecurityGroupLifecycleRunning
  1262  					globallyEnabled = true
  1263  				})
  1264  
  1265  				It("returns the warnings", func() {
  1266  					Expect(fakeCloudControllerClient.GetSecurityGroupsCallCount()).To(Equal(1))
  1267  					query := fakeCloudControllerClient.GetSecurityGroupsArgsForCall(0)
  1268  					Expect(query).To(Equal([]ccv3.Query{
  1269  						{Key: ccv3.NameFilter, Values: []string{securityGroupName}},
  1270  					}))
  1271  
  1272  					Expect(fakeCloudControllerClient.UpdateSecurityGroupCallCount()).To(Equal(1))
  1273  					args := fakeCloudControllerClient.UpdateSecurityGroupArgsForCall(0)
  1274  					Expect(args).To(Equal(resources.SecurityGroup{
  1275  						GUID:                   "some-security-group-guid",
  1276  						RunningGloballyEnabled: &trueValue,
  1277  					}))
  1278  
  1279  					Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
  1280  					Expect(executeErr).NotTo(HaveOccurred())
  1281  				})
  1282  			})
  1283  
  1284  			When("updating running to false", func() {
  1285  				BeforeEach(func() {
  1286  					lifeycle = constant.SecurityGroupLifecycleRunning
  1287  					globallyEnabled = false
  1288  				})
  1289  
  1290  				It("returns the warnings", func() {
  1291  					Expect(fakeCloudControllerClient.GetSecurityGroupsCallCount()).To(Equal(1))
  1292  					query := fakeCloudControllerClient.GetSecurityGroupsArgsForCall(0)
  1293  					Expect(query).To(Equal([]ccv3.Query{
  1294  						{Key: ccv3.NameFilter, Values: []string{securityGroupName}},
  1295  					}))
  1296  
  1297  					Expect(fakeCloudControllerClient.UpdateSecurityGroupCallCount()).To(Equal(1))
  1298  					args := fakeCloudControllerClient.UpdateSecurityGroupArgsForCall(0)
  1299  					Expect(args).To(Equal(resources.SecurityGroup{
  1300  						GUID:                   "some-security-group-guid",
  1301  						RunningGloballyEnabled: &falseValue,
  1302  					}))
  1303  
  1304  					Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
  1305  					Expect(executeErr).NotTo(HaveOccurred())
  1306  				})
  1307  			})
  1308  		})
  1309  
  1310  		When("the request to get the security group errors", func() {
  1311  			BeforeEach(func() {
  1312  				lifeycle = constant.SecurityGroupLifecycleRunning
  1313  				globallyEnabled = false
  1314  
  1315  				fakeCloudControllerClient.GetSecurityGroupsReturns(
  1316  					nil,
  1317  					ccv3.Warnings{"warning-1"},
  1318  					errors.New("get-group-error"),
  1319  				)
  1320  
  1321  				fakeCloudControllerClient.UpdateSecurityGroupReturns(
  1322  					resources.SecurityGroup{},
  1323  					ccv3.Warnings{"warning-2"},
  1324  					nil,
  1325  				)
  1326  			})
  1327  
  1328  			It("returns the warnings and error", func() {
  1329  				Expect(warnings).To(ConsistOf("warning-1"))
  1330  				Expect(executeErr).To(MatchError("get-group-error"))
  1331  			})
  1332  		})
  1333  
  1334  		When("the request to update the security group errors", func() {
  1335  			BeforeEach(func() {
  1336  				lifeycle = constant.SecurityGroupLifecycleRunning
  1337  				globallyEnabled = false
  1338  
  1339  				fakeCloudControllerClient.GetSecurityGroupsReturns(
  1340  					[]resources.SecurityGroup{
  1341  						{
  1342  							GUID: "some-security-group-guid",
  1343  							Name: securityGroupName,
  1344  						},
  1345  					},
  1346  					ccv3.Warnings{"warning-1"},
  1347  					nil,
  1348  				)
  1349  
  1350  				fakeCloudControllerClient.UpdateSecurityGroupReturns(
  1351  					resources.SecurityGroup{},
  1352  					ccv3.Warnings{"warning-2"},
  1353  					errors.New("update-group-error"),
  1354  				)
  1355  			})
  1356  
  1357  			It("returns the warnings and error", func() {
  1358  				Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
  1359  				Expect(executeErr).To(MatchError("update-group-error"))
  1360  			})
  1361  		})
  1362  	})
  1363  
  1364  	Describe("DeleteSecurityGroup", func() {
  1365  		var securityGroupName = "elsa"
  1366  
  1367  		JustBeforeEach(func() {
  1368  			warnings, executeErr = actor.DeleteSecurityGroup(securityGroupName)
  1369  		})
  1370  
  1371  		When("the request succeeds", func() {
  1372  			BeforeEach(func() {
  1373  				fakeCloudControllerClient.GetSecurityGroupsReturns(
  1374  					[]resources.SecurityGroup{
  1375  						{
  1376  							GUID: "some-security-group-guid",
  1377  							Name: securityGroupName,
  1378  						},
  1379  					},
  1380  					ccv3.Warnings{"warning-1"},
  1381  					nil,
  1382  				)
  1383  
  1384  				fakeCloudControllerClient.DeleteSecurityGroupReturns(
  1385  					ccv3.JobURL("https://jobs/job_guid"),
  1386  					ccv3.Warnings{"warning-2"},
  1387  					nil,
  1388  				)
  1389  
  1390  				fakeCloudControllerClient.PollJobReturns(
  1391  					ccv3.Warnings{"warning-3"},
  1392  					nil,
  1393  				)
  1394  			})
  1395  
  1396  			It("deletes the security group asynchronously", func() {
  1397  				// Delete the security group asynchronously
  1398  				Expect(fakeCloudControllerClient.DeleteSecurityGroupCallCount()).To(Equal(1))
  1399  				passedSecurityGroupGuid := fakeCloudControllerClient.DeleteSecurityGroupArgsForCall(0)
  1400  				Expect(passedSecurityGroupGuid).To(Equal("some-security-group-guid"))
  1401  
  1402  				// Poll the delete job
  1403  				Expect(fakeCloudControllerClient.PollJobCallCount()).To(Equal(1))
  1404  				responseJobUrl := fakeCloudControllerClient.PollJobArgsForCall(0)
  1405  				Expect(responseJobUrl).To(Equal(ccv3.JobURL("https://jobs/job_guid")))
  1406  			})
  1407  
  1408  			It("returns the warnings and error", func() {
  1409  				Expect(warnings).To(ConsistOf("warning-1", "warning-2", "warning-3"))
  1410  				Expect(executeErr).To(BeNil())
  1411  			})
  1412  		})
  1413  
  1414  		When("the request to get the security group errors", func() {
  1415  			BeforeEach(func() {
  1416  				fakeCloudControllerClient.GetSecurityGroupsReturns(
  1417  					nil,
  1418  					ccv3.Warnings{"warning-1"},
  1419  					errors.New("get-group-error"),
  1420  				)
  1421  
  1422  				fakeCloudControllerClient.DeleteSecurityGroupReturns(
  1423  					ccv3.JobURL(""),
  1424  					ccv3.Warnings{"warning-2"},
  1425  					nil,
  1426  				)
  1427  			})
  1428  
  1429  			It("returns the warnings and error", func() {
  1430  				Expect(warnings).To(ConsistOf("warning-1"))
  1431  				Expect(executeErr).To(MatchError("get-group-error"))
  1432  			})
  1433  		})
  1434  
  1435  		When("the request to delete the security group errors", func() {
  1436  			BeforeEach(func() {
  1437  				fakeCloudControllerClient.GetSecurityGroupsReturns(
  1438  					[]resources.SecurityGroup{
  1439  						{
  1440  							GUID: "some-security-group-guid",
  1441  							Name: securityGroupName,
  1442  						},
  1443  					},
  1444  					ccv3.Warnings{"warning-1"},
  1445  					nil,
  1446  				)
  1447  
  1448  				fakeCloudControllerClient.DeleteSecurityGroupReturns(
  1449  					ccv3.JobURL(""),
  1450  					ccv3.Warnings{"warning-2"},
  1451  					errors.New("delete-group-error"),
  1452  				)
  1453  			})
  1454  
  1455  			It("returns the warnings and error", func() {
  1456  				Expect(warnings).To(ConsistOf("warning-1", "warning-2"))
  1457  				Expect(executeErr).To(MatchError("delete-group-error"))
  1458  			})
  1459  		})
  1460  	})
  1461  })