github.com/DaAlbrecht/cf-cli@v0.0.0-20231128151943-1fe19bb400b9/integration/v7/isolated/create_service_key_command_test.go (about)

     1  package isolated
     2  
     3  import (
     4  	"os"
     5  	"time"
     6  
     7  	"code.cloudfoundry.org/cli/integration/helpers"
     8  	"code.cloudfoundry.org/cli/integration/helpers/servicebrokerstub"
     9  	"code.cloudfoundry.org/cli/resources"
    10  	. "github.com/onsi/ginkgo"
    11  	. "github.com/onsi/gomega"
    12  	. "github.com/onsi/gomega/gbytes"
    13  	. "github.com/onsi/gomega/gexec"
    14  )
    15  
    16  var _ = Describe("create-service-key command", func() {
    17  	Describe("help", func() {
    18  		matchHelpMessage := SatisfyAll(
    19  			Say(`NAME:\n`),
    20  			Say(`\s+create-service-key - Create key for a service instance\n`),
    21  			Say(`\n`),
    22  			Say(`USAGE:\n`),
    23  			Say(`\s+cf create-service-key SERVICE_INSTANCE SERVICE_KEY \[-c PARAMETERS_AS_JSON\] \[--wait\]\n`),
    24  			Say(`\s+Optionally provide service-specific configuration parameters in a valid JSON object in-line.\n`),
    25  			Say(`\s+cf create-service-key SERVICE_INSTANCE SERVICE_KEY -c '{\"name\":\"value\",\"name\":\"value\"}'\n`),
    26  			Say(`\s+Optionally provide a file containing service-specific configuration parameters in a valid JSON object. The path to the parameters file can be an absolute or relative path to a file.\n`),
    27  			Say(`\s+cf create-service-key SERVICE_INSTANCE SERVICE_KEY -c PATH_TO_FILE\n`),
    28  			Say(`\s+Example of valid JSON object:\n`),
    29  			Say(`\s+{\n`),
    30  			Say(`\s+\"permissions\": \"read-only\"\n`),
    31  			Say(`\s+}\n`),
    32  			Say(`\n`),
    33  			Say(`EXAMPLES:\n`),
    34  			Say(`\s+cf create-service-key mydb mykey -c '{\"permissions\":\"read-only\"}'\n`),
    35  			Say(`\s+cf create-service-key mydb mykey -c ~/workspace/tmp/instance_config.json\n`),
    36  			Say(`ALIAS:\n`),
    37  			Say(`\s+csk\n`),
    38  			Say(`\n`),
    39  			Say(`OPTIONS:\n`),
    40  			Say(`\s+-c\s+Valid JSON object containing service-specific configuration parameters, provided either in-line or in a file. For a list of supported configuration parameters, see documentation for the particular service offering.\n`),
    41  			Say(`\s+--wait, -w\s+Wait for the operation to complete\n`),
    42  			Say(`\n`),
    43  			Say(`SEE ALSO:\n`),
    44  			Say(`\s+service-key\n`),
    45  		)
    46  
    47  		When("--help flag is set", func() {
    48  			It("displays command usage to output", func() {
    49  				session := helpers.CF("create-service-key", "--help")
    50  				Eventually(session).Should(Exit(0))
    51  				Expect(string(session.Err.Contents())).To(HaveLen(0))
    52  				Expect(session.Out).To(matchHelpMessage)
    53  			})
    54  		})
    55  
    56  		When("there are no arguments", func() {
    57  			It("fails with a help message", func() {
    58  				session := helpers.CF("create-service-key")
    59  				Eventually(session).Should(Exit(1))
    60  				Expect(session.Err).To(Say("Incorrect Usage: the required arguments `SERVICE_INSTANCE` and `SERVICE_KEY` were not provided"))
    61  				Expect(session.Out).To(matchHelpMessage)
    62  			})
    63  		})
    64  		When("there are insufficient arguments", func() {
    65  			It("fails with a help message", func() {
    66  				session := helpers.CF("create-service-key", "service-instance")
    67  				Eventually(session).Should(Exit(1))
    68  				Expect(session.Err).To(Say("Incorrect Usage: the required argument `SERVICE_KEY` was not provided"))
    69  				Expect(session.Out).To(matchHelpMessage)
    70  			})
    71  		})
    72  
    73  		When("there are superfluous arguments", func() {
    74  			It("fails with a help message", func() {
    75  				session := helpers.CF("create-service-key", "service-instance", "service-key", "superfluous")
    76  				Eventually(session).Should(Exit(1))
    77  				Expect(session.Err).To(Say(`Incorrect Usage: unexpected argument "superfluous"`))
    78  				Expect(session.Out).To(matchHelpMessage)
    79  			})
    80  		})
    81  	})
    82  
    83  	When("the environment is not setup correctly", func() {
    84  		It("fails with the appropriate errors", func() {
    85  			helpers.CheckEnvironmentTargetedCorrectly(true, true, ReadOnlyOrg, "create-service-key", "service-name", "key-name")
    86  		})
    87  	})
    88  
    89  	When("the environment is setup correctly", func() {
    90  		var (
    91  			org                 string
    92  			space               string
    93  			username            string
    94  			serviceInstanceName string
    95  			serviceKeyName      string
    96  		)
    97  
    98  		BeforeEach(func() {
    99  			org = helpers.NewOrgName()
   100  			space = helpers.NewSpaceName()
   101  			username, _ = helpers.GetCredentials()
   102  
   103  			helpers.SetupCF(org, space)
   104  
   105  			serviceInstanceName = helpers.NewServiceInstanceName()
   106  			serviceKeyName = helpers.PrefixedRandomName("KEY")
   107  		})
   108  
   109  		AfterEach(func() {
   110  			helpers.QuickDeleteOrg(org)
   111  		})
   112  
   113  		When("provided with a service instance name that doesn't exist", func() {
   114  			It("displays FAILED and an informative error, and exits 1", func() {
   115  				session := helpers.CF("create-service-key", serviceInstanceName, serviceKeyName)
   116  				Eventually(session.Out).Should(Say("FAILED"))
   117  				Eventually(session.Err).Should(Say("Service instance '%s' not found", serviceInstanceName))
   118  				Eventually(session).Should(Exit(1))
   119  			})
   120  		})
   121  
   122  		When("user-provided service instance exists", func() {
   123  			BeforeEach(func() {
   124  				Eventually(helpers.CF("cups", serviceInstanceName)).Should(Exit(0))
   125  			})
   126  
   127  			It("fails to create the service key", func() {
   128  				session := helpers.CF("create-service-key", serviceInstanceName, serviceKeyName)
   129  				Eventually(session).Should(Exit(1))
   130  
   131  				Expect(session.Out).To(Say(`FAILED\n`))
   132  				Expect(session.Err).To(Say(`Service credential bindings of type 'key' are not supported for user-provided service instances.\n`))
   133  			})
   134  		})
   135  
   136  		When("managed service instance exists", func() {
   137  			var broker *servicebrokerstub.ServiceBrokerStub
   138  
   139  			BeforeEach(func() {
   140  				broker = servicebrokerstub.EnableServiceAccess()
   141  				helpers.CreateManagedServiceInstance(broker.FirstServiceOfferingName(), broker.FirstServicePlanName(), serviceInstanceName)
   142  			})
   143  
   144  			AfterEach(func() {
   145  				broker.Forget()
   146  			})
   147  
   148  			It("creates the service key and displays OK", func() {
   149  				session := helpers.CF("create-service-key", serviceInstanceName, serviceKeyName)
   150  				Eventually(session).Should(Exit(0))
   151  				Expect(session.Out).To(SatisfyAll(
   152  					Say(`Creating service key %s for service instance %s as %s\.\.\.\n`, serviceKeyName, serviceInstanceName, username),
   153  					Say(`OK\n`),
   154  				))
   155  				Expect(string(session.Err.Contents())).To(HaveLen(0))
   156  			})
   157  
   158  			When("a service key with the provided name already exists", func() {
   159  				BeforeEach(func() {
   160  					Eventually(helpers.CF("create-service-key", serviceInstanceName, serviceKeyName)).Should(Exit(0))
   161  				})
   162  
   163  				It("displays OK and an informative error message", func() {
   164  					session := helpers.CF("create-service-key", serviceInstanceName, serviceKeyName)
   165  					Eventually(session).Should(Exit(0))
   166  
   167  					Expect(session.Out).To(SatisfyAll(
   168  						Say(`\n`),
   169  						Say(`Service key %s already exists\n`, serviceKeyName),
   170  						Say(`OK\n`),
   171  					))
   172  					Expect(string(session.Err.Contents())).To(HaveLen(0))
   173  				})
   174  			})
   175  
   176  			When("the service is not bindable", func() {
   177  				BeforeEach(func() {
   178  					broker.Services[0].Bindable = false
   179  					broker.Configure().Register()
   180  				})
   181  
   182  				It("displays FAILED and an informative error, and exits 1", func() {
   183  					session := helpers.CF("create-service-key", serviceInstanceName, serviceKeyName)
   184  					Eventually(session).Should(Exit(1))
   185  					Expect(session.Out).To(Say(`FAILED\n`))
   186  					Expect(session.Err).To(Say(`Service plan does not allow bindings\.\n`))
   187  				})
   188  			})
   189  
   190  			Describe("parameters", func() {
   191  				checkParameters := func(params map[string]interface{}) {
   192  					var receiver struct {
   193  						Resources []resources.ServiceCredentialBinding `json:"resources"`
   194  					}
   195  					helpers.Curl(&receiver, "/v3/service_credential_bindings?service_instance_names=%s", serviceInstanceName)
   196  					Expect(receiver.Resources).To(HaveLen(1))
   197  
   198  					var parametersReceiver map[string]interface{}
   199  					helpers.Curl(&parametersReceiver, `/v3/service_credential_bindings/%s/parameters`, receiver.Resources[0].GUID)
   200  					Expect(parametersReceiver).To(Equal(params))
   201  				}
   202  
   203  				When("provided valid configuration parameters", func() {
   204  					It("sends the parameters to the service broker", func() {
   205  						session := helpers.CF("create-service-key", serviceInstanceName, serviceKeyName, "-c", `{"wheres":"waldo"}`)
   206  						Eventually(session).Should(Exit(0))
   207  
   208  						checkParameters(map[string]interface{}{"wheres": "waldo"})
   209  					})
   210  				})
   211  
   212  				When("provided invalid configuration parameters", func() {
   213  					It("displays an invalid configuration error", func() {
   214  						session := helpers.CF("create-service-key", serviceInstanceName, serviceKeyName, "-c", `{"bad json"}`)
   215  						Eventually(session).Should(Exit(1))
   216  						Expect(session.Err).To(Say("Invalid configuration provided for -c flag. Please provide a valid JSON object or path to a file containing a valid JSON object."))
   217  					})
   218  				})
   219  
   220  				When("configuration parameters are provided in a file", func() {
   221  					When("the file contains valid JSON", func() {
   222  						const parametersJSON = `{"valid":"json"}`
   223  						var tempFilePath string
   224  
   225  						BeforeEach(func() {
   226  							tempFilePath = helpers.TempFileWithContent(parametersJSON)
   227  						})
   228  
   229  						AfterEach(func() {
   230  							Expect(os.Remove(tempFilePath)).To(Succeed())
   231  						})
   232  
   233  						It("sends the parameters to the service broker", func() {
   234  							session := helpers.CF("create-service-key", serviceInstanceName, serviceKeyName, "-c", tempFilePath)
   235  							Eventually(session).Should(Exit(0))
   236  
   237  							checkParameters(map[string]interface{}{"valid": "json"})
   238  						})
   239  					})
   240  
   241  					When("the file-path does not exist", func() {
   242  						It("displays an invalid configuration error, and exits 1", func() {
   243  							session := helpers.CF("create-service-key", serviceInstanceName, serviceKeyName, "-c", `/this/is/not/valid`)
   244  							Eventually(session).Should(Exit(1))
   245  							Expect(session.Err).To(Say("Invalid configuration provided for -c flag. Please provide a valid JSON object or path to a file containing a valid JSON object."))
   246  						})
   247  					})
   248  
   249  					When("the file contains invalid json", func() {
   250  						var tempFilePath string
   251  
   252  						BeforeEach(func() {
   253  							tempFilePath = helpers.TempFileWithContent("{i-am-very-bad-json")
   254  						})
   255  
   256  						AfterEach(func() {
   257  							Expect(os.Remove(tempFilePath)).To(Succeed())
   258  						})
   259  
   260  						It("displays an invalid configuration error, and exits 1", func() {
   261  							session := helpers.CF("create-service-key", serviceInstanceName, serviceKeyName, "-c", tempFilePath)
   262  							Eventually(session).Should(Exit(1))
   263  							Expect(session.Err).To(Say("Invalid configuration provided for -c flag. Please provide a valid JSON object or path to a file containing a valid JSON object."))
   264  						})
   265  					})
   266  				})
   267  			})
   268  
   269  			Describe("asynchronous broker response", func() {
   270  				BeforeEach(func() {
   271  					broker.WithAsyncDelay(time.Second).Configure()
   272  				})
   273  
   274  				It("starts to create the service key", func() {
   275  					session := helpers.CF("create-service-key", serviceInstanceName, serviceKeyName)
   276  					Eventually(session).Should(Exit(0))
   277  					Expect(session.Out).To(SatisfyAll(
   278  						Say(`Creating service key %s for service instance %s as %s\.\.\.\n`, serviceKeyName, serviceInstanceName, username),
   279  						Say(`OK\n`),
   280  						Say(`Create in progress\.\n`),
   281  					))
   282  
   283  					Expect(string(session.Err.Contents())).To(BeEmpty())
   284  				})
   285  
   286  				When("--wait flag specified", func() {
   287  					It("waits for completion", func() {
   288  						session := helpers.CF("create-service-key", serviceInstanceName, serviceKeyName, "--wait")
   289  						Eventually(session).Should(Exit(0))
   290  						Expect(session.Out).To(SatisfyAll(
   291  							Say(`Creating service key %s for service instance %s as %s\.\.\.\n`, serviceKeyName, serviceInstanceName, username),
   292  							Say(`Waiting for the operation to complete\.+\n`),
   293  							Say(`\n`),
   294  							Say(`OK\n`),
   295  						))
   296  
   297  						Expect(string(session.Err.Contents())).To(BeEmpty())
   298  					})
   299  				})
   300  			})
   301  		})
   302  	})
   303  })