Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/GHI-11-freestyle-jobs #60

Merged
merged 21 commits into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import javax.servlet.ServletException
/**
* The AbstractBuildStep class is an abstract class that serves as the base for the plugin build steps in Jenkins.
*/
abstract class AbstractBuildStep(private val connectionName: String) : Builder(), SimpleBuildStep {
abstract class AbstractBuildStep(val connectionName: String) : Builder(), SimpleBuildStep {
/**
* Performs the build step.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import org.zowe.kotlinsdk.RecordFormat
import org.zowe.kotlinsdk.zowe.client.sdk.core.ZOSConnection
import org.zowe.zdevops.Messages
import org.zowe.zdevops.classic.AbstractBuildStep
import org.zowe.zdevops.logic.AllocateOperation.Companion.allocateDataset
import org.zowe.zdevops.logic.allocateDataset
import org.zowe.zdevops.utils.validateDatasetName
import java.io.IOException
import javax.servlet.ServletException
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ 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 Down Expand Up @@ -69,7 +70,7 @@ constructor(
* @return FormValidation.ok() if the member name is valid, or an error message otherwise
*/
fun doCheckMember(@QueryParameter member: String): FormValidation? {
return if (member.isEmpty()) FormValidation.ok() else validateMemberName(member)
return validateMemberName(member)?: validateFieldIsNotEmpty(member)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* This program and the accompanying materials are made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Copyright IBA Group 2023
*/

package org.zowe.zdevops.classic.steps

import hudson.Extension
import hudson.Launcher
import hudson.model.AbstractBuild
import hudson.model.BuildListener
import hudson.util.FormValidation
import org.kohsuke.stapler.DataBoundConstructor
import org.kohsuke.stapler.QueryParameter
import org.zowe.kotlinsdk.zowe.client.sdk.core.ZOSConnection
import org.zowe.zdevops.Messages
import org.zowe.zdevops.classic.AbstractBuildStep
import org.zowe.zdevops.logic.performTsoCommand
import org.zowe.zdevops.utils.validateFieldIsNotEmpty


/**
* A Jenkins Pipeline step for performing a TSO (Time Sharing Option) command on a z/OS system via freestyle job.
*/
class PerformTsoCommandStep
/**
* Data-bound constructor for the {@code PerformTsoCommandStep} step.
*
* @param connectionName The name of the z/OS connection to be used for executing the TSO command.
* @param acct The z/OS account number.
* @param command The TSO command to be executed.
*/
@DataBoundConstructor
constructor(
connectionName: String,
val acct: String,
val command: String,
) : AbstractBuildStep(connectionName) {

/**
* Performs the TSO command execution step within a Jenkins Pipeline build.
*
* @param build The current Jenkins build.
* @param launcher The build launcher.
* @param listener The build listener.
* @param zosConnection The z/OS connection to execute the TSO command.
*/
override fun perform(
build: AbstractBuild<*, *>,
launcher: Launcher,
listener: BuildListener,
zosConnection: ZOSConnection
) {
performTsoCommand(zosConnection, listener, acct, command)
}


/**
* Descriptor for the {@code PerformTsoCommandStep} step.
*
* This descriptor provides information about the step and makes it available for use
* within Jenkins Pipelines.
*/
@Extension
class DescriptorImpl : Companion.DefaultBuildDescriptor(Messages.zdevops_classic_performTsoCommandStep_display_name()) {

/**
* Performs form validation for the 'acct' parameter to ensure it is not empty.
*
* @param acct The z/OS account number field value to validate.
* @return A {@link FormValidation} object indicating whether the field is valid or contains an error.
*/
fun doCheckAcct(@QueryParameter acct: String): FormValidation? {
return validateFieldIsNotEmpty(acct)
}

/**
* Performs form validation for the 'command' parameter to ensure it is not empty.
*
* @param command The TSO command field value to validate.
* @return A {@link FormValidation} object indicating whether the field is valid or contains an error.
*/
fun doCheckCommand(@QueryParameter command: String): FormValidation? {
return validateFieldIsNotEmpty(command)
}

}
}
144 changes: 144 additions & 0 deletions src/main/kotlin/org/zowe/zdevops/classic/steps/WriteFileToFileStep.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package org.zowe.zdevops.classic.steps

import hudson.AbortException
import hudson.Extension
import hudson.Launcher
import hudson.model.AbstractBuild
import hudson.model.BuildListener
import hudson.util.FormValidation
import hudson.util.ListBoxModel
import org.kohsuke.stapler.DataBoundConstructor
import org.kohsuke.stapler.DataBoundSetter
import org.kohsuke.stapler.QueryParameter
import org.kohsuke.stapler.bind.JavaScriptMethod
import org.zowe.kotlinsdk.zowe.client.sdk.core.ZOSConnection
import org.zowe.zdevops.Messages
import org.zowe.zdevops.classic.AbstractBuildStep
import org.zowe.zdevops.logic.writeToFile
import org.zowe.zdevops.utils.validateFieldIsNotEmpty
import java.io.File

class WriteFileToFileStep
@DataBoundConstructor
constructor(
connectionName: String,
val filePathUSS: String,
var binary: Boolean = false,
var fileOption: String?,
) : AbstractBuildStep(connectionName) {

private var localFilePath: String? = null
private var workspacePath: String? = null

@DataBoundSetter
fun setLocalFilePath(localFilePath: String?) {
this.localFilePath = localFilePath
}
@DataBoundSetter
fun setWorkspacePath(workspacePath: String?) {
this.workspacePath = workspacePath
}
fun getLocalFilePath(): String? {
return this.localFilePath
}
fun getWorkspacePath(): String? {
return this.workspacePath
}

override fun perform(
build: AbstractBuild<*, *>,
launcher: Launcher,
listener: BuildListener,
zosConnection: ZOSConnection
) {
val sourcePath = if(workspacePath != null) workspacePath else localFilePath
listener.logger.println(Messages.zdevops_declarative_writing_file_from_file(filePathUSS, sourcePath, zosConnection.host, zosConnection.zosmfPort))
val workspace = build.executor?.currentWorkspace
val file = when (fileOption) {
DescriptorImpl().localFileOption -> localFilePath?.let { File(it) }
DescriptorImpl().workspaceFileOption -> {
val fileWorkspacePath = workspace?.remote + '\\' + workspacePath
File(fileWorkspacePath)
}
else -> throw AbortException(Messages.zdevops_classic_write_options_invalid())
}
val text = file?.readBytes()
if (text != null) {
writeToFile(listener, zosConnection, filePathUSS, text, binary)
}
}

@Extension
class DescriptorImpl :
Companion.DefaultBuildDescriptor(Messages.zdevops_classic_writeFileToFileStep_display_name()) {
private var lastStepId = 0
private val marker: String = "WFTF"

val chooseFileOption = "choose"
val localFileOption = "local"
val workspaceFileOption = "workspace"

/**
* Creates a unique step ID
*
* @return The generated step ID
*/
@JavaScriptMethod
@Synchronized
fun createStepId(): String {
return marker + lastStepId++.toString()
}

/**
* Fills the file option items for the dropdown menu
*
* @return The ListBoxModel containing the file option items
*/
fun doFillFileOptionItems(): ListBoxModel {
val result = ListBoxModel()

result.add(Messages.zdevops_classic_write_options_choose(), chooseFileOption)
result.add(Messages.zdevops_classic_write_options_local(), localFileOption)
result.add(Messages.zdevops_classic_write_options_workspace(), workspaceFileOption)

return result
}

/**
* Checks if the file option is valid
*
* @param fileOption The selected file option
* @return FormValidation.ok() if the file option is valid, or an error message otherwise
*/
fun doCheckFileOption(@QueryParameter fileOption: String): FormValidation? {
if (fileOption == chooseFileOption || fileOption.isEmpty()) return FormValidation.error(Messages.zdevops_classic_write_options_required())
return FormValidation.ok()
}

/**
* Checks if the local file path not empty
*
* @param localFilePath The local file path
* @param fileOption The selected file option
* @return FormValidation.ok() if the local file path is not empty, or an error message otherwise
*/
fun doCheckLocalFilePath(@QueryParameter localFilePath: String,
@QueryParameter fileOption: String): FormValidation? {
return if (fileOption == localFileOption) validateFieldIsNotEmpty(localFilePath)
else FormValidation.ok()
}

/**
* Checks if the workspace path is not empty
*
* @param workspacePath The workspace path
* @param fileOption The selected file option
* @return FormValidation.ok() if the workspace path is not empty, or an error message otherwise
*/
fun doCheckWorkspacePath(@QueryParameter workspacePath: String,
@QueryParameter fileOption: String): FormValidation? {
return if (fileOption == workspaceFileOption) validateFieldIsNotEmpty(workspacePath)
else FormValidation.ok()
}
}
}
90 changes: 90 additions & 0 deletions src/main/kotlin/org/zowe/zdevops/classic/steps/WriteToFileStep.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* This program and the accompanying materials are made available under the terms of the
* Eclipse Public License v2.0 which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-v20.html
*
* SPDX-License-Identifier: EPL-2.0
*
* Copyright IBA Group 2023
*/

package org.zowe.zdevops.classic.steps

import hudson.Extension
import hudson.Launcher
import hudson.model.AbstractBuild
import hudson.model.BuildListener
import hudson.util.FormValidation
import org.kohsuke.stapler.DataBoundConstructor
import org.kohsuke.stapler.QueryParameter
import org.zowe.kotlinsdk.zowe.client.sdk.core.ZOSConnection
import org.zowe.zdevops.Messages
import org.zowe.zdevops.classic.AbstractBuildStep
import org.zowe.zdevops.logic.writeToFile
import org.zowe.zdevops.utils.validateFieldIsNotEmpty

/**
* A build step for writing text(string) to a USS file
*/
class WriteToFileStep
/**
* Constructs a new instance of WriteToFileStep.
*
* @param filePath The name of the z/OS connection
* @param text The name of the dataset
* @param binary The name of the member
*/
@DataBoundConstructor
constructor(
connectionName: String,
val filePath: String,
val text: String,
var binary: Boolean = false,
) : AbstractBuildStep(connectionName) {

/**
* Performs the write operation
*
* @param build The build object
* @param launcher The launcher for executing commands
* @param listener The listener for logging messages
* @param zosConnection The ZOSConnection for interacting with z/OS
*/
override fun perform(
build: AbstractBuild<*, *>,
launcher: Launcher,
listener: BuildListener,
zosConnection: ZOSConnection
) {
listener.logger.println(Messages.zdevops_declarative_writing_file_from_input(filePath, zosConnection.host, zosConnection.zosmfPort))
val textBytes = text.toByteArray()
writeToFile(listener, zosConnection, filePath, textBytes, binary)
}

/**
* The descriptor for the WriteToFileStep
*/
@Extension
class DescriptorImpl : Companion.DefaultBuildDescriptor(Messages.zdevops_classic_writeToFileStep_display_name()) {
/**
* Validates the file path
*
* @param filePath The file path to write to
* @return FormValidation.ok() if the path is not empty, or an error message otherwise
*/
fun doCheckFilePath(@QueryParameter filePath: String): FormValidation? {
return validateFieldIsNotEmpty(filePath)
}

/**
* Validates the text to write
*
* @param text The text to write
* @return FormValidation.ok() if the text is not empty, or an error message otherwise
*/
fun doCheckText(@QueryParameter text: String): FormValidation? {
return validateFieldIsNotEmpty(text)
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,18 @@ package org.zowe.zdevops.declarative.jobs

import hudson.EnvVars
import hudson.Extension
import org.zowe.kotlinsdk.*
import org.zowe.kotlinsdk.zowe.client.sdk.core.ZOSConnection
import org.zowe.zdevops.declarative.AbstractZosmfAction
import hudson.FilePath
import hudson.Launcher
import hudson.model.Run
import hudson.model.TaskListener
import org.jenkinsci.Symbol
import org.kohsuke.stapler.DataBoundConstructor
import org.kohsuke.stapler.DataBoundSetter
import org.zowe.kotlinsdk.*
import org.zowe.kotlinsdk.zowe.client.sdk.core.ZOSConnection
import org.zowe.zdevops.Messages
import org.zowe.zdevops.logic.AllocateOperation.Companion.allocateDataset
import org.zowe.zdevops.declarative.AbstractZosmfAction
import org.zowe.zdevops.logic.allocateDataset

/**
* Represents an action for allocating a dataset in a declarative style
Expand Down
Loading