You've already forked sap-jenkins-library
							
							
				mirror of
				https://github.com/SAP/jenkins-library.git
				synced 2025-10-30 23:57:50 +02:00 
			
		
		
		
	Add ServiceKey deletion to cloudFoundryDeleteService step (#1177)
This commit is contained in:
		| @@ -1,12 +1,16 @@ | ||||
| package cmd | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/command" | ||||
| 	"github.com/SAP/jenkins-library/pkg/log" | ||||
| 	"github.com/SAP/jenkins-library/pkg/telemetry" | ||||
| ) | ||||
|  | ||||
| func cloudFoundryDeleteService(CloudFoundryDeleteServiceOptions cloudFoundryDeleteServiceOptions, telemetryData *telemetry.CustomData) error { | ||||
| func cloudFoundryDeleteService(options cloudFoundryDeleteServiceOptions, telemetryData *telemetry.CustomData) { | ||||
|  | ||||
| 	c := command.Command{} | ||||
|  | ||||
| @@ -14,35 +18,92 @@ func cloudFoundryDeleteService(CloudFoundryDeleteServiceOptions cloudFoundryDele | ||||
| 	c.Stdout(log.Entry().Writer()) | ||||
| 	c.Stderr(log.Entry().Writer()) | ||||
|  | ||||
| 	cloudFoundryLogin(CloudFoundryDeleteServiceOptions, &c) | ||||
| 	var err error | ||||
|  | ||||
| 	err := cloudFoundryDeleteServiceFunction(CloudFoundryDeleteServiceOptions.CfServiceInstance, &c) | ||||
| 	if err != nil { | ||||
| 		cloudFoundryLogout(&c) | ||||
| 		log.Entry(). | ||||
| 			WithError(err). | ||||
| 			Fatal("Failed to delete Service!") | ||||
| 		return err | ||||
| 	err = cloudFoundryLogin(options, &c) | ||||
|  | ||||
| 	if err == nil && options.CfDeleteServiceKeys == true { | ||||
| 		err = cloudFoundryDeleteServiceKeys(options, &c) | ||||
| 	} | ||||
|  | ||||
| 	cloudFoundryLogout(&c) | ||||
| 	if err == nil { | ||||
| 		err = cloudFoundryDeleteServiceFunction(options.CfServiceInstance, &c) | ||||
| 	} | ||||
|  | ||||
| 	var logoutErr error | ||||
|  | ||||
| 	if err == nil { | ||||
| 		logoutErr = cloudFoundryLogout(&c) | ||||
| 		if logoutErr != nil { | ||||
| 			log.Entry(). | ||||
| 				WithError(logoutErr). | ||||
| 				Fatal("Error while logging out occured.") | ||||
| 		} | ||||
| 	} else if err != nil { | ||||
| 		logoutErr = cloudFoundryLogout(&c) | ||||
| 		if logoutErr != nil { | ||||
| 			log.Entry(). | ||||
| 				WithError(logoutErr). | ||||
| 				Fatal("Error while logging out occured.") | ||||
| 		} | ||||
| 		log.Entry(). | ||||
| 			WithError(err). | ||||
| 			Fatal("Error occured.") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func cloudFoundryDeleteServiceKeys(options cloudFoundryDeleteServiceOptions, c execRunner) error { | ||||
|  | ||||
| 	log.Entry().Info("Deleting inherent Service Keys") | ||||
|  | ||||
| 	var cfFindServiceKeysScript = []string{"service-keys", options.CfServiceInstance} | ||||
|  | ||||
| 	var serviceKeyBytes bytes.Buffer | ||||
| 	c.Stdout(&serviceKeyBytes) | ||||
|  | ||||
| 	err := c.RunExecutable("cf", cfFindServiceKeysScript...) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("Failed to Delete Service Key, most likely your service doesn't exist: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	if len(serviceKeyBytes.String()) == 0 { | ||||
| 		log.Entry().Info("No service key could be retrieved for your requested Service") | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	var lines []string = strings.Split(serviceKeyBytes.String(), "\n") | ||||
| 	if len(lines) <= 4 { | ||||
| 		log.Entry().Info("No Service Keys active to be deleted") | ||||
| 		return nil | ||||
| 	} | ||||
| 	var numberOfLines = len(lines) | ||||
| 	log.Entry().WithField("Number of service keys :", numberOfLines-4).Info("ServiceKey") | ||||
| 	//Deleting all matched Service Keys for Service | ||||
| 	for i := 3; i <= numberOfLines-2; i++ { | ||||
| 		log.Entry().WithField("Deleting Service Key", lines[i]).Info("ServiceKeyDeletion") | ||||
| 		var cfDeleteServiceKeyScript = []string{"delete-service-key", options.CfServiceInstance, lines[i], "-f"} | ||||
| 		err := c.RunExecutable("cf", cfDeleteServiceKeyScript...) | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("Failed to Delete Service Key: %w", err) | ||||
| 		} | ||||
| 	} | ||||
| 	log.Entry().Info("ServiceKeys have been deleted!") | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func cloudFoundryLogin(CloudFoundryDeleteServiceOptions cloudFoundryDeleteServiceOptions, c execRunner) error { | ||||
| 	var cfLoginScript = []string{"login", "-a", CloudFoundryDeleteServiceOptions.CfAPIEndpoint, "-o", CloudFoundryDeleteServiceOptions.CfOrg, "-s", CloudFoundryDeleteServiceOptions.CfSpace, "-u", CloudFoundryDeleteServiceOptions.Username, "-p", CloudFoundryDeleteServiceOptions.Password} | ||||
| func cloudFoundryLogin(options cloudFoundryDeleteServiceOptions, c execRunner) error { | ||||
| 	var cfLoginScript = []string{"login", "-a", options.CfAPIEndpoint, "-o", options.CfOrg, "-s", options.CfSpace, "-u", options.Username, "-p", options.Password} | ||||
|  | ||||
| 	log.Entry().WithField("cfAPI:", CloudFoundryDeleteServiceOptions.CfAPIEndpoint).WithField("cfOrg", CloudFoundryDeleteServiceOptions.CfOrg).WithField("space", CloudFoundryDeleteServiceOptions.CfSpace).WithField("password", CloudFoundryDeleteServiceOptions.Password).Info("Logging into Cloud Foundry..") | ||||
| 	log.Entry().WithField("cfAPI:", options.CfAPIEndpoint).WithField("cfOrg", options.CfOrg).WithField("space", options.CfSpace).Info("Logging into Cloud Foundry..") | ||||
|  | ||||
| 	err := c.RunExecutable("cf", cfLoginScript...) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		log.Entry(). | ||||
| 			WithError(err). | ||||
| 			Fatal("Failed to login to Cloud Foundry") | ||||
| 		return fmt.Errorf("Failed to login to Cloud Foundry: %w", err) | ||||
| 	} | ||||
| 	log.Entry().Info("Logged in successfully to Cloud Foundry..") | ||||
| 	return err | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func cloudFoundryDeleteServiceFunction(service string, c execRunner) error { | ||||
| @@ -51,11 +112,12 @@ func cloudFoundryDeleteServiceFunction(service string, c execRunner) error { | ||||
| 	log.Entry().WithField("cfService", service).Info("Deleting the requested Service") | ||||
|  | ||||
| 	err := c.RunExecutable("cf", cfdeleteServiceScript...) | ||||
|  | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 		return fmt.Errorf("Failed to delete Service: %w", err) | ||||
| 	} | ||||
| 	log.Entry().Info("Deletion of Service is finished or the Service has never existed") | ||||
| 	return err | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func cloudFoundryLogout(c execRunner) error { | ||||
| @@ -65,10 +127,8 @@ func cloudFoundryLogout(c execRunner) error { | ||||
|  | ||||
| 	err := c.RunExecutable("cf", cfLogoutScript) | ||||
| 	if err != nil { | ||||
| 		log.Entry(). | ||||
| 			WithError(err). | ||||
| 			Fatal("Failed to Logout of Cloud Foudnry") | ||||
| 		return fmt.Errorf("Failed to Logout of Cloud Foundry: %w", err) | ||||
| 	} | ||||
| 	log.Entry().Info("Logged out successfully") | ||||
| 	return err | ||||
| 	return nil | ||||
| } | ||||
|   | ||||
| @@ -14,12 +14,13 @@ import ( | ||||
| ) | ||||
|  | ||||
| type cloudFoundryDeleteServiceOptions struct { | ||||
| 	CfAPIEndpoint     string `json:"cfApiEndpoint,omitempty"` | ||||
| 	Username          string `json:"username,omitempty"` | ||||
| 	Password          string `json:"password,omitempty"` | ||||
| 	CfOrg             string `json:"cfOrg,omitempty"` | ||||
| 	CfSpace           string `json:"cfSpace,omitempty"` | ||||
| 	CfServiceInstance string `json:"cfServiceInstance,omitempty"` | ||||
| 	CfAPIEndpoint       string `json:"cfApiEndpoint,omitempty"` | ||||
| 	Username            string `json:"username,omitempty"` | ||||
| 	Password            string `json:"password,omitempty"` | ||||
| 	CfOrg               string `json:"cfOrg,omitempty"` | ||||
| 	CfSpace             string `json:"cfSpace,omitempty"` | ||||
| 	CfServiceInstance   string `json:"cfServiceInstance,omitempty"` | ||||
| 	CfDeleteServiceKeys bool   `json:"cfDeleteServiceKeys,omitempty"` | ||||
| } | ||||
|  | ||||
| // CloudFoundryDeleteServiceCommand DeleteCloudFoundryService | ||||
| @@ -64,6 +65,7 @@ func addCloudFoundryDeleteServiceFlags(cmd *cobra.Command, stepConfig *cloudFoun | ||||
| 	cmd.Flags().StringVar(&stepConfig.CfOrg, "cfOrg", os.Getenv("PIPER_cfOrg"), "CF org") | ||||
| 	cmd.Flags().StringVar(&stepConfig.CfSpace, "cfSpace", os.Getenv("PIPER_cfSpace"), "CF Space") | ||||
| 	cmd.Flags().StringVar(&stepConfig.CfServiceInstance, "cfServiceInstance", os.Getenv("PIPER_cfServiceInstance"), "Parameter of ServiceInstance Name to delete CloudFoundry Service") | ||||
| 	cmd.Flags().BoolVar(&stepConfig.CfDeleteServiceKeys, "cfDeleteServiceKeys", false, "Parameter to force deletion of Cloud Foundry Service Keys") | ||||
|  | ||||
| 	cmd.MarkFlagRequired("cfApiEndpoint") | ||||
| 	cmd.MarkFlagRequired("username") | ||||
| @@ -127,6 +129,14 @@ func cloudFoundryDeleteServiceMetadata() config.StepData { | ||||
| 						Mandatory:   true, | ||||
| 						Aliases:     []config.Alias{{Name: "cloudFoundry/serviceInstance"}}, | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "cfDeleteServiceKeys", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"}, | ||||
| 						Type:        "bool", | ||||
| 						Mandatory:   false, | ||||
| 						Aliases:     []config.Alias{{Name: "cloudFoundry/cfDeleteServiceKeys"}}, | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
|   | ||||
| @@ -50,10 +50,19 @@ func TestCloudFoundryDeleteService(t *testing.T) { | ||||
| 			assert.Equal(t, "logout", execRunner.Calls[2].Params[0]) | ||||
| 		} | ||||
| 	}) | ||||
| 	t.Run("CF Delete Service: Error case", func(t *testing.T) { | ||||
| 		ServiceName := "testInstance" | ||||
| 		error := cloudFoundryDeleteServiceFunction(ServiceName, &execRunner) | ||||
| 	t.Run("CF Delete Service Keys: success case", func(t *testing.T) { | ||||
| 		config := cloudFoundryDeleteServiceOptions{ | ||||
| 			CfAPIEndpoint:     "https://api.endpoint.com", | ||||
| 			CfOrg:             "testOrg", | ||||
| 			CfSpace:           "testSpace", | ||||
| 			Username:          "testUser", | ||||
| 			Password:          "testPassword", | ||||
| 			CfServiceInstance: "testInstance", | ||||
| 		} | ||||
| 		error := cloudFoundryDeleteServiceKeys(config, &execRunner) | ||||
| 		if error == nil { | ||||
| 			assert.Equal(t, "cf", execRunner.Calls[3].Exec) | ||||
| 			assert.Equal(t, []string{"service-keys", "testInstance"}, execRunner.Calls[3].Params) | ||||
| 		} | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -5,8 +5,9 @@ | ||||
| ## Prerequisites | ||||
|  | ||||
| This step is for deleting an existing service on Cloud Foundry. | ||||
| You need to provide the Cloud Foundry API Endpoint, the Organisation as well as the Space and the respective Service Instance Name you want to delete.  | ||||
| You need to provide the Cloud Foundry API Endpoint, the Organisation as well as the Space and the respective Service Instance Name you want to delete. | ||||
| Furthermore you will need to provide the Cloud Foundry Login Credentials, which must be stored in the Jenkins Configuration. | ||||
| Additionally you can set the cfDeleteServiceKeys flag for deleting all Service Keys that belong to the respective Service. | ||||
|  | ||||
| ## ${docGenParameters} | ||||
|  | ||||
| @@ -25,5 +26,6 @@ cloudFoundryDeleteService( | ||||
|     cfspace: 'cfspace', | ||||
|     cfserviceInstance: 'cfserviceInstance', | ||||
|     cfCredentialsId: 'cfcredentialsId', | ||||
| )  | ||||
| ``` | ||||
|     cfDeleteServiceKeys: true, | ||||
| ) | ||||
| ``` | ||||
|   | ||||
| @@ -66,6 +66,16 @@ spec: | ||||
|         mandatory: true | ||||
|         aliases: | ||||
|           - name: cloudFoundry/serviceInstance | ||||
|       - name: cfDeleteServiceKeys | ||||
|         type: bool | ||||
|         description: Parameter to force deletion of Cloud Foundry Service Keys | ||||
|         scope: | ||||
|         - PARAMETERS | ||||
|         - STAGES | ||||
|         - STEPS | ||||
|         mandatory: false | ||||
|         aliases: | ||||
|           - name: cloudFoundry/cfDeleteServiceKeys | ||||
|   containers: | ||||
|     - name: cf | ||||
|       image: ppiper/cf-cli | ||||
|   | ||||
		Reference in New Issue
	
	Block a user