github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/pkg/transportrequest/solman/upload.go (about) 1 package solman 2 3 import ( 4 "fmt" 5 "github.com/SAP/jenkins-library/pkg/config/validation" 6 "github.com/SAP/jenkins-library/pkg/log" 7 "github.com/pkg/errors" 8 "strings" 9 ) 10 11 // FileSystem interface collecting everything which is file system 12 // related and needed in the context of a SOLMAN upload. 13 type FileSystem interface { 14 FileExists(path string) (bool, error) 15 } 16 17 // UploadAction Collects all the properties we need for the deployment 18 type UploadAction struct { 19 Connection Connection 20 ChangeDocumentID string 21 TransportRequestID string 22 ApplicationID string 23 File string 24 CMOpts []string 25 } 26 27 // Action collects everything which is needed to perform a SOLMAN upload 28 type Action interface { 29 WithConnection(Connection) 30 WithChangeDocumentID(string) 31 WithTransportRequestID(string) 32 WithApplicationID(string) 33 WithFile(string) 34 WithCMOpts([]string) 35 Perform(fs FileSystem, command Exec) error 36 } 37 38 // WithConnection specifies all the connection details which 39 // are required in order to connect to SOLMAN 40 func (a *UploadAction) WithConnection(c Connection) { 41 a.Connection = c 42 } 43 44 // WithChangeDocumentID specifies the change document which 45 // receives the executable. 46 func (a *UploadAction) WithChangeDocumentID(id string) { 47 a.ChangeDocumentID = id 48 } 49 50 // WithTransportRequestID specifies the transport request which 51 // receives the executable. 52 func (a *UploadAction) WithTransportRequestID(id string) { 53 a.TransportRequestID = id 54 } 55 56 // WithApplicationID specifies the application ID. 57 func (a *UploadAction) WithApplicationID(id string) { 58 a.ApplicationID = id 59 } 60 61 // WithFile specifies the executable which should be uploaded into 62 // a transport on SOLMAN 63 func (a *UploadAction) WithFile(f string) { 64 a.File = f 65 } 66 67 // WithCMOpts sets additional options for calling the 68 // cm client tool. E.g. -D options. Useful for troubleshooting 69 func (a *UploadAction) WithCMOpts(opts []string) { 70 a.CMOpts = opts 71 } 72 73 // Perform performs the SOLMAN upload 74 func (a *UploadAction) Perform(fs FileSystem, command Exec) error { 75 76 log.Entry().Infof("Deploying artifact '%s' to '%s'.", 77 a.File, a.Connection.Endpoint) 78 79 missingParameters, err := validation.FindEmptyStringsInConfigStruct(*a) 80 81 if err == nil { 82 notInitialized := len(missingParameters) != 0 83 if notInitialized { 84 err = fmt.Errorf("the following parameters are not available '%s'", missingParameters) 85 } 86 } 87 88 if err == nil { 89 var exists bool 90 exists, err = fs.FileExists(a.File) 91 92 if err == nil && !exists { 93 err = fmt.Errorf("file '%s' does not exist", a.File) 94 } 95 } 96 97 if err == nil { 98 if len(a.CMOpts) > 0 { 99 command.SetEnv([]string{fmt.Sprintf("CMCLIENT_OPTS=%s", strings.Join(a.CMOpts, " "))}) 100 } 101 102 err = command.RunExecutable("cmclient", 103 "--endpoint", a.Connection.Endpoint, 104 "--user", a.Connection.User, 105 "--password", a.Connection.Password, 106 "upload-file-to-transport", 107 "-cID", a.ChangeDocumentID, 108 "-tID", a.TransportRequestID, 109 a.ApplicationID, a.File) 110 111 exitCode := command.GetExitCode() 112 113 if exitCode != 0 { 114 message := fmt.Sprintf("upload command returned with exit code '%d'", exitCode) 115 if err != nil { 116 // Using the wrapping here is to some extend an abuse, since it is not really 117 // error chaining (the other error is not necessaryly a "predecessor" of this one). 118 // But it is a pragmatic approach for not loosing information for trouble shooting. There 119 // is no possibility to have something like suppressed errors. 120 err = errors.Wrap(err, message) 121 } else { 122 err = errors.New(message) 123 } 124 } 125 } 126 127 if err == nil { 128 log.Entry().Infof("Deployment succeeded, artifact: '%s', endpoint: '%s'", 129 a.File, a.Connection.Endpoint) 130 } else { 131 log.Entry().WithError(err).Warnf("Deployment failed, artifact: '%s', endpoint: '%s'", 132 a.File, a.Connection.Endpoint) 133 } 134 135 return errors.Wrapf(err, "cannot upload artifact '%s'", a.File) 136 }