How to get logged in user Jenkins pipeline - jenkins

I can get build user in Jenkins pipeline (using build user var plugin). But I can't get logged in user. Please see below script
stage('Manual Approval')
{
steps {
script {
def userInput
try {
userInput = input(id: 'Proceed1', message: 'Do you want to approve this step ?', parameters: [[$class: 'BooleanParameterDefinition', defaultValue: true, description: '', name: 'Please confirm you agree with this' ]])
} catch (err)
{
def user = err.getCauses()[0].getUser()
userInput = false
echo "Aborted by: [${user}]"
}
}
}
}
And here is log of Jenkins
Input requested
Approved by admin
How can I get the user name "admin" in this case (if the value of input is true) ? When I use the function User.current().getId(), it always return SYSTEM
In my case, I want to check logged in user whether has correct permission or not

It's not very clear what you are asking but it sounds like you want the id of the user who approved the input step.
If that is the case then you can use the submitterParameter property of the input step. You will find it in the input step doco (https://www.jenkins.io/doc/pipeline/steps/pipeline-input-step/) and under Pipeline Syntax in Jenkins.
This is what it would look like in your example:
def userInput = input(id: 'Proceed1',
submitterParameter: 'submitter',
message: 'Do you want to approve this step ?',
parameters: [booleanParam(defaultValue: true, description:'',name: 'Please confirm you agree with this'])
println userInput.submitter
Note that if you didn't have any other parameters in the input step then the return value would be the submitter user id directly instead of a map as is the case above.

Related

How to execute shell script in jenkins Active Choice Parameter so that I can get the dynamic inputs

I tried fetching present working directory using below script in Active Choice Parameter in Jenkins but it's not giving any output. Also the fallback script is not getting called
def command = "pwd"
def proc = command.execute()
proc.waitFor()
def output = proc.in.text
def exitcode = proc.exitValue()
def error = proc.err.text
println "${output}"
This script will run well with script console in Jenkins at http://jenkins-url/script but in active choice you don't need to print the output instead you can return the output from script so parameter will get the value.
def command = "pwd"
def proc = command.execute()
proc.waitFor()
def output = proc.in.text
def exitcode = proc.exitValue()
def error = proc.err.text
return [output]
in jenkins pipeline you can print the value of the parameter as below -
suppose you have defined the parameter name in active choice is param1 and you can get the value in pipeline as below -
pipeline {
agent any
stages {
stage('sample active choice') {
steps {
echo "Param value is ${param1}"
}
}
}
}

Jenkins Pipeline Get Rejecter Name instead of user id

I have followed below link to reject /approve deployment request. But if i reject deployment i can only get user id. How can i get user name?
def user = err.getCauses()[0].getUser()
https://support.cloudbees.com/hc/en-us/articles/226554067-Pipeline-How-to-add-an-input-step-with-timeout-that-continues-if-timeout-is-reached-using-a-default-value?mobile_site=true
Try this:
import hudson.model.Cause
import hudson.tasks.Mailer
import hudson.model.User
def name = cause.getUserName()
println "name is ${name}"
def jenkins_id = cause.getUserId()
println "jenkins_id is ${jenkins_id}"
User u = User.get(jenkins_id)
def umail = u.getProperty(Mailer.UserProperty.class)
def email = umail.getAddress()
println "email is ${email}"
You may want to read the JavaDocs of the User class to see if the name is available.
I found solution to this as below
def user = err.getCauses()[0].getUser().getDisplayName()

How to render Html template with info from database in Services

I am having dificulties to do the following:
Having a job that runs from time to time (Done)
Fetching some data from database inside that job (Done)
Next step would be use that data with a template that I already created (HTML) and then render it to PDF
Then send an email with that pdf in attachment
This is my current job:
def execute() {
println("Hi, I am a schedule Job triggering every half an hour from 7 AM to 22 PM that will never stop running until master jose tells me to :)")
EventService.updateOffersdwh()
EventService.getUncheckedOffers()
}
which is working properly :)
Those are my service's methods called in the previous job:
def updateOffersdwh(){
def sql = Sql.newInstance("jdbc:postgresql://"+hostname+":5432/xyz", username, password, "org.postgresql.Driver")
sql.rows(" Select From bird_admin.updt_offerorders('2018-03-07','2018-03-07','" + database + "') ");
println('Updating Order and Offers datawarehouse...');
}
def getUncheckedOffers(){
def sql = sql.newInstance("jdbc:postgresql://"+hostname+":5432/xyz", username, password, "org.postgresql.Driver")
def query = "select id, poo_id, b.name, b.address_line1, b.address_line2, b.zipcode, event_date::date, task_name, sku_id, sku_name, column_type, column_value, instance_name,checked FROM bird_admin.ooisdwh a LEFT JOIN sd_bel.cfg_point_of_operation b ON a.poo_id = b.id WHERE checked = false"
def offers = sql.rows(query)
println('DEBUG OFFERS FINAL:: '+offers)
}
Can anyone please advice or guide me on the next steps?
How can I use a template in html that I already have in my views\template folder?
What is the best way to use the info from the database and render the html with that info?
Should I use a controller? If so, how? I'm kinda lost now :|
I'm not 100% sure if you want to use the template for the body of the email or the attachment, but to use a template for the body of the email you can do the following.
First add the dependency for the Grails mail plugin:
build.gradle
dependencies {
compile "org.grails.plugins:mail:2.0.0"
...
}
Then in your service generate the body using the template and send like:
class YourService {
def groovyPageRenderer
def mailService
def getUncheckedOffers(){
def sql = sql.newInstance("jdbc:postgresql://"+hostname+":5432/xyz", username, password, "org.postgresql.Driver")
def query = "select id, poo_id, b.name, b.address_line1, b.address_line2, b.zipcode, event_date::date, task_name, sku_id, sku_name, column_type, column_value, instance_name,checked FROM bird_admin.ooisdwh a LEFT JOIN sd_bel.cfg_point_of_operation b ON a.poo_id = b.id WHERE checked = false"
def offers = sql.rows(query)
def content = groovyPageRenderer.render( view: "/aViewDirectory/mail",
model:[offers : offers ] )
mailService.sendMail {
to 'anEmailRecipient#somewhere.com'
subject "Email subject"
html( content )
}
}
There's a section in the email plugin docs about attachments.
You can follow the steps above to generate a PDF from a template and attach as per the docs.

How I can use one Rspec expect assertion to be run for every test, without repeating myself?

I have different functions to write a Rspec tests for. But the problem is, what I try to test here, has same syntax per each function, so I have to copy paste that "expect" line for each test case. Do you know how I can write that expect assertion once and apply to each test step?
look at "expect(Delayed::Job.count).to eq(1)" In the code below:
it 'is able to send reminder email for submission deadline to signed-up users ' do
mail = DelayedMailer.new(#assignment.id, "submission", #due_at)
Delayed::Job.enqueue(payload_object: mail, priority: 1, run_at: 1.second.from_now)
expect(Delayed::Job.count).to eq(1)
expect(Delayed::Job.last.handler).to include("deadline_type: submission")
expect { mail.perform } .to change { Mailer.deliveries.count } .by(1)
end
it 'is able to send reminder email for review deadline to reviewers ' do
mail = DelayedMailer.new(#assignment.id, "review", #due_at)
Delayed::Job.enqueue(payload_object: mail, priority: 1, run_at: 1.second.from_now)
expect(Delayed::Job.count).to eq(1)
expect(Delayed::Job.last.handler).to include("deadline_type: review")
expect { mail.perform } .to change { Mailer.deliveries.count } .by(1)
end
it 'is able to send reminder email for Metareview deadline to meta-reviewers and team members of the assignment' do
mail = DelayedMailer.new(#assignment.id, "metareview", #due_at)
Delayed::Job.enqueue(payload_object: mail, priority: 1, run_at: 1.second.from_now)
expect(Delayed::Job.count).to eq(1)
expect(Delayed::Job.last.handler).to include("deadline_type: metareview")
expect { mail.perform } .to change { Mailer.deliveries.count } .by(2)
end
You've got two options here:
1) Make a helper method that wraps that logic: https://relishapp.com/rspec/rspec-core/v/3-4/docs/helper-methods/define-helper-methods-in-a-module
The only downside to this one is that you'll have to call the method everywhere you want it.
or
2) Use an after each hook: https://relishapp.com/rspec/rspec-core/v/3-4/docs/helper-methods/define-helper-methods-in-a-module
I don't recommend this one because it will literally run after every spec.

rspec test for passing params into a controller

I am having trouble setting up a spec for something that I did. I know that it is working the way I want it to because i've manually tested this, but I know if I still want a spec associated with it.
I have an index of players, and I also have a section of teams that are able to assign priority players. By doing that assigning, they pulling from the initial controller that generates the index.
For the team section I have just an ajax call where I am passing the params
ajax:
url: "#{admin_players_path(disabled: 'false')}"
dataType: 'json'
Here is the controller, I have a conditional in there that accounts for the request from the team page.
def index
#q = #player.search(params[:q])
if params[:disabled] == 'false'
#player = #q.result(distinct: true).enabled
else
#player = #q.result(distinct: true)
end
end
That is essentially all I did on my app side of things, and it works well. If I ask for the players in the normal index, it shows them to me both disabled and enabled, and if I look to assign priority players it only shows me enabled players.
My problem is revolved around my spec as I can't get things properly set up to account for that params change.
context "with a prioritized player set up" do
let(:params) { { disabled: false } }
let!(:player1) { create(:player, disabled: true, disabled_at: Time.current) }
let!(:player2) { create(:player) }
it 'returns only enabled players' do
get :index, params: params
expect(assigns[:player]).to_not include(player1)
end
end
Regardless of how I try to setup my spec, I cannot get the proper condition the way i'd like and keep getting the spec to fail. Would anyone know what I am missing with this one?
Ok so after a little work behind it, I was able to figure out what was needed within this.
In the ajax url I have the params set to disabled: 'false'
but in the spec I have the params set at let(:params) { { disabled: false } }
The problem is that in the ajax call I have things set as a string, but in the spec I have them set as a boolean.
All I had to do was change the set up to let(:params) { { disabled: ‘false' } }
and the specs were all good to go!

Resources