github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/pkg/transportrequest/solman/create.go (about) 1 package solman 2 3 import ( 4 "bytes" 5 "fmt" 6 "github.com/SAP/jenkins-library/pkg/config/validation" 7 "github.com/SAP/jenkins-library/pkg/log" 8 "github.com/pkg/errors" 9 "io" 10 "strings" 11 ) 12 13 // CreateAction Collects all the properties we need for creating a transport request 14 type CreateAction struct { 15 Connection Connection 16 ChangeDocumentID string 17 DevelopmentSystemID string 18 CMOpts []string 19 } 20 21 // Create collects everything which is needed for creating a transport request 22 type Create interface { 23 WithConnection(Connection) 24 WithChangeDocumentID(string) 25 WithDevelopmentSystemID(string) 26 WithCMOpts([]string) 27 Perform(command Exec) (string, error) 28 } 29 30 // WithConnection specifies all the connection details which 31 // are required in order to connect so SOLMAN 32 func (a *CreateAction) WithConnection(c Connection) { 33 a.Connection = c 34 } 35 36 // WithChangeDocumentID specifies the change document for that 37 // the transport request is created. 38 func (a *CreateAction) WithChangeDocumentID(id string) { 39 a.ChangeDocumentID = id 40 } 41 42 // WithDevelopmentSystemID specifies the development system ID. 43 func (a *CreateAction) WithDevelopmentSystemID(id string) { 44 a.DevelopmentSystemID = id 45 } 46 47 // WithCMOpts sets additional options for calling the 48 // cm client tool. E.g. -D options. Useful for troubleshooting 49 func (a *CreateAction) WithCMOpts(opts []string) { 50 a.CMOpts = opts 51 } 52 53 // Perform creates a new transport request 54 func (a *CreateAction) Perform(command Exec) (string, error) { 55 56 log.Entry().Infof("Creating new transport request via '%s'.", a.Connection.Endpoint) 57 58 missingParameters, err := validation.FindEmptyStringsInConfigStruct(*a) 59 60 if err == nil { 61 if len(missingParameters) != 0 { 62 err = fmt.Errorf("the following parameters are not available %s", missingParameters) 63 } 64 } 65 66 var transportRequestID string 67 68 if err == nil { 69 if len(a.CMOpts) > 0 { 70 command.SetEnv([]string{fmt.Sprintf("CMCLIENT_OPTS=%s", strings.Join(a.CMOpts, " "))}) 71 } 72 73 oldStdout := command.GetStdout() 74 defer func() { 75 command.Stdout(oldStdout) 76 }() 77 78 var cmClientStdout bytes.Buffer 79 w := io.MultiWriter(&cmClientStdout, oldStdout) 80 command.Stdout(w) 81 82 err = command.RunExecutable("cmclient", 83 "--endpoint", a.Connection.Endpoint, 84 "--user", a.Connection.User, 85 "--password", a.Connection.Password, 86 "create-transport", 87 "-cID", a.ChangeDocumentID, 88 "-dID", a.DevelopmentSystemID, 89 ) 90 91 exitCode := command.GetExitCode() 92 if exitCode != 0 { 93 message := fmt.Sprintf("create transport request command returned with exit code '%d'", exitCode) 94 if err != nil { 95 // Using the wrapping here is to some extend an abuse, since it is not really 96 // error chaining (the other error is not necessaryly a "predecessor" of this one). 97 // But it is a pragmatic approach for not loosing information for trouble shooting. There 98 // is no possibility to have something like suppressed errors. 99 err = errors.Wrap(err, message) 100 } else { 101 err = errors.New(message) 102 } 103 } 104 105 if err == nil { 106 transportRequestID = strings.TrimSpace(cmClientStdout.String()) 107 } 108 } 109 110 if err == nil { 111 log.Entry().Infof("Created transport request '%s' at '%s'. ChangeDocumentId: '%s', DevelopmentSystemId: '%s'", 112 transportRequestID, 113 a.Connection.Endpoint, 114 a.ChangeDocumentID, 115 a.DevelopmentSystemID, 116 ) 117 } else { 118 log.Entry().WithError(err).Warnf("Creating transport request '%s' at '%s' failed. ChangeDocumentId: '%s', DevelopmentSystemId: '%s'", 119 transportRequestID, 120 a.Connection.Endpoint, 121 a.ChangeDocumentID, 122 a.DevelopmentSystemID, 123 ) 124 } 125 126 return transportRequestID, errors.Wrap(err, "cannot create transport request") 127 }