github.com/nimakaviani/cli@v6.37.1-0.20180619223813-e734901a73fa+incompatible/integration/global/share_service_command_test.go (about) 1 package global 2 3 import ( 4 "fmt" 5 6 "code.cloudfoundry.org/cli/api/cloudcontroller/ccversion" 7 "code.cloudfoundry.org/cli/integration/helpers" 8 . "github.com/onsi/ginkgo" 9 . "github.com/onsi/gomega" 10 . "github.com/onsi/gomega/gbytes" 11 . "github.com/onsi/gomega/gexec" 12 . "github.com/onsi/gomega/ghttp" 13 ) 14 15 var _ = Describe("share-service command", func() { 16 var ( 17 sourceOrgName string 18 sourceSpaceName string 19 sharedToOrgName string 20 sharedToSpaceName string 21 serviceInstance string 22 ) 23 24 BeforeEach(func() { 25 helpers.SkipIfVersionLessThan(ccversion.MinVersionShareServiceV3) 26 27 sourceOrgName = helpers.NewOrgName() 28 sourceSpaceName = helpers.NewSpaceName() 29 sharedToOrgName = helpers.NewOrgName() 30 sharedToSpaceName = helpers.NewSpaceName() 31 serviceInstance = helpers.PrefixedRandomName("svc-inst") 32 33 helpers.LoginCF() 34 session := helpers.CF("enable-feature-flag", "service_instance_sharing") 35 Eventually(session).Should(Exit(0)) 36 }) 37 38 Describe("help", func() { 39 Context("when --help flag is set", func() { 40 It("Displays command usage to output", func() { 41 session := helpers.CF("share-service", "--help") 42 Eventually(session).Should(Say("NAME:")) 43 Eventually(session).Should(Say("share-service - Share a service instance with another space")) 44 Eventually(session).Should(Say("USAGE:")) 45 Eventually(session).Should(Say("cf share-service SERVICE_INSTANCE -s OTHER_SPACE \\[-o OTHER_ORG\\]")) 46 Eventually(session).Should(Say("OPTIONS:")) 47 Eventually(session).Should(Say("-o\\s+Org of the other space \\(Default: targeted org\\)")) 48 Eventually(session).Should(Say("-s\\s+Space to share the service instance into")) 49 Eventually(session).Should(Say("SEE ALSO:")) 50 Eventually(session).Should(Say("bind-service, service, services, unshare-service")) 51 Eventually(session).Should(Exit(0)) 52 }) 53 }) 54 }) 55 56 Context("when the service instance name is not provided", func() { 57 It("tells the user that the service instance name is required, prints help text, and exits 1", func() { 58 session := helpers.CF("share-service", "-s", sharedToSpaceName) 59 60 Eventually(session.Err).Should(Say("Incorrect Usage: the required argument `SERVICE_INSTANCE` was not provided")) 61 Eventually(session).Should(Say("NAME:")) 62 Eventually(session).Should(Exit(1)) 63 }) 64 }) 65 66 Context("when the space name is not provided", func() { 67 It("tells the user that the space name is required, prints help text, and exits 1", func() { 68 session := helpers.CF("share-service") 69 70 Eventually(session.Err).Should(Say("Incorrect Usage: the required flag `-s' was not specified")) 71 Eventually(session).Should(Say("NAME:")) 72 Eventually(session).Should(Exit(1)) 73 }) 74 }) 75 76 Context("when the environment is not setup correctly", func() { 77 It("fails with the appropriate errors", func() { 78 helpers.CheckEnvironmentTargetedCorrectly(true, true, ReadOnlyOrg, "share-service", serviceInstance, "-s", sharedToSpaceName) 79 }) 80 81 Context("when the v3 api does not exist", func() { 82 var server *Server 83 84 BeforeEach(func() { 85 server = helpers.StartAndTargetServerWithoutV3API() 86 }) 87 88 AfterEach(func() { 89 server.Close() 90 }) 91 92 It("fails with error message that the minimum version is not met", func() { 93 session := helpers.CF("share-service", serviceInstance, "-s", sharedToSpaceName) 94 Eventually(session).Should(Say("FAILED")) 95 Eventually(session.Err).Should(Say("This command requires CF API version 3\\.36\\.0 or higher\\.")) 96 Eventually(session).Should(Exit(1)) 97 }) 98 }) 99 100 Context("when the v3 api version is lower than the minimum version", func() { 101 var server *Server 102 103 BeforeEach(func() { 104 server = helpers.StartAndTargetServerWithAPIVersions(helpers.DefaultV2Version, "3.0.0") 105 }) 106 107 AfterEach(func() { 108 server.Close() 109 }) 110 111 It("fails with error message that the minimum version is not met", func() { 112 session := helpers.CF("share-service", serviceInstance, "-s", sharedToSpaceName) 113 Eventually(session).Should(Say("FAILED")) 114 Eventually(session.Err).Should(Say("This command requires CF API version 3\\.36\\.0 or higher\\.")) 115 Eventually(session).Should(Exit(1)) 116 }) 117 }) 118 }) 119 120 Context("when the environment is set up correctly", func() { 121 var ( 122 domain string 123 service string 124 servicePlan string 125 ) 126 127 BeforeEach(func() { 128 service = helpers.PrefixedRandomName("SERVICE") 129 servicePlan = helpers.PrefixedRandomName("SERVICE-PLAN") 130 131 helpers.CreateOrgAndSpace(sharedToOrgName, sharedToSpaceName) 132 helpers.SetupCF(sourceOrgName, sourceSpaceName) 133 134 domain = helpers.DefaultSharedDomain() 135 }) 136 137 AfterEach(func() { 138 helpers.QuickDeleteOrg(sharedToOrgName) 139 helpers.QuickDeleteOrg(sourceOrgName) 140 }) 141 142 Context("when there is a managed service instance in my current targeted space", func() { 143 var broker helpers.ServiceBroker 144 145 BeforeEach(func() { 146 broker = helpers.NewServiceBroker(helpers.NewServiceBrokerName(), helpers.NewAssets().ServiceBroker, domain, service, servicePlan) 147 broker.Push() 148 broker.Configure(true) 149 broker.Create() 150 151 Eventually(helpers.CF("enable-service-access", service)).Should(Exit(0)) 152 Eventually(helpers.CF("create-service", service, servicePlan, serviceInstance)).Should(Exit(0)) 153 }) 154 155 AfterEach(func() { 156 broker.Destroy() 157 }) 158 159 Context("when I want to share my service instance to a space in another org", func() { 160 AfterEach(func() { 161 Eventually(helpers.CF("unshare-service", serviceInstance, "-s", sharedToSpaceName, "-o", sharedToOrgName, "-f")).Should(Exit(0)) 162 }) 163 164 It("shares the service instance from my targeted space with the share-to org/space", func() { 165 username, _ := helpers.GetCredentials() 166 session := helpers.CF("share-service", serviceInstance, "-s", sharedToSpaceName, "-o", sharedToOrgName) 167 Eventually(session.Out).Should(Say("Sharing service instance %s into org %s / space %s as %s\\.\\.\\.", serviceInstance, sharedToOrgName, sharedToSpaceName, username)) 168 Eventually(session.Out).Should(Say("OK")) 169 Eventually(session).Should(Exit(0)) 170 }) 171 172 Context("when the service instance is already shared with that space", func() { 173 BeforeEach(func() { 174 Eventually(helpers.CF("share-service", serviceInstance, "-s", sharedToSpaceName, "-o", sharedToOrgName)).Should(Exit(0)) 175 }) 176 177 It("displays a warning and exits 0", func() { 178 session := helpers.CF("share-service", serviceInstance, "-s", sharedToSpaceName, "-o", sharedToOrgName) 179 Consistently(session.Out).ShouldNot(Say("FAILED")) 180 Eventually(session.Out).Should(Say("Service instance %s is already shared with that space\\.", serviceInstance)) 181 Eventually(session.Out).Should(Say("OK")) 182 Eventually(session).Should(Exit(0)) 183 }) 184 }) 185 }) 186 187 Context("when I want to share my service instance into another space in my targeted org", func() { 188 BeforeEach(func() { 189 helpers.CreateSpace(sharedToSpaceName) 190 }) 191 192 AfterEach(func() { 193 Eventually(helpers.CF("unshare-service", serviceInstance, "-s", sharedToSpaceName, "-f")).Should(Exit(0)) 194 }) 195 196 It("shares the service instance from my targeted space with the share-to space", func() { 197 username, _ := helpers.GetCredentials() 198 session := helpers.CF("share-service", serviceInstance, "-s", sharedToSpaceName) 199 Eventually(session.Out).Should(Say("Sharing service instance %s into org %s / space %s as %s\\.\\.\\.", serviceInstance, sourceOrgName, sharedToSpaceName, username)) 200 Eventually(session.Out).Should(Say("OK")) 201 Eventually(session).Should(Exit(0)) 202 }) 203 204 Context("when the service instance is already shared with that space", func() { 205 BeforeEach(func() { 206 Eventually(helpers.CF("share-service", serviceInstance, "-s", sharedToSpaceName)).Should(Exit(0)) 207 }) 208 209 It("displays a warning and exits 0", func() { 210 session := helpers.CF("share-service", serviceInstance, "-s", sharedToSpaceName) 211 Consistently(session.Out).ShouldNot(Say("FAILED")) 212 Eventually(session.Out).Should(Say("Service instance %s is already shared with that space\\.", serviceInstance)) 213 Eventually(session.Out).Should(Say("OK")) 214 Eventually(session).Should(Exit(0)) 215 }) 216 }) 217 }) 218 219 Context("when the org I want to share into does not exist", func() { 220 It("fails with an org not found error", func() { 221 session := helpers.CF("share-service", serviceInstance, "-s", sharedToSpaceName, "-o", "missing-org") 222 Eventually(session).Should(Say("FAILED")) 223 Eventually(session.Err).Should(Say("Organization 'missing-org' not found")) 224 Eventually(session).Should(Exit(1)) 225 }) 226 }) 227 228 Context("when the space I want to share into does not exist", func() { 229 It("fails with a space not found error", func() { 230 session := helpers.CF("share-service", serviceInstance, "-s", "missing-space") 231 Eventually(session).Should(Say("FAILED")) 232 Eventually(session.Err).Should(Say("Space 'missing-space' not found")) 233 Eventually(session).Should(Exit(1)) 234 }) 235 }) 236 237 Context("when I am a SpaceAuditor in the space I want to share into", func() { 238 var sharedToSpaceGUID string 239 BeforeEach(func() { 240 user := helpers.NewUsername() 241 password := helpers.NewPassword() 242 Eventually(helpers.CF("create-user", user, password)).Should(Exit(0)) 243 Eventually(helpers.CF("set-space-role", user, sourceOrgName, sourceSpaceName, "SpaceDeveloper")).Should(Exit(0)) 244 Eventually(helpers.CF("set-space-role", user, sharedToOrgName, sharedToSpaceName, "SpaceAuditor")).Should(Exit(0)) 245 env := map[string]string{ 246 "CF_USERNAME": user, 247 "CF_PASSWORD": password, 248 } 249 Eventually(helpers.CFWithEnv(env, "auth")).Should(Exit(0)) 250 helpers.TargetOrgAndSpace(sharedToOrgName, sharedToSpaceName) 251 sharedToSpaceGUID = helpers.GetSpaceGUID(sharedToSpaceName) 252 helpers.TargetOrgAndSpace(sourceOrgName, sourceSpaceName) 253 }) 254 255 AfterEach(func() { 256 helpers.SetupCF(sourceOrgName, sourceSpaceName) 257 }) 258 259 It("fails with an unauthorized error", func() { 260 session := helpers.CF("share-service", serviceInstance, "-s", sharedToSpaceName, "-o", sharedToOrgName) 261 Eventually(session).Should(Say("FAILED")) 262 Eventually(session.Err).Should(Say("Unable to share service instance %s with spaces \\['%s'\\].", serviceInstance, sharedToSpaceGUID)) 263 Eventually(session.Err).Should(Say("Write permission is required in order to share a service instance with a space")) 264 Eventually(session).Should(Exit(1)) 265 }) 266 }) 267 268 Context("when my targeted space is the same as my share-to space", func() { 269 It("fails with a cannot share to self error", func() { 270 session := helpers.CF("share-service", serviceInstance, "-s", sourceSpaceName) 271 Eventually(session).Should(Say("FAILED")) 272 Eventually(session.Err).Should(Say("Service instances cannot be shared into the space where they were created")) 273 Eventually(session).Should(Exit(1)) 274 }) 275 }) 276 277 Context("when a service instance with the same name exists in the shared-to space", func() { 278 BeforeEach(func() { 279 helpers.CreateSpace(sharedToSpaceName) 280 helpers.TargetOrgAndSpace(sourceOrgName, sharedToSpaceName) 281 Eventually(helpers.CF("create-service", service, servicePlan, serviceInstance)).Should(Exit(0)) 282 helpers.TargetOrgAndSpace(sourceOrgName, sourceSpaceName) 283 }) 284 285 It("fails with a name clash error", func() { 286 session := helpers.CF("share-service", serviceInstance, "-s", sharedToSpaceName) 287 Eventually(session).Should(Say("FAILED")) 288 Eventually(session.Err).Should(Say(fmt.Sprintf("A service instance called %s already exists in %s", serviceInstance, sharedToSpaceName))) 289 Eventually(session).Should(Exit(1)) 290 }) 291 }) 292 293 Context("when the service instance is NOT shareable", func() { 294 Context("due to global settings", func() { 295 BeforeEach(func() { 296 helpers.DisableFeatureFlag("service_instance_sharing") 297 }) 298 299 AfterEach(func() { 300 helpers.EnableFeatureFlag("service_instance_sharing") 301 }) 302 303 It("should display that the service instance feature flag is disabled and exit 1", func() { 304 session := helpers.CF("share-service", serviceInstance, "-s", sharedToSpaceName, "-o", sharedToOrgName) 305 Eventually(session.Err).Should(Say(`The "service_instance_sharing" feature flag is disabled for this Cloud Foundry platform.`)) 306 Eventually(session).Should(Exit(1)) 307 }) 308 }) 309 310 Context("due to service broker settings", func() { 311 BeforeEach(func() { 312 broker.Configure(false) 313 broker.Update() 314 }) 315 316 It("should display that service instance sharing is disabled for this service and exit 1", func() { 317 session := helpers.CF("share-service", serviceInstance, "-s", sharedToSpaceName, "-o", sharedToOrgName) 318 Eventually(session.Err).Should(Say("Service instance sharing is disabled for this service.")) 319 Eventually(session).Should(Exit(1)) 320 }) 321 }) 322 323 Context("due to global settings AND service broker settings", func() { 324 BeforeEach(func() { 325 helpers.DisableFeatureFlag("service_instance_sharing") 326 broker.Configure(false) 327 broker.Update() 328 }) 329 330 AfterEach(func() { 331 helpers.EnableFeatureFlag("service_instance_sharing") 332 }) 333 334 It("should display that service instance sharing is disabled for this service and exit 1", func() { 335 session := helpers.CF("share-service", serviceInstance, "-s", sharedToSpaceName, "-o", sharedToOrgName) 336 Eventually(session.Err).Should(Say(`The "service_instance_sharing" feature flag is disabled for this Cloud Foundry platform. Also, service instance sharing is disabled for this service.`)) 337 Eventually(session).Should(Exit(1)) 338 }) 339 }) 340 }) 341 }) 342 343 Context("when the service instance does not exist", func() { 344 It("fails with a service instance not found error", func() { 345 session := helpers.CF("share-service", serviceInstance, "-s", sharedToSpaceName) 346 Eventually(session).Should(Say("FAILED")) 347 Eventually(session.Err).Should(Say("Specified instance not found or not a managed service instance. Sharing is not supported for user provided services.")) 348 Eventually(session).Should(Exit(1)) 349 }) 350 }) 351 352 Context("when I try to share a user-provided-service", func() { 353 BeforeEach(func() { 354 helpers.CF("create-user-provided-service", serviceInstance, "-p", `{"username":"admin","password":"pa55woRD"}`) 355 }) 356 357 It("fails with only managed services can be shared", func() { 358 session := helpers.CF("share-service", serviceInstance, "-s", sharedToSpaceName, "-o", sharedToOrgName) 359 Eventually(session).Should(Say("FAILED")) 360 Eventually(session.Err).Should(Say("User-provided services cannot be shared")) 361 Eventually(session).Should(Exit(1)) 362 }) 363 }) 364 }) 365 })