diff --git a/README.md b/README.md index ed362c3..361e6cd 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ Here is an example config `json`: "app_domain": "my-cf.com", "admin_user": "admin", "admin_password": "PASS", + "isolation_segment": name-of-my-isolation-segment", "tcp_domain": "tcp.my-cf.com", "use_single_app_instance": false, "available_port": 1025 @@ -108,6 +109,9 @@ The `tcp_domain` and `available_port` values are not required _unless_ you elect to run the `app_syslog_availability` test. +The `isolation_segment` value is not required _unless_ +you wish to run uptimer against apps pushed to an isolation segment. + Uptimer by default pushes two instances of an app for its uptime measurements, but it can be configured to push only a single instance diff --git a/cfCmdGenerator/cfCmdGenerator.go b/cfCmdGenerator/cfCmdGenerator.go index b44e48e..97abf02 100644 --- a/cfCmdGenerator/cfCmdGenerator.go +++ b/cfCmdGenerator/cfCmdGenerator.go @@ -18,6 +18,8 @@ type CfCmdGenerator interface { SetQuota(org, quota string) cmdStartWaiter.CmdStartWaiter CreateOrg(org string) cmdStartWaiter.CmdStartWaiter CreateSpace(org, space string) cmdStartWaiter.CmdStartWaiter + EnableOrgIsolation(org, isolationSegment string) cmdStartWaiter.CmdStartWaiter + SetOrgDefaultIsolationSegment(org, isolationSegment string) cmdStartWaiter.CmdStartWaiter Target(org, space string) cmdStartWaiter.CmdStartWaiter Push(name, path string, instances int, noRoute bool) cmdStartWaiter.CmdStartWaiter Delete(name string) cmdStartWaiter.CmdStartWaiter @@ -99,6 +101,21 @@ func (c *cfCmdGenerator) CreateOrg(org string) cmdStartWaiter.CmdStartWaiter { ) } +func (c *cfCmdGenerator) EnableOrgIsolation(org, isolationSegment string) cmdStartWaiter.CmdStartWaiter { + return c.setCfHome( + exec.Command( + "cf", "enable-org-isolation", org, isolationSegment, + ), + ) +} +func (c *cfCmdGenerator) SetOrgDefaultIsolationSegment(org, isolationSegment string) cmdStartWaiter.CmdStartWaiter { + return c.setCfHome( + exec.Command( + "cf", "set-org-default-isolation-segment", org, isolationSegment, + ), + ) +} + func (c *cfCmdGenerator) CreateSpace(org string, space string) cmdStartWaiter.CmdStartWaiter { return c.setCfHome( exec.Command( diff --git a/cfCmdGenerator/cfCmdGenerator_test.go b/cfCmdGenerator/cfCmdGenerator_test.go index 4ec551f..c95c087 100644 --- a/cfCmdGenerator/cfCmdGenerator_test.go +++ b/cfCmdGenerator/cfCmdGenerator_test.go @@ -219,6 +219,22 @@ var _ = Describe("CfCmdGenerator", func() { expectCommandToBeEquivalent(cmd, expectedCmd, cfHomeEnvVar) }) }) + + Describe("EnableOrgIsolation", func() { + It("Generates the correct command", func() { + expectedCmd := exec.Command("cf", "enable-org-isolation", "someOrg", "someIsoSeg") + cmd := generator.EnableOrgIsolation("someOrg", "someIsoSeg") + expectCommandToBeEquivalent(cmd, expectedCmd, cfHomeEnvVar) + }) + }) + + Describe("SetOrgDefaultIsolationSegment", func() { + It("Generates the correct command", func() { + expectedCmd := exec.Command("cf", "set-org-default-isolation-segment", "someOrg", "someIsoSeg") + cmd := generator.SetOrgDefaultIsolationSegment("someOrg", "someIsoSeg") + expectCommandToBeEquivalent(cmd, expectedCmd, cfHomeEnvVar) + }) + }) }) func expectCommandToBeEquivalent(cmd cmdStartWaiter.CmdStartWaiter, expectedCmd *exec.Cmd, envIncludes ...string) { diff --git a/cfCmdGenerator/cfCmdGeneratorfakes/fake_cf_cmd_generator.go b/cfCmdGenerator/cfCmdGeneratorfakes/fake_cf_cmd_generator.go index 99e33b4..f4b1a07 100644 --- a/cfCmdGenerator/cfCmdGeneratorfakes/fake_cf_cmd_generator.go +++ b/cfCmdGenerator/cfCmdGeneratorfakes/fake_cf_cmd_generator.go @@ -135,6 +135,18 @@ type FakeCfCmdGenerator struct { deleteQuotaReturnsOnCall map[int]struct { result1 cmdStartWaiter.CmdStartWaiter } + EnableOrgIsolationStub func(string, string) cmdStartWaiter.CmdStartWaiter + enableOrgIsolationMutex sync.RWMutex + enableOrgIsolationArgsForCall []struct { + arg1 string + arg2 string + } + enableOrgIsolationReturns struct { + result1 cmdStartWaiter.CmdStartWaiter + } + enableOrgIsolationReturnsOnCall map[int]struct { + result1 cmdStartWaiter.CmdStartWaiter + } LogOutStub func() cmdStartWaiter.CmdStartWaiter logOutMutex sync.RWMutex logOutArgsForCall []struct { @@ -194,6 +206,18 @@ type FakeCfCmdGenerator struct { restageReturnsOnCall map[int]struct { result1 cmdStartWaiter.CmdStartWaiter } + SetOrgDefaultIsolationSegmentStub func(string, string) cmdStartWaiter.CmdStartWaiter + setOrgDefaultIsolationSegmentMutex sync.RWMutex + setOrgDefaultIsolationSegmentArgsForCall []struct { + arg1 string + arg2 string + } + setOrgDefaultIsolationSegmentReturns struct { + result1 cmdStartWaiter.CmdStartWaiter + } + setOrgDefaultIsolationSegmentReturnsOnCall map[int]struct { + result1 cmdStartWaiter.CmdStartWaiter + } SetQuotaStub func(string, string) cmdStartWaiter.CmdStartWaiter setQuotaMutex sync.RWMutex setQuotaArgsForCall []struct { @@ -909,6 +933,68 @@ func (fake *FakeCfCmdGenerator) DeleteQuotaReturnsOnCall(i int, result1 cmdStart }{result1} } +func (fake *FakeCfCmdGenerator) EnableOrgIsolation(arg1 string, arg2 string) cmdStartWaiter.CmdStartWaiter { + fake.enableOrgIsolationMutex.Lock() + ret, specificReturn := fake.enableOrgIsolationReturnsOnCall[len(fake.enableOrgIsolationArgsForCall)] + fake.enableOrgIsolationArgsForCall = append(fake.enableOrgIsolationArgsForCall, struct { + arg1 string + arg2 string + }{arg1, arg2}) + stub := fake.EnableOrgIsolationStub + fakeReturns := fake.enableOrgIsolationReturns + fake.recordInvocation("EnableOrgIsolation", []interface{}{arg1, arg2}) + fake.enableOrgIsolationMutex.Unlock() + if stub != nil { + return stub(arg1, arg2) + } + if specificReturn { + return ret.result1 + } + return fakeReturns.result1 +} + +func (fake *FakeCfCmdGenerator) EnableOrgIsolationCallCount() int { + fake.enableOrgIsolationMutex.RLock() + defer fake.enableOrgIsolationMutex.RUnlock() + return len(fake.enableOrgIsolationArgsForCall) +} + +func (fake *FakeCfCmdGenerator) EnableOrgIsolationCalls(stub func(string, string) cmdStartWaiter.CmdStartWaiter) { + fake.enableOrgIsolationMutex.Lock() + defer fake.enableOrgIsolationMutex.Unlock() + fake.EnableOrgIsolationStub = stub +} + +func (fake *FakeCfCmdGenerator) EnableOrgIsolationArgsForCall(i int) (string, string) { + fake.enableOrgIsolationMutex.RLock() + defer fake.enableOrgIsolationMutex.RUnlock() + argsForCall := fake.enableOrgIsolationArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeCfCmdGenerator) EnableOrgIsolationReturns(result1 cmdStartWaiter.CmdStartWaiter) { + fake.enableOrgIsolationMutex.Lock() + defer fake.enableOrgIsolationMutex.Unlock() + fake.EnableOrgIsolationStub = nil + fake.enableOrgIsolationReturns = struct { + result1 cmdStartWaiter.CmdStartWaiter + }{result1} +} + +func (fake *FakeCfCmdGenerator) EnableOrgIsolationReturnsOnCall(i int, result1 cmdStartWaiter.CmdStartWaiter) { + fake.enableOrgIsolationMutex.Lock() + defer fake.enableOrgIsolationMutex.Unlock() + fake.EnableOrgIsolationStub = nil + if fake.enableOrgIsolationReturnsOnCall == nil { + fake.enableOrgIsolationReturnsOnCall = make(map[int]struct { + result1 cmdStartWaiter.CmdStartWaiter + }) + } + fake.enableOrgIsolationReturnsOnCall[i] = struct { + result1 cmdStartWaiter.CmdStartWaiter + }{result1} +} + func (fake *FakeCfCmdGenerator) LogOut() cmdStartWaiter.CmdStartWaiter { fake.logOutMutex.Lock() ret, specificReturn := fake.logOutReturnsOnCall[len(fake.logOutArgsForCall)] @@ -1211,6 +1297,68 @@ func (fake *FakeCfCmdGenerator) RestageReturnsOnCall(i int, result1 cmdStartWait }{result1} } +func (fake *FakeCfCmdGenerator) SetOrgDefaultIsolationSegment(arg1 string, arg2 string) cmdStartWaiter.CmdStartWaiter { + fake.setOrgDefaultIsolationSegmentMutex.Lock() + ret, specificReturn := fake.setOrgDefaultIsolationSegmentReturnsOnCall[len(fake.setOrgDefaultIsolationSegmentArgsForCall)] + fake.setOrgDefaultIsolationSegmentArgsForCall = append(fake.setOrgDefaultIsolationSegmentArgsForCall, struct { + arg1 string + arg2 string + }{arg1, arg2}) + stub := fake.SetOrgDefaultIsolationSegmentStub + fakeReturns := fake.setOrgDefaultIsolationSegmentReturns + fake.recordInvocation("SetOrgDefaultIsolationSegment", []interface{}{arg1, arg2}) + fake.setOrgDefaultIsolationSegmentMutex.Unlock() + if stub != nil { + return stub(arg1, arg2) + } + if specificReturn { + return ret.result1 + } + return fakeReturns.result1 +} + +func (fake *FakeCfCmdGenerator) SetOrgDefaultIsolationSegmentCallCount() int { + fake.setOrgDefaultIsolationSegmentMutex.RLock() + defer fake.setOrgDefaultIsolationSegmentMutex.RUnlock() + return len(fake.setOrgDefaultIsolationSegmentArgsForCall) +} + +func (fake *FakeCfCmdGenerator) SetOrgDefaultIsolationSegmentCalls(stub func(string, string) cmdStartWaiter.CmdStartWaiter) { + fake.setOrgDefaultIsolationSegmentMutex.Lock() + defer fake.setOrgDefaultIsolationSegmentMutex.Unlock() + fake.SetOrgDefaultIsolationSegmentStub = stub +} + +func (fake *FakeCfCmdGenerator) SetOrgDefaultIsolationSegmentArgsForCall(i int) (string, string) { + fake.setOrgDefaultIsolationSegmentMutex.RLock() + defer fake.setOrgDefaultIsolationSegmentMutex.RUnlock() + argsForCall := fake.setOrgDefaultIsolationSegmentArgsForCall[i] + return argsForCall.arg1, argsForCall.arg2 +} + +func (fake *FakeCfCmdGenerator) SetOrgDefaultIsolationSegmentReturns(result1 cmdStartWaiter.CmdStartWaiter) { + fake.setOrgDefaultIsolationSegmentMutex.Lock() + defer fake.setOrgDefaultIsolationSegmentMutex.Unlock() + fake.SetOrgDefaultIsolationSegmentStub = nil + fake.setOrgDefaultIsolationSegmentReturns = struct { + result1 cmdStartWaiter.CmdStartWaiter + }{result1} +} + +func (fake *FakeCfCmdGenerator) SetOrgDefaultIsolationSegmentReturnsOnCall(i int, result1 cmdStartWaiter.CmdStartWaiter) { + fake.setOrgDefaultIsolationSegmentMutex.Lock() + defer fake.setOrgDefaultIsolationSegmentMutex.Unlock() + fake.SetOrgDefaultIsolationSegmentStub = nil + if fake.setOrgDefaultIsolationSegmentReturnsOnCall == nil { + fake.setOrgDefaultIsolationSegmentReturnsOnCall = make(map[int]struct { + result1 cmdStartWaiter.CmdStartWaiter + }) + } + fake.setOrgDefaultIsolationSegmentReturnsOnCall[i] = struct { + result1 cmdStartWaiter.CmdStartWaiter + }{result1} +} + func (fake *FakeCfCmdGenerator) SetQuota(arg1 string, arg2 string) cmdStartWaiter.CmdStartWaiter { fake.setQuotaMutex.Lock() ret, specificReturn := fake.setQuotaReturnsOnCall[len(fake.setQuotaArgsForCall)] @@ -1422,6 +1570,8 @@ func (fake *FakeCfCmdGenerator) Invocations() map[string][][]interface{} { defer fake.deleteOrgMutex.RUnlock() fake.deleteQuotaMutex.RLock() defer fake.deleteQuotaMutex.RUnlock() + fake.enableOrgIsolationMutex.RLock() + defer fake.enableOrgIsolationMutex.RUnlock() fake.logOutMutex.RLock() defer fake.logOutMutex.RUnlock() fake.mapRouteMutex.RLock() @@ -1432,6 +1582,8 @@ func (fake *FakeCfCmdGenerator) Invocations() map[string][][]interface{} { defer fake.recentLogsMutex.RUnlock() fake.restageMutex.RLock() defer fake.restageMutex.RUnlock() + fake.setOrgDefaultIsolationSegmentMutex.RLock() + defer fake.setOrgDefaultIsolationSegmentMutex.RUnlock() fake.setQuotaMutex.RLock() defer fake.setQuotaMutex.RUnlock() fake.streamLogsMutex.RLock() diff --git a/cfWorkflow/cfWorkflow.go b/cfWorkflow/cfWorkflow.go index b8d52d8..b49c7d4 100644 --- a/cfWorkflow/cfWorkflow.go +++ b/cfWorkflow/cfWorkflow.go @@ -82,8 +82,16 @@ func (c *cfWorkflow) Setup(ccg cfCmdGenerator.CfCmdGenerator) []cmdStartWaiter.C ccg.Api(c.cf.API), ccg.Auth(c.cf.AdminUser, c.cf.AdminPassword), ccg.CreateOrg(c.org), - ccg.CreateSpace(c.org, c.space), } + + if c.cf.IsolationSegment != "" { + ret = append(ret, + ccg.EnableOrgIsolation(c.org, c.cf.IsolationSegment), + ccg.SetOrgDefaultIsolationSegment(c.org, c.cf.IsolationSegment), + ) + } + ret = append(ret, ccg.CreateSpace(c.org, c.space)) + if c.quota != "" { ret = append(ret, ccg.CreateQuota(c.quota), ccg.SetQuota(c.org, c.quota)) } diff --git a/cfWorkflow/cfWorkflow_test.go b/cfWorkflow/cfWorkflow_test.go index f696a86..055f3ec 100644 --- a/cfWorkflow/cfWorkflow_test.go +++ b/cfWorkflow/cfWorkflow_test.go @@ -180,6 +180,25 @@ var _ = Describe("CfWorkflow", func() { )) }) }) + When("Isolation Segments are provided", func() { + BeforeEach(func() { cfc.IsolationSegment = "someIsoSeg" }) + It("returns a series of commands including setting up the isolation segment for the org/space", func() { + cmds := cw.Setup(ccg) + + Expect(cmds).To(Equal( + []cmdStartWaiter.CmdStartWaiter{ + ccg.Api("jigglypuff.cf-app.com"), + ccg.Auth("pika", "chu"), + ccg.CreateOrg("someOrg"), + ccg.EnableOrgIsolation("someOrg", "someIsoSeg"), + ccg.SetOrgDefaultIsolationSegment("someOrg", "someIsoSeg"), + ccg.CreateSpace("someOrg", "someSpace"), + ccg.CreateQuota("someQuota"), + ccg.SetQuota("someOrg", "someQuota"), + }, + )) + }) + }) }) Describe("TearDown", func() { diff --git a/config/config.go b/config/config.go index eed0719..6def9df 100644 --- a/config/config.go +++ b/config/config.go @@ -19,10 +19,11 @@ type Command struct { } type Cf struct { - API string `json:"api"` - AppDomain string `json:"app_domain"` - AdminUser string `json:"admin_user"` - AdminPassword string `json:"admin_password"` + API string `json:"api"` + AppDomain string `json:"app_domain"` + AdminUser string `json:"admin_user"` + AdminPassword string `json:"admin_password"` + IsolationSegment string `json:"isolation_segment"` TCPDomain string `json:"tcp_domain"` TCPPort int `json:"tcp_port"`