github.com/nimakaviani/cli@v6.37.1-0.20180619223813-e734901a73fa+incompatible/integration/experimental/unshare_service_command_test.go (about) 1 package experimental 2 3 import ( 4 "code.cloudfoundry.org/cli/api/cloudcontroller/ccversion" 5 "code.cloudfoundry.org/cli/integration/helpers" 6 . "github.com/onsi/ginkgo" 7 . "github.com/onsi/gomega" 8 . "github.com/onsi/gomega/gbytes" 9 . "github.com/onsi/gomega/gexec" 10 . "github.com/onsi/gomega/ghttp" 11 ) 12 13 var _ = Describe("unshare-service command", func() { 14 var ( 15 sourceOrgName string 16 sourceSpaceName string 17 sharedToOrgName string 18 sharedToSpaceName string 19 serviceInstance string 20 ) 21 22 BeforeEach(func() { 23 helpers.SkipIfVersionLessThan(ccversion.MinVersionShareServiceV3) 24 25 sourceOrgName = helpers.NewOrgName() 26 sourceSpaceName = helpers.NewSpaceName() 27 sharedToOrgName = helpers.NewOrgName() 28 sharedToSpaceName = helpers.NewSpaceName() 29 serviceInstance = helpers.PrefixedRandomName("svc-inst") 30 31 helpers.LoginCF() 32 }) 33 34 Describe("help", func() { 35 Context("when --help flag is set", func() { 36 It("Displays command usage to output", func() { 37 session := helpers.CF("unshare-service", "--help") 38 Eventually(session).Should(Say("NAME:")) 39 Eventually(session).Should(Say("unshare-service - Unshare a shared service instance from a space")) 40 Eventually(session).Should(Say("USAGE:")) 41 Eventually(session).Should(Say("cf unshare-service SERVICE_INSTANCE -s OTHER_SPACE \\[-o OTHER_ORG\\] \\[-f\\]")) 42 Eventually(session).Should(Say("OPTIONS:")) 43 Eventually(session).Should(Say("-o\\s+Org of the other space \\(Default: targeted org\\)")) 44 Eventually(session).Should(Say("-s\\s+Space to unshare the service instance from")) 45 Eventually(session).Should(Say("-f\\s+Force unshare without confirmation")) 46 Eventually(session).Should(Say("SEE ALSO:")) 47 Eventually(session).Should(Say("delete-service, service, services, share-service, unbind-service")) 48 Eventually(session).Should(Exit(0)) 49 }) 50 }) 51 }) 52 53 Context("when the service instance name is not provided", func() { 54 It("tells the user that the service instance name is required, prints help text, and exits 1", func() { 55 session := helpers.CF("unshare-service", "-s", sharedToSpaceName) 56 57 Eventually(session.Err).Should(Say("Incorrect Usage: the required argument `SERVICE_INSTANCE` was not provided")) 58 Eventually(session).Should(Say("NAME:")) 59 Eventually(session).Should(Exit(1)) 60 }) 61 }) 62 63 Context("when the space name is not provided", func() { 64 It("tells the user that the space name is required, prints help text, and exits 1", func() { 65 session := helpers.CF("unshare-service") 66 67 Eventually(session.Err).Should(Say("Incorrect Usage: the required flag `-s' was not specified")) 68 Eventually(session).Should(Say("NAME:")) 69 Eventually(session).Should(Exit(1)) 70 }) 71 }) 72 73 Context("when the environment is not setup correctly", func() { 74 It("fails with the appropriate errors", func() { 75 helpers.CheckEnvironmentTargetedCorrectly(true, true, ReadOnlyOrg, "unshare-service", serviceInstance, "-s", sharedToSpaceName) 76 }) 77 78 Context("when the v3 api does not exist", func() { 79 var server *Server 80 81 BeforeEach(func() { 82 server = helpers.StartAndTargetServerWithoutV3API() 83 }) 84 85 AfterEach(func() { 86 server.Close() 87 }) 88 89 It("fails with error message that the minimum version is not met", func() { 90 session := helpers.CF("unshare-service", serviceInstance, "-s", sharedToSpaceName) 91 Eventually(session).Should(Say("FAILED")) 92 Eventually(session.Err).Should(Say("This command requires CF API version 3\\.36\\.0 or higher\\.")) 93 Eventually(session).Should(Exit(1)) 94 }) 95 }) 96 97 Context("when the v3 api version is lower than the minimum version", func() { 98 var server *Server 99 100 BeforeEach(func() { 101 server = helpers.StartAndTargetServerWithAPIVersions(helpers.DefaultV2Version, "3.0.0") 102 }) 103 104 AfterEach(func() { 105 server.Close() 106 }) 107 108 It("fails with error message that the minimum version is not met", func() { 109 session := helpers.CF("unshare-service", serviceInstance, "-s", sharedToSpaceName) 110 Eventually(session).Should(Say("FAILED")) 111 Eventually(session.Err).Should(Say("This command requires CF API version 3\\.36\\.0 or higher\\.")) 112 Eventually(session).Should(Exit(1)) 113 }) 114 }) 115 }) 116 117 Context("when the environment is set up correctly", func() { 118 var ( 119 domain string 120 service string 121 servicePlan string 122 ) 123 124 BeforeEach(func() { 125 service = helpers.PrefixedRandomName("SERVICE") 126 servicePlan = helpers.PrefixedRandomName("SERVICE-PLAN") 127 128 helpers.CreateOrgAndSpace(sharedToOrgName, sharedToSpaceName) 129 helpers.SetupCF(sourceOrgName, sourceSpaceName) 130 131 domain = helpers.DefaultSharedDomain() 132 }) 133 134 AfterEach(func() { 135 helpers.QuickDeleteOrg(sourceOrgName) 136 helpers.QuickDeleteOrg(sharedToOrgName) 137 }) 138 139 Context("when there is a managed service instance in my current targeted space", func() { 140 var broker helpers.ServiceBroker 141 142 BeforeEach(func() { 143 broker = helpers.NewServiceBroker(helpers.NewServiceBrokerName(), helpers.NewAssets().ServiceBroker, domain, service, servicePlan) 144 broker.Push() 145 broker.Configure(true) 146 broker.Create() 147 148 Eventually(helpers.CF("enable-service-access", service)).Should(Exit(0)) 149 Eventually(helpers.CF("create-service", service, servicePlan, serviceInstance)).Should(Exit(0)) 150 }) 151 152 AfterEach(func() { 153 broker.Destroy() 154 }) 155 156 Context("when the service instance has not been shared to this space", func() { 157 It("displays info and idempotently exits 0", func() { 158 session := helpers.CF("unshare-service", serviceInstance, "-s", sharedToSpaceName, "-o", sharedToOrgName, "-f") 159 Eventually(session).Should(Say("Service instance %s is not shared with space %s in organization %s\\.", serviceInstance, sharedToSpaceName, sharedToOrgName)) 160 Eventually(session).Should(Say("OK")) 161 Eventually(session).Should(Exit(0)) 162 }) 163 }) 164 165 Context("when I have shared my service instance to a space in another org ('-o' flag provided)", func() { 166 BeforeEach(func() { 167 session := helpers.CF("share-service", serviceInstance, "-s", sharedToSpaceName, "-o", sharedToOrgName) 168 Eventually(session).Should(Exit(0)) 169 }) 170 171 Context("when the org I want to unshare from does not exist", func() { 172 It("fails with an org not found error", func() { 173 session := helpers.CF("unshare-service", serviceInstance, "-s", sharedToSpaceName, "-o", "missing-org", "-f") 174 Eventually(session).Should(Say("Service instance %s is not shared with space %s in organization missing-org\\.", serviceInstance, sharedToSpaceName)) 175 Eventually(session).Should(Say("OK")) 176 Eventually(session).Should(Exit(0)) 177 }) 178 }) 179 180 Context("when the space I want to unshare from does not exist", func() { 181 It("fails with a space not found error", func() { 182 session := helpers.CF("unshare-service", serviceInstance, "-s", "missing-space", "-o", sharedToOrgName, "-f") 183 Eventually(session).Should(Say("Service instance %s is not shared with space missing-space in organization %s\\.", serviceInstance, sharedToOrgName)) 184 Eventually(session).Should(Say("OK")) 185 Eventually(session).Should(Exit(0)) 186 }) 187 }) 188 189 Context("when I want to unshare my service instance from a space and org", func() { 190 It("successfully unshares the service instance", func() { 191 username, _ := helpers.GetCredentials() 192 session := helpers.CF("unshare-service", serviceInstance, "-s", sharedToSpaceName, "-o", sharedToOrgName, "-f") 193 Eventually(session).Should(Say("Unsharing service instance %s from org %s / space %s as %s\\.\\.\\.", serviceInstance, sharedToOrgName, sharedToSpaceName, username)) 194 Eventually(session).Should(Say("OK")) 195 Eventually(session).Should(Exit(0)) 196 }) 197 }) 198 }) 199 200 Context("when I have shared my service instance to a space within the targeted org ('-o' flag NOT provided)", func() { 201 BeforeEach(func() { 202 helpers.CreateSpace(sharedToSpaceName) 203 204 session := helpers.CF("share-service", serviceInstance, "-s", sharedToSpaceName) 205 Eventually(session).Should(Exit(0)) 206 }) 207 208 Context("when the space I want to unshare from does not exist", func() { 209 It("fails with a space not found error", func() { 210 session := helpers.CF("unshare-service", serviceInstance, "-s", "missing-space", "-f") 211 Eventually(session).Should(Say("Service instance %s is not shared with space missing-space in organization %s\\.", serviceInstance, sourceOrgName)) 212 Eventually(session).Should(Say("OK")) 213 Eventually(session).Should(Exit(0)) 214 }) 215 }) 216 217 Context("when I want to unshare my service instance from the space", func() { 218 It("successfully unshares the service instance when I am admin", func() { 219 username, _ := helpers.GetCredentials() 220 session := helpers.CF("unshare-service", serviceInstance, "-s", sharedToSpaceName, "-f") 221 Eventually(session).Should(Say("Unsharing service instance %s from org %s / space %s as %s\\.\\.\\.", serviceInstance, sourceOrgName, sharedToSpaceName, username)) 222 Eventually(session).Should(Say("OK")) 223 Eventually(session).Should(Exit(0)) 224 }) 225 226 Context("when I have no access to the shared-to space", func() { 227 var ( 228 username string 229 password string 230 ) 231 232 BeforeEach(func() { 233 username = helpers.NewUsername() 234 password = helpers.NewPassword() 235 Eventually(helpers.CF("create-user", username, password)).Should(Exit(0)) 236 Eventually(helpers.CF("set-space-role", username, sourceOrgName, sourceSpaceName, "SpaceDeveloper")).Should(Exit(0)) 237 env := map[string]string{ 238 "CF_USERNAME": username, 239 "CF_PASSWORD": password, 240 } 241 Eventually(helpers.CFWithEnv(env, "auth")).Should(Exit(0)) 242 helpers.TargetOrgAndSpace(sourceOrgName, sourceSpaceName) 243 }) 244 245 AfterEach(func() { 246 helpers.LoginCF() 247 helpers.TargetOrgAndSpace(sourceOrgName, sourceSpaceName) 248 session := helpers.CF("delete-user", username, "-f") 249 Eventually(session).Should(Say("OK")) 250 Eventually(session).Should(Exit(0)) 251 }) 252 253 It("successfully unshares the service instance", func() { 254 session := helpers.CF("unshare-service", serviceInstance, "-s", sharedToSpaceName, "-f") 255 Eventually(session).Should(Say("OK")) 256 Eventually(session).Should(Exit(0)) 257 }) 258 }) 259 }) 260 }) 261 }) 262 263 Context("when the service instance does not exist", func() { 264 Context("when the -f flag is provided", func() { 265 It("fails with a service instance not found error", func() { 266 session := helpers.CF("unshare-service", serviceInstance, "-s", sharedToSpaceName, "-f") 267 Eventually(session).Should(Say("FAILED")) 268 Eventually(session.Err).Should(Say("Specified instance not found or not a managed service instance\\. Sharing is not supported for user provided services\\.")) 269 Eventually(session).Should(Exit(1)) 270 }) 271 }) 272 273 Context("when the -f flag not is provided", func() { 274 var buffer *Buffer 275 276 BeforeEach(func() { 277 buffer = NewBuffer() 278 }) 279 280 Context("when the user enters 'y'", func() { 281 BeforeEach(func() { 282 buffer.Write([]byte("y\n")) 283 }) 284 285 It("fails with a service instance not found error", func() { 286 username, _ := helpers.GetCredentials() 287 session := helpers.CFWithStdin(buffer, "unshare-service", serviceInstance, "-s", sharedToSpaceName) 288 Eventually(session.Err).Should(Say("WARNING: Unsharing this service instance will remove any service bindings that exist in any spaces that this instance is shared into\\. This could cause applications to stop working\\.")) 289 Eventually(session).Should(Say("Really unshare the service instance\\? \\[yN\\]")) 290 Eventually(session).Should(Say("Unsharing service instance %s from org %s / space %s as %s\\.\\.\\.", serviceInstance, sourceOrgName, sharedToSpaceName, username)) 291 Eventually(session).Should(Say("FAILED")) 292 Eventually(session.Err).Should(Say("Specified instance not found or not a managed service instance\\. Sharing is not supported for user provided services\\.")) 293 Eventually(session).Should(Exit(1)) 294 }) 295 }) 296 297 Context("when the user enters 'n'", func() { 298 BeforeEach(func() { 299 buffer.Write([]byte("n\n")) 300 }) 301 302 It("does not attempt to unshare", func() { 303 session := helpers.CFWithStdin(buffer, "unshare-service", serviceInstance, "-s", sharedToSpaceName) 304 Eventually(session.Err).Should(Say("WARNING: Unsharing this service instance will remove any service bindings that exist in any spaces that this instance is shared into\\. This could cause applications to stop working\\.")) 305 Eventually(session).Should(Say("Really unshare the service instance\\? \\[yN\\]")) 306 Eventually(session).Should(Say("Unshare cancelled")) 307 Eventually(session).Should(Exit(0)) 308 }) 309 }) 310 311 Context("when the user enters the default input (hits return)", func() { 312 BeforeEach(func() { 313 buffer.Write([]byte("\n")) 314 }) 315 316 It("does not attempt to unshare", func() { 317 session := helpers.CFWithStdin(buffer, "unshare-service", serviceInstance, "-s", sharedToSpaceName) 318 Eventually(session.Err).Should(Say("WARNING: Unsharing this service instance will remove any service bindings that exist in any spaces that this instance is shared into\\. This could cause applications to stop working\\.")) 319 Eventually(session).Should(Say("Really unshare the service instance\\? \\[yN\\]")) 320 Eventually(session).Should(Say("Unshare cancelled")) 321 Eventually(session).Should(Exit(0)) 322 }) 323 }) 324 325 Context("when the user enters an invalid answer", func() { 326 BeforeEach(func() { 327 // The second '\n' is intentional. Otherwise the buffer will be 328 // closed while the interaction is still waiting for input; it gets 329 // an EOF and causes an error. 330 buffer.Write([]byte("wat\n\n")) 331 }) 332 333 It("asks again", func() { 334 session := helpers.CFWithStdin(buffer, "unshare-service", serviceInstance, "-s", sharedToSpaceName) 335 Eventually(session.Err).Should(Say("WARNING: Unsharing this service instance will remove any service bindings that exist in any spaces that this instance is shared into\\. This could cause applications to stop working\\.")) 336 Eventually(session).Should(Say("Really unshare the service instance\\? \\[yN\\]")) 337 Eventually(session).Should(Say("invalid input \\(not y, n, yes, or no\\)")) 338 Eventually(session).Should(Say("Really unshare the service instance\\? \\[yN\\]")) 339 Eventually(session).Should(Say("Unshare cancelled")) 340 Eventually(session).Should(Exit(0)) 341 }) 342 }) 343 }) 344 }) 345 346 Context("when there is a shared service instance in my currently targeted space", func() { 347 var broker helpers.ServiceBroker 348 var user string 349 var password string 350 351 BeforeEach(func() { 352 broker = helpers.NewServiceBroker(helpers.NewServiceBrokerName(), helpers.NewAssets().ServiceBroker, domain, service, servicePlan) 353 broker.Push() 354 broker.Configure(true) 355 broker.Create() 356 user = helpers.NewUsername() 357 password = helpers.NewPassword() 358 359 helpers.SetupCF(sourceOrgName, sourceSpaceName) 360 Eventually(helpers.CF("enable-service-access", service)).Should(Exit(0)) 361 Eventually(helpers.CF("create-service", service, servicePlan, serviceInstance)).Should(Exit(0)) 362 Eventually(helpers.CF("share-service", serviceInstance, "-s", sharedToSpaceName, "-o", sharedToOrgName)).Should(Exit(0)) 363 364 Eventually(helpers.CF("create-user", user, password)).Should(Exit(0)) 365 Eventually(helpers.CF("set-space-role", user, sharedToOrgName, sharedToSpaceName, "SpaceDeveloper")).Should(Exit(0)) 366 }) 367 368 AfterEach(func() { 369 helpers.SetupCF(sourceOrgName, sourceSpaceName) 370 Eventually(helpers.CF("delete-user", user)).Should(Exit(0)) 371 broker.Destroy() 372 }) 373 374 Context("and I have no access to the source space", func() { 375 BeforeEach(func() { 376 env := map[string]string{ 377 "CF_USERNAME": user, 378 "CF_PASSWORD": password, 379 } 380 Eventually(helpers.CFWithEnv(env, "auth")).Should(Exit(0)) 381 Eventually(helpers.CF("target", "-o", sharedToOrgName, "-s", sharedToSpaceName)).Should(Exit(0)) 382 }) 383 384 It("returns a permission error on an attempt to unshare the service", func() { 385 session := helpers.CF("unshare-service", serviceInstance, "-s", sharedToSpaceName, "-o", sharedToOrgName, "-f") 386 Eventually(session).Should(Say("FAILED")) 387 Eventually(session.Err).Should(Say("You are not authorized to perform the requested action")) 388 Eventually(session).Should(Exit(1)) 389 }) 390 }) 391 392 Context("and I have SpaceAuditor access to the source space", func() { 393 BeforeEach(func() { 394 env := map[string]string{ 395 "CF_USERNAME": user, 396 "CF_PASSWORD": password, 397 } 398 Eventually(helpers.CF("set-space-role", user, sourceOrgName, sourceSpaceName, "SpaceAuditor")).Should(Exit(0)) 399 Eventually(helpers.CFWithEnv(env, "auth")).Should(Exit(0)) 400 Eventually(helpers.CF("target", "-o", sharedToOrgName, "-s", sharedToSpaceName)).Should(Exit(0)) 401 }) 402 403 It("returns a permission error on an attempt to unshare the service", func() { 404 session := helpers.CF("unshare-service", serviceInstance, "-s", sharedToSpaceName, "-o", sharedToOrgName, "-f") 405 Eventually(session).Should(Say("FAILED")) 406 Eventually(session.Err).Should(Say("You are not authorized to perform the requested action")) 407 Eventually(session).Should(Exit(1)) 408 }) 409 }) 410 }) 411 }) 412 })