github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/pkg/transportrequest/rfc/upload.go (about) 1 package rfc 2 3 import ( 4 "fmt" 5 "github.com/SAP/jenkins-library/pkg/command" 6 "github.com/SAP/jenkins-library/pkg/config/validation" 7 "github.com/SAP/jenkins-library/pkg/log" 8 "github.com/pkg/errors" 9 "strconv" 10 ) 11 12 const ( 13 eq = "=" 14 ) 15 16 // Exec Everything we need for calling an executable 17 type Exec interface { 18 command.ExecRunner 19 GetExitCode() int 20 } 21 22 // Upload ... 23 type Upload interface { 24 Perform(Exec) error 25 WithConnection(Connection) 26 WithConfiguration(UploadConfig) 27 WithApplication(Application) 28 WithTransportRequestID(string) 29 WithApplicationURL(string) 30 } 31 32 // Connection Everything we need for connecting to the ABAP system 33 type Connection struct { 34 // The endpoint in for form <protocol>://<host>:<port>, no path 35 Endpoint string 36 // The ABAP client, like e.g. "001" 37 Client string 38 // The ABAP instance, like e.g. "DEV", "QA" 39 Instance string 40 User string 41 Password string 42 } 43 44 // Application Application specific properties 45 type Application struct { 46 Name string 47 Description string 48 AbapPackage string 49 } 50 51 // UploadConfig additional configuration properties 52 type UploadConfig struct { 53 AcceptUnixStyleEndOfLine bool 54 CodePage string 55 FailUploadOnWarning bool 56 Verbose bool 57 } 58 59 // UploadAction Collects all the properties we need for the deployment 60 type UploadAction struct { 61 Connection Connection 62 Application Application 63 Configuration UploadConfig 64 TransportRequestID string 65 ApplicationURL string 66 } 67 68 // WithApplicationURL The location of the deployable 69 func (action *UploadAction) WithApplicationURL(z string) { 70 action.ApplicationURL = z 71 } 72 73 // WithTransportRequestID The transport request ID for the upload 74 func (action *UploadAction) WithTransportRequestID(t string) { 75 action.TransportRequestID = t 76 } 77 78 // WithApplication Everything we need to know about the application 79 func (action *UploadAction) WithApplication(a Application) { 80 action.Application = a 81 } 82 83 // WithConfiguration Everything we need to know in order to perform the upload 84 func (action *UploadAction) WithConfiguration(c UploadConfig) { 85 action.Configuration = c 86 } 87 88 // WithConnection Everything we need to know about the connection 89 func (action *UploadAction) WithConnection(c Connection) { 90 action.Connection = c 91 } 92 93 // Perform Performs the upload 94 func (action *UploadAction) Perform(command Exec) error { 95 96 log.Entry().Infof("Deploying artifact '%s' to '%s', client: '%s', instance: '%s'.", 97 action.ApplicationURL, action.Connection.Endpoint, action.Connection.Client, action.Connection.Instance, 98 ) 99 100 parametersWithMissingValues, err := validation.FindEmptyStringsInConfigStruct(*action) 101 if err != nil { 102 return fmt.Errorf("invalid configuration parameters detected. SOLMAN upload parameter may be missing : %w", err) 103 } 104 if len(parametersWithMissingValues) != 0 { 105 return fmt.Errorf("cannot perform artifact upload. The following parameters are not available %s", parametersWithMissingValues) 106 } 107 108 command.SetEnv([]string{ 109 "ABAP_DEVELOPMENT_SERVER" + eq + action.Connection.Endpoint, 110 "ABAP_DEVELOPMENT_USER" + eq + action.Connection.User, 111 "ABAP_DEVELOPMENT_PASSWORD" + eq + action.Connection.Password, 112 "ABAP_DEVELOPMENT_INSTANCE" + eq + action.Connection.Instance, 113 "ABAP_DEVELOPMENT_CLIENT" + eq + action.Connection.Client, 114 "ABAP_APPLICATION_NAME" + eq + action.Application.Name, 115 "ABAP_APPLICATION_DESC" + eq + action.Application.Description, 116 "ABAP_PACKAGE" + eq + action.Application.AbapPackage, 117 "ZIP_FILE_URL" + eq + action.ApplicationURL, 118 "CODE_PAGE" + eq + action.Configuration.CodePage, 119 "ABAP_ACCEPT_UNIX_STYLE_EOL" + eq + toAbapBool(action.Configuration.AcceptUnixStyleEndOfLine), 120 "FAIL_UPLOAD_ON_WARNING" + eq + strconv.FormatBool(action.Configuration.FailUploadOnWarning), 121 "VERBOSE" + eq + strconv.FormatBool(action.Configuration.Verbose), 122 }) 123 124 err = command.RunExecutable("cts", fmt.Sprintf("uploadToABAP:%s", action.TransportRequestID)) 125 126 exitCode := command.GetExitCode() 127 if exitCode != 0 { 128 message := fmt.Sprintf("upload command returned with exit code '%d'", exitCode) 129 if err != nil { 130 // Using the wrapping here is to some extend an abuse, since it is not really 131 // error chaining (the other error is not necessaryly a "predecessor" of this one). 132 // But it is a pragmatic approach for not loosing information for trouble shooting. There 133 // is no possibility to have something like suppressed errors. 134 err = errors.Wrap(err, message) 135 } else { 136 err = errors.New(message) 137 } 138 } 139 140 if err == nil { 141 log.Entry().Infof("Deploying artifact '%s' to '%s', client: '%s', instance: '%s' succeeded.", 142 action.ApplicationURL, action.Connection.Endpoint, action.Connection.Client, action.Connection.Instance, 143 ) 144 } else { 145 log.Entry().Warnf("Deploying artifact '%s' to '%s', client: '%s', instance: '%s' failed.", 146 action.ApplicationURL, action.Connection.Endpoint, action.Connection.Client, action.Connection.Instance, 147 ) 148 } 149 return errors.Wrap(err, "cannot upload artifact") 150 } 151 152 func toAbapBool(b bool) string { 153 abapBool := "-" 154 if b { 155 abapBool = "X" 156 } 157 return abapBool 158 }