Skip to content

Commit

Permalink
Merge branch 'release/v0.2.0' into feature/IJMP-1710-declarative-conn…
Browse files Browse the repository at this point in the history
…ection-error

Signed-off-by: Anatoli Kalbasin <[email protected]>
  • Loading branch information
callbacksin authored Sep 18, 2024
2 parents 762f5bb + 880cf4b commit 1b7a3db
Show file tree
Hide file tree
Showing 21 changed files with 225 additions and 50 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Zowe zDevOps Jenkins plugin

## About the plugin
## About the plugin
The Zowe zDevOps Jenkins Plugin by [IBA Group](https://ibagroupit.com/?utm_campaign=IBA_W-Mainframe&utm_source=jenkins&utm_medium=referral&utm_content=description_zdevops) is an open-source, secure , and reliable agent-less Jenkins plugin that makes it possible to perform most of the actual tasks on the mainframe, managing it with a modern native mainframe zOSMF REST API and the capabilities of available zOSMF SDKs.

## Main features
Expand Down
36 changes: 24 additions & 12 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>4.78</version>
<version>4.78</version> <!-- See https://github.com/jenkinsci/plugin-pom/releases for available versions-->
<relativePath />
</parent>

Expand All @@ -19,7 +19,7 @@


<properties>
<revision>0.2.0-</revision>
<revision>0.2.0</revision>
<changelist>-SNAPSHOT</changelist>
<jenkins.version>2.414.3</jenkins.version>
<java.version>17</java.version>
Expand Down Expand Up @@ -375,22 +375,12 @@
<version>2.10.1</version>
</dependency>

<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>script-security</artifactId>
</dependency>

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>

<dependency>
<groupId>org.jenkins-ci</groupId>
<artifactId>annotation-indexer</artifactId>
</dependency>

<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
Expand Down Expand Up @@ -439,6 +429,28 @@
<scope>test</scope>
</dependency>

<!-- Jenkins plug-ins -->

<dependency>
<groupId>org.jenkins-ci</groupId>
<artifactId>annotation-indexer</artifactId>
</dependency>

<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>script-security</artifactId>
</dependency>

<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>credentials</artifactId>
</dependency>

<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-step-api</artifactId>
</dependency>

</dependencies>

<repositories>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ constructor(
val primary: Int = 1,
var secondary: Int,
var recFm: RecordFormat,
var failOnExist: Boolean = false,
) : AbstractBuildStep(connectionName){

private var volser: String? = null
Expand Down Expand Up @@ -177,7 +178,8 @@ constructor(
dataClass,
avgBlk,
dsnType,
dsModel
dsModel,
failOnExist,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import org.zowe.zdevops.Messages
import org.zowe.zdevops.classic.AbstractBuildStep
import org.zowe.zdevops.logic.deleteDatasetOrMember
import org.zowe.zdevops.utils.validateDatasetName
import org.zowe.zdevops.utils.validateFieldIsNotEmpty
import org.zowe.zdevops.utils.validateMemberName

class DeleteDatasetStep
Expand All @@ -38,6 +37,7 @@ constructor(
connectionName: String,
val dsn: String,
val member: String?,
val failOnNotExist: Boolean = false ,
) : AbstractBuildStep(connectionName) {

override fun perform(
Expand All @@ -46,7 +46,7 @@ constructor(
listener: BuildListener,
zosConnection: ZOSConnection
) {
deleteDatasetOrMember(dsn, member, zosConnection, listener)
deleteDatasetOrMember(dsn, member, zosConnection, listener, failOnNotExist)
}

@Extension
Expand All @@ -67,10 +67,14 @@ constructor(
* Checks if the member name is valid
*
* @param member The dataset member name
* @return FormValidation.ok() if the member name is valid, or an error message otherwise
* @return FormValidation.ok() if either the member name is valid or is not provided, or an error message otherwise
*/
fun doCheckMember(@QueryParameter member: String): FormValidation? {
return validateMemberName(member)?: validateFieldIsNotEmpty(member)
return if (member.isNotBlank()) {
validateMemberName(member)
} else {
FormValidation.ok()
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ class DeleteDatasetsByMaskStep
constructor(
connectionName: String,
val dsnMask: String,
val failOnNotExist: Boolean = false,
) : AbstractBuildStep(connectionName) {

override fun perform(
Expand All @@ -39,7 +40,7 @@ constructor(
listener: BuildListener,
zosConnection: ZOSConnection
) {
deleteDatasetsByMask(dsnMask, zosConnection, listener)
deleteDatasetsByMask(dsnMask, zosConnection, listener, failOnNotExist)
}

@Extension
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@ constructor(
val linkBuilder: (String?, String, String) -> String = { jobUrl, jobName, jobId ->
"${jobUrl}ws/${jobName}.${jobId}/*view*/"
}
val returnCode = submitJobSync(jobName, zosConnection, listener, workspace, build.getEnvironment(listener)["JOB_URL"], linkBuilder)
if (checkRC && !returnCode.equals("CC 0000")) {
val jobResult = submitJobSync(jobName, zosConnection, listener, workspace, build.getEnvironment(listener)["JOB_URL"], linkBuilder)
if (checkRC && !jobResult.equals("CC 0000")) {
throw AbortException("Job RC code is not 0000")
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ constructor(
private val dsOrg: DatasetOrganization,
private val primary: Int,
private var secondary: Int,
private var recFm: RecordFormat) :
private var recFm: RecordFormat,
private var failOnExist: Boolean = false) :
AbstractZosmfAction() {

private var volser: String? = null
Expand Down Expand Up @@ -126,7 +127,8 @@ constructor(
dataClass,
avgBlk,
dsnType,
dsModel
dsModel,
failOnExist,
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,17 @@ class DeleteDatasetDeclarative @DataBoundConstructor constructor(

private var dsn: String = ""
private var member: String = ""
private var failOnNotExist: Boolean = false

@DataBoundSetter
fun setDsn(dsn: String) { this.dsn = dsn }

@DataBoundSetter
fun setMember(member: String) { this.member = member }

@DataBoundSetter
fun setFailOnNotExist(failOnNotExist: Boolean) { this.failOnNotExist = failOnNotExist }

override val exceptionMessage: String = zMessages.zdevops_deleting_ds_fail()

override fun perform(
Expand All @@ -83,7 +87,7 @@ class DeleteDatasetDeclarative @DataBoundConstructor constructor(
listener: TaskListener,
zosConnection: ZOSConnection
) {
deleteDatasetOrMember(dsn, member, zosConnection, listener)
deleteDatasetOrMember(dsn, member, zosConnection, listener, failOnNotExist)
}

@Symbol("deleteDataset")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,14 @@ class DeleteDatasetsByMaskDeclarative @DataBoundConstructor constructor(
) : AbstractZosmfAction() {

private var mask: String = ""
private var failOnNotExist: Boolean = false

@DataBoundSetter
fun setMask(mask: String) { this.mask = mask }

@DataBoundSetter
fun setFailOnNotExist(failOnNotExist: Boolean) { this.failOnNotExist = failOnNotExist }

override val exceptionMessage: String = zMessages.zdevops_deleting_ds_fail()

override fun perform(
Expand All @@ -70,7 +74,7 @@ class DeleteDatasetsByMaskDeclarative @DataBoundConstructor constructor(
listener: TaskListener,
zosConnection: ZOSConnection
) {
deleteDatasetsByMask(mask, zosConnection,listener)
deleteDatasetsByMask(mask, zosConnection,listener, failOnNotExist)
}


Expand Down
16 changes: 12 additions & 4 deletions src/main/kotlin/org/zowe/zdevops/logic/AllocateOperation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ fun allocateDataset(listener: TaskListener,
dataClass: String?,
avgBlk: Int?,
dsnType: DsnameType?,
dsModel: String?

dsModel: String?,
failOnExist: Boolean,
) {
listener.logger.println(Messages.zdevops_declarative_DSN_allocating(dsn, zosConnection.host, zosConnection.zosmfPort))
val alcParms = CreateDataset(
Expand All @@ -79,6 +79,14 @@ fun allocateDataset(listener: TaskListener,
dsnType,
dsModel
)
ZosDsn(zosConnection).createDsn(dsn, alcParms)
listener.logger.println(Messages.zdevops_declarative_DSN_allocated_success(dsn))
try {
ZosDsn(zosConnection).createDsn(dsn, alcParms)
listener.logger.println(Messages.zdevops_declarative_DSN_allocated_success(dsn))
} catch (allocateDsEx: Exception) {
listener.logger.println("Dataset allocation failed. Reason: $allocateDsEx")
if(failOnExist) {
throw allocateDsEx
}
listener.logger.println("The `failOnExist` option is set to false. Continuing with execution.")
}
}
41 changes: 28 additions & 13 deletions src/main/kotlin/org/zowe/zdevops/logic/DeleteOperation.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,31 @@ private val successMessage: String = zMessages.zdevops_deleting_ds_success()
* @param listener The task listener to log information and handle exceptions.
* @throws AbortException If the mask is empty or no matching datasets are found.
*/
fun deleteDatasetsByMask(mask: String, zosConnection: ZOSConnection, listener: TaskListener) {
fun deleteDatasetsByMask(mask: String, zosConnection: ZOSConnection, listener: TaskListener, failOnNotExist: Boolean) {
if (mask.isEmpty()) {
throw AbortException(zMessages.zdevops_deleting_datasets_by_mask_but_mask_is_empty())
}
listener.logger.println(zMessages.zdevops_deleting_ds_by_mask(mask))
val dsnList = ZosDsnList(zosConnection).listDsn(mask, ListParams())
if (dsnList.items.isEmpty()) {
throw AbortException(zMessages.zdevops_deleting_ds_fail_no_matching_mask())
}
dsnList.items.forEach {
runMFTryCatchWrappedQuery(listener) {
listener.logger.println(zMessages.zdevops_deleting_ds(it.name, zosConnection.host, zosConnection.zosmfPort))
ZosDsn(zosConnection).deleteDsn(it.name)
try {
val dsnList = ZosDsnList(zosConnection).listDsn(mask, ListParams())
if (dsnList.items.isEmpty()) {
throw AbortException(zMessages.zdevops_deleting_ds_fail_no_matching_mask())
}
dsnList.items.forEach {
runMFTryCatchWrappedQuery(listener) {
listener.logger.println(zMessages.zdevops_deleting_ds(it.name, zosConnection.host, zosConnection.zosmfPort))
ZosDsn(zosConnection).deleteDsn(it.name)
}
}
listener.logger.println(successMessage)
} catch (doesNotExistEx: Exception) {
if(failOnNotExist) {
throw doesNotExistEx
}
listener.logger.println("Reason: $doesNotExistEx")
// TODO I wanna have the dataset name here - it's inside exception message?
listener.logger.println("Dataset deletion failed, but the `failOnNotExist` option is set to false. Continuing with execution.")
}
listener.logger.println(successMessage)
}

/**
Expand All @@ -56,22 +65,28 @@ fun deleteDatasetsByMask(mask: String, zosConnection: ZOSConnection, listener: T
* @param listener The task listener to log information and handle exceptions.
* @throws AbortException If the dataset name is empty or the member name is invalid.
*/
fun deleteDatasetOrMember(dsn: String, member: String?, zosConnection: ZOSConnection, listener: TaskListener) {
fun deleteDatasetOrMember(dsn: String, member: String?, zosConnection: ZOSConnection, listener: TaskListener, failOnNotExist: Boolean) {
if (dsn.isEmpty()) {
throw AbortException(zMessages.zdevops_deleting_ds_fail_dsn_param_empty())
}
val logMessage = if (!member.isNullOrEmpty()) zMessages.zdevops_deleting_ds_member(member, dsn, zosConnection.host, zosConnection.zosmfPort)
else zMessages.zdevops_deleting_ds(dsn, zosConnection.host, zosConnection.zosmfPort)
listener.logger.println(logMessage)
runMFTryCatchWrappedQuery(listener) {
try {
if (!member.isNullOrEmpty()) {
isMemberNameValid(member)
ZosDsn(zosConnection).deleteDsn(dsn, member)
} else {
ZosDsn(zosConnection).deleteDsn(dsn)
}
listener.logger.println(successMessage)
} catch (doesNotExistEx: Exception) {
if(failOnNotExist) {
throw doesNotExistEx
}
listener.logger.println("Reason: $doesNotExistEx")
listener.logger.println("Dataset deletion failed, but the `failOnNotExist` option is set to false. Continuing with execution.")
}
listener.logger.println(successMessage)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import hudson.AbortException
import hudson.model.TaskListener
import org.zowe.kotlinsdk.zowe.client.sdk.core.ZOSConnection
import org.zowe.kotlinsdk.zowe.client.sdk.zostso.IssueTso
import org.zowe.kotlinsdk.zowe.client.sdk.zostso.input.StartTsoParams
import org.zowe.zdevops.Messages

/**
Expand All @@ -36,12 +37,12 @@ fun performTsoCommand(
command: String,
) {
listener.logger.println(Messages.zdevops_issue_TSO_command(command))
runCatching {
val tsoCommandResponse = IssueTso(zosConnection).issueTsoCommand(acct, command)
try {
val tsoCommandResponse = IssueTso(zosConnection).issueTsoCommand(acct, command, StartTsoParams(), failOnPrompt = true)
listener.logger.println(tsoCommandResponse.commandResponses)
}.onFailure {
} catch (ex: Exception) {
listener.logger.println(Messages.zdevops_TSO_command_fail())
throw AbortException(Messages.zdevops_TSO_command_fail())
throw ex
}
listener.logger.println(Messages.zdevops_TSO_command_success())
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import java.io.PrintWriter
import java.io.StringWriter
import java.net.URL


/**
* Gets a list of datasets
* Calls the listDsn function of ZosDsnList to list data set names.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,7 @@
</td>
</tr>
</table>
<form:entry field="failOnExist" title="failOnExist?" description="If the dataset already exists and the option is enabled, execution will halt.">
<form:checkbox/>
</form:entry>
</jelly:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@
<form:entry field="member" title="${%zdevops.classic.member.title}">
<form:textbox/>
</form:entry>
<form:entry field="failOnNotExist" title="failOnNotExist?" description="If the dataset does not exists and the option is enabled, execution will halt.">
<form:checkbox/>
</form:entry>
</jelly:jelly>
Loading

0 comments on commit 1b7a3db

Please sign in to comment.