github.com/xgoffin/jenkins-library@v1.154.0/cmd/integrationArtifactGetServiceEndpoint.go (about)

     1  package cmd
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"net/http"
     7  	"strings"
     8  
     9  	"github.com/Jeffail/gabs/v2"
    10  	"github.com/SAP/jenkins-library/pkg/command"
    11  	"github.com/SAP/jenkins-library/pkg/cpi"
    12  	piperhttp "github.com/SAP/jenkins-library/pkg/http"
    13  	"github.com/SAP/jenkins-library/pkg/log"
    14  	"github.com/SAP/jenkins-library/pkg/telemetry"
    15  	"github.com/pkg/errors"
    16  )
    17  
    18  type integrationArtifactGetServiceEndpointUtils interface {
    19  	command.ExecRunner
    20  
    21  	// Add more methods here, or embed additional interfaces, or remove/replace as required.
    22  	// The integrationArtifactGetServiceEndpointUtils interface should be descriptive of your runtime dependencies,
    23  	// i.e. include everything you need to be able to mock in tests.
    24  	// Unit tests shall be executable in parallel (not depend on global state), and don't (re-)test dependencies.
    25  }
    26  
    27  type integrationArtifactGetServiceEndpointUtilsBundle struct {
    28  	*command.Command
    29  
    30  	// Embed more structs as necessary to implement methods or interfaces you add to integrationArtifactGetServiceEndpointUtils.
    31  	// Structs embedded in this way must each have a unique set of methods attached.
    32  	// If there is no struct which implements the method you need, attach the method to
    33  	// integrationArtifactGetServiceEndpointUtilsBundle and forward to the implementation of the dependency.
    34  }
    35  
    36  func newIntegrationArtifactGetServiceEndpointUtils() integrationArtifactGetServiceEndpointUtils {
    37  	utils := integrationArtifactGetServiceEndpointUtilsBundle{
    38  		Command: &command.Command{},
    39  	}
    40  	// Reroute command output to logging framework
    41  	utils.Stdout(log.Writer())
    42  	utils.Stderr(log.Writer())
    43  	return &utils
    44  }
    45  
    46  func integrationArtifactGetServiceEndpoint(config integrationArtifactGetServiceEndpointOptions, telemetryData *telemetry.CustomData, commonPipelineEnvironment *integrationArtifactGetServiceEndpointCommonPipelineEnvironment) {
    47  	// Utils can be used wherever the command.ExecRunner interface is expected.
    48  	// It can also be used for example as a mavenExecRunner.
    49  	httpClient := &piperhttp.Client{}
    50  
    51  	// For HTTP calls import  piperhttp "github.com/SAP/jenkins-library/pkg/http"
    52  	// and use a  &piperhttp.Client{} in a custom system
    53  	// Example: step checkmarxExecuteScan.go
    54  
    55  	// Error situations should be bubbled up until they reach the line below which will then stop execution
    56  	// through the log.Entry().Fatal() call leading to an os.Exit(1) in the end.
    57  	err := runIntegrationArtifactGetServiceEndpoint(&config, telemetryData, httpClient, commonPipelineEnvironment)
    58  	if err != nil {
    59  		log.Entry().WithError(err).Fatal("step execution failed")
    60  	}
    61  }
    62  
    63  func runIntegrationArtifactGetServiceEndpoint(config *integrationArtifactGetServiceEndpointOptions, telemetryData *telemetry.CustomData, httpClient piperhttp.Sender, commonPipelineEnvironment *integrationArtifactGetServiceEndpointCommonPipelineEnvironment) error {
    64  	clientOptions := piperhttp.ClientOptions{}
    65  	header := make(http.Header)
    66  	header.Add("Accept", "application/json")
    67  	serviceKey, err := cpi.ReadCpiServiceKey(config.APIServiceKey)
    68  	if err != nil {
    69  		return err
    70  	}
    71  	servieEndpointURL := fmt.Sprintf("%s/api/v1/ServiceEndpoints?$expand=EntryPoints", serviceKey.OAuth.Host)
    72  	tokenParameters := cpi.TokenParameters{TokenURL: serviceKey.OAuth.OAuthTokenProviderURL, Username: serviceKey.OAuth.ClientID, Password: serviceKey.OAuth.ClientSecret, Client: httpClient}
    73  	token, err := cpi.CommonUtils.GetBearerToken(tokenParameters)
    74  	if err != nil {
    75  		return errors.Wrap(err, "failed to fetch Bearer Token")
    76  	}
    77  	clientOptions.Token = fmt.Sprintf("Bearer %s", token)
    78  	httpClient.SetOptions(clientOptions)
    79  	httpMethod := "GET"
    80  	serviceEndpointResp, httpErr := httpClient.SendRequest(httpMethod, servieEndpointURL, nil, header, nil)
    81  
    82  	if httpErr != nil {
    83  		return errors.Wrapf(httpErr, "HTTP %v request to %v failed with error", httpMethod, servieEndpointURL)
    84  	}
    85  
    86  	if serviceEndpointResp != nil && serviceEndpointResp.Body != nil {
    87  		defer serviceEndpointResp.Body.Close()
    88  	}
    89  
    90  	if serviceEndpointResp == nil {
    91  		return errors.Errorf("did not retrieve a HTTP response: %v", httpErr)
    92  	}
    93  
    94  	if serviceEndpointResp.StatusCode == 200 {
    95  		bodyText, readErr := ioutil.ReadAll(serviceEndpointResp.Body)
    96  		if readErr != nil {
    97  			return errors.Wrap(readErr, "HTTP response body could not be read")
    98  		}
    99  		jsonResponse, parsingErr := gabs.ParseJSON([]byte(bodyText))
   100  		if parsingErr != nil {
   101  			return errors.Wrapf(parsingErr, "HTTP response body could not be parsed as JSON: %v", string(bodyText))
   102  		}
   103  
   104  		for _, child := range jsonResponse.S("d", "results").Children() {
   105  			iflowID := strings.ReplaceAll(child.Path("Name").String(), "\"", "")
   106  			if iflowID == config.IntegrationFlowID {
   107  				entryPoints := child.S("EntryPoints")
   108  				finalEndpoint := entryPoints.Path("results.0.Url").Data().(string)
   109  				commonPipelineEnvironment.custom.integrationFlowServiceEndpoint = finalEndpoint
   110  				return nil
   111  			}
   112  		}
   113  	}
   114  	responseBody, readErr := ioutil.ReadAll(serviceEndpointResp.Body)
   115  
   116  	if readErr != nil {
   117  		return errors.Wrapf(readErr, "HTTP response body could not be read, Response status code: %v", serviceEndpointResp.StatusCode)
   118  	}
   119  
   120  	log.Entry().Errorf("a HTTP error occurred!  Response body: %v, Response status code: %v", string(responseBody), serviceEndpointResp.StatusCode)
   121  	return errors.Errorf("Unable to get integration flow service endpoint, Response Status code: %v", serviceEndpointResp.StatusCode)
   122  }