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

puppet_helper.groovy uses deprecated remoting mode #749

Closed
oc243 opened this issue May 2, 2017 · 26 comments · Fixed by #752
Closed

puppet_helper.groovy uses deprecated remoting mode #749

oc243 opened this issue May 2, 2017 · 26 comments · Fixed by #752

Comments

@oc243
Copy link

oc243 commented May 2, 2017

My puppet config uses the bootstrap script as described in [0]. However, it appears to have been broken by the deprecation of remoting mode [1]. When puppet runs I now get:

java -jar /usr/share/jenkins/jenkins-cli.jar -s http://127.0.0.1:8080 -http groovy /usr/share/jenkins/puppet_helper.groovy create_or_update_user admin me@me.com  admin <SSH KEY>

ERROR: This command is requesting the deprecated -remoting mode. See https://jenkins.io/redirect/cli-command-requires-channel

It looks as if we now need to use the ssh or http authentication methods in the create_or_update_user function of puppet_helper.groovy.

[0] https://github.com/jenkinsci/puppet-jenkins#cli-helper
[1] jenkinsci/jenkins#2795

@elconas
Copy link
Contributor

elconas commented May 5, 2017

This is true for Jenkins >= 2.54 and Jenkins LTS >= 2.46.2

See:

Note: Calling the groovy helper like this works. I don't see the difference:

  $helper_cmd = join(
    delete_undef_values([
      '/usr/bin/cat',
      $helper_groovy,
      '|',
      '/usr/bin/java',
      "-jar ${::jenkins::cli::jar}",
      "-s http://127.0.0.1:${port}${prefix}",
      $auth_arg,
      "groovy ="
    ]),
    ' '
  )

I have a working prototype with SSH -ssh -u USER and HTTP -auth USER:PASS or -auth @/path/to/password_file working. It is version aware, however I don't know how to determine the jenkins version really. So I need to add an explicit parameter. I will link the pull request.

@oc243
Copy link
Author

oc243 commented May 5, 2017

Thanks @elconas. Would be interested ti see your PR :)

elconas added a commit to elconas/puppet-jenkins that referenced this issue May 6, 2017
@elconas
Copy link
Contributor

elconas commented May 7, 2017

The pull request is work in progress. Right now everything looks good, however I need to fix the xtypes to be jenkins version aware.

I could use something like this in the provider that should work with all packages and plattforms.

root@server # unzip -c /usr/lib/jenkins/jenkins.war WEB-INF/web.xml  | grep display-name
  <display-name>Jenkins v2.46.2</display-name>

Also we need to add explicit cli_remoting option to the x_types to provide heuristics + explicit settings for the new CLI.

However fixing the x_types is kind of difficult. If someone (@oc243) can jump in to fix it based on the puppet code in the pull request, thanks.

@elconas
Copy link
Contributor

elconas commented May 7, 2017

It seems the native types and providers can not easily be ported, as all data is supplied via stdin (user config via json), making it impossible to provide the helper script via stdin, which is a requirement to avoid remoing (See https://github.com/jenkinsci/jenkins/blob/729016989e13632bc980957d05060510efddf41f/core/src/main/java/hudson/cli/GroovyCommand.java#L97-L100)

So all native types need to be refactored, to supply the data via cmdline as argument to the command (e.g. groovy = update_user '...json_data_..') with proper escaping. This involves editing the puppet_helper.groovy (expects data from stdin) as well as all native types. :(

@elconas
Copy link
Contributor

elconas commented May 7, 2017

I personally think it is time for a rewrite of rtyler/jenkins based on native types and providers ONLY and for jenkins 2.46.2 and 2.54 onward (new major version), using the remoting free cli and supporting -auth @file as authentication, as this would enable the module to configure matrix security, active directory and LDAP integration (cli authenticating via username password and with SSH Key) and everything that is missing now. Then all legacy code could be thrown away. This could then also be a Puppet4 only rewrite with fixes for puppetserver using all the nice iterations and such ...

@jhoblitt
Copy link
Member

jhoblitt commented May 7, 2017

It sounds like there's little reason to keep using the cli jar. It should be possible to replace the cli based providers with something that uses the /scriptText end point directly.

@elconas
Copy link
Contributor

elconas commented May 8, 2017

I found that a valid workaround (as long as CLI and Jenkins are running on the same machine) is to write the puppet_helper.groovy json data to the temporary file instead of stdin (already happening), make it readbale by jenkins and provide the filename as command line parameter transparently. This avoids printing the json data on ps ax output (including credentials, which may be a security risk) and makes groovy work with latest Jenkins non remoting CLI, also with username and password, which allows to AD and LDAP usage (which we do)

elconas added a commit to elconas/puppet-jenkins that referenced this issue May 8, 2017
@elconas
Copy link
Contributor

elconas commented May 8, 2017

@jhoblitt @oc243 I updated the pull request after all tests are green into a single commit. With the code in this pull request, I can also use username and password for CLI access, allowing AD and LDAP integration.

@uhanisch
Copy link

uhanisch commented May 9, 2017

Great job

@stefanandres
Copy link

stefanandres commented May 10, 2017

Nice Job, but how is this supposed to work now?

classes:
  - jenkins
  - jenkins::security

jenkins::security::security_model: full_control

on a fresh installation will result in:

Info: /Stage[main]/Jenkins::Security/Jenkins::Cli::Exec[jenkins-security-full_control]/Exec[jenkins-security-full_control]: Scheduling refresh of Class[Jenkins::Cli::Reload]
Info: Class[Jenkins::Cli::Reload]: Scheduling refresh of Exec[reload-jenkins]
Notice: /Stage[main]/Jenkins::Cli::Reload/Exec[reload-jenkins]/returns:
Notice: /Stage[main]/Jenkins::Cli::Reload/Exec[reload-jenkins]/returns: ERROR: anonymous is missing the Overall/Administer permission
Notice: /Stage[main]/Jenkins::Cli::Reload/Exec[reload-jenkins]/returns: May 10, 2017 4:44:12 PM hudson.cli.CLI$5 run
Notice: /Stage[main]/Jenkins::Cli::Reload/Exec[reload-jenkins]/returns: WARNING: null
Notice: /Stage[main]/Jenkins::Cli::Reload/Exec[reload-jenkins]/returns: java.io.IOException: Stream is closed
Notice: /Stage[main]/Jenkins::Cli::Reload/Exec[reload-jenkins]/returns:         at sun.net.www.protocol.http.HttpURLConnection$StreamingOutputStream.checkError(HttpURLConnection.java:3512)
Notice: /Stage[main]/Jenkins::Cli::Reload/Exec[reload-jenkins]/returns:         at sun.net.www.protocol.http.HttpURLConnection$StreamingOutputStream.write(HttpURLConnection.java:3486)
Notice: /Stage[main]/Jenkins::Cli::Reload/Exec[reload-jenkins]/returns:         at java.io.DataOutputStream.writeInt(DataOutputStream.java:197)
Notice: /Stage[main]/Jenkins::Cli::Reload/Exec[reload-jenkins]/returns:         at hudson.cli.PlainCLIProtocol$EitherSide.send(PlainCLIProtocol.java:175)
Notice: /Stage[main]/Jenkins::Cli::Reload/Exec[reload-jenkins]/returns:         at hudson.cli.PlainCLIProtocol$ClientSide.sendEndStdin(PlainCLIProtocol.java:347)
Notice: /Stage[main]/Jenkins::Cli::Reload/Exec[reload-jenkins]/returns:         at hudson.cli.CLI$5.run(CLI.java:671)
Error: /Stage[main]/Jenkins::Cli::Reload/Exec[reload-jenkins]: Failed to call refresh: java -jar /usr/share/jenkins/jenkins-cli.jar -s http://localhost:8080 reload-configuration returned 6 instead of one of [0]
Error: /Stage[main]/Jenkins::Cli::Reload/Exec[reload-jenkins]: java -jar /usr/share/jenkins/jenkins-cli.jar -s http://localhost:8080 reload-configuration returned 6 instead of one of [0]

Can you add more documentation?

@elconas
Copy link
Contributor

elconas commented May 11, 2017

@stefanandres Hi, unfortunately this never worked with this module since jenkins 2.0 is released, as all cli commands fail for Jenkins 2.0. This is due to "secure by default", which means prior to Jenkins 2.0 jenkins was "unsecure" by default. Since 2.0 it is "full_control" per default. Howevber how can puppet use the CLI to create users if there is no bootstrapping user.

We solved this by using https://wiki.jenkins-ci.org/display/JENKINS/Configuring+Jenkins+upon+start+up and creating a init script that creates the bootstrapping user during startup. This is all in a provate module, "wrapping" rtyler/jenkins.

@stefanandres
Copy link

I rather seems the new installation without jenkins::security was in unauthentiated mode (when I used http://...:8080 I could do anything without logging in). After executing jenkins::security with full_control, it prompts me to create an initial user, but the CLI will fail (as you explained).

elconas added a commit to elconas/puppet-jenkins that referenced this issue May 11, 2017
elconas added a commit to elconas/puppet-jenkins that referenced this issue May 11, 2017
elconas added a commit to elconas/puppet-jenkins that referenced this issue May 11, 2017
@elconas
Copy link
Contributor

elconas commented May 11, 2017

@stefanandres I prepared an extended version of the pull request, adding Jenkins 2.0 bootstrapping user support (See #761). Maybe you can try this one (please see README.md in this branch for how to setup bootstrap user).

@jhoblitt How to proceed. Is there anything needed from your side for this pull request to be approved ?

@stefanandres
Copy link

Okay - the #761 fix seems to work:

classes:
  - jenkins
  - jenkins::security

jenkins_password: mypassword

jenkins::security::security_model: full_control
jenkins::cli_remoting_free: true
jenkins::cli_username: puppet
jenkins::cli_password: "%{hiera('jenkins_password')}"
jenkins::bootstrapuser_hash:
  'puppet':
    ensure: present
    email: root@localhost
    password: "%{hiera('jenkins_password')}"
    full_name: 'Puppet bootstrapping user, do not remove'
Notice: /Stage[main]/Jenkins::Security/Jenkins::Cli::Exec[jenkins-security-full_control]/Exec[jenkins-security-full_control]/returns: executed successfully

@elconas
Copy link
Contributor

elconas commented May 11, 2017

@stefanandres Nice, Great, Thanks. I also try to fix the spec.

@elconas
Copy link
Contributor

elconas commented May 11, 2017

@jhoblitt So maybe better merge #761 instead as #761 contains some tests (acceptance only) and also fixes the "sshd not enabled by default" issue on latest Jenkins Servers (needed to wort with ssh key authentication on 2.54++ and 2.46.2.++)

@stefanandres
Copy link

Okay, I won't be able to use this pull request though. When creating a bootstrap user it just wipes my securityrealm.ldap configuration from config.xml after a jenkins restart. So the entire design of creating a local user for using remote-cli won't work when using external users. :/

@elconas
Copy link
Contributor

elconas commented May 16, 2017

@stefanandres bootstrap users are only needed for local authentication mode (full_access). If you have AD / LDAP, you can use cli_username and cli_password without the bootstrap users.

@stefanandres
Copy link

stefanandres commented May 16, 2017

@elconas Thanks, but alas the module still deploys a puppet.bootstrapping.groovy file which leads to the ldap configuration being wiped upon restart.

This is the configuration I used

  class {'jenkins':
    install_java      => true,
    cli_remoting_free => true,
    cli_username      => $cli_username,
    cli_password      => $cli_password,
  }

(ldap came from augeas)

When removing the puppet.bootstrapping.groovy file before the restart (gotta be quick for this), jenkins will load fine with LDAP and even the remote CLI is working with the cli_username, cli_password.

@elconas
Copy link
Contributor

elconas commented May 16, 2017

@stefanandres I fixed the code. puppet.bootstrapping.groovy is now only created if bootstrap users is not empty. This should work with your ldap setting now.

@stefanandres
Copy link

Really appreciate your effort! Which branch is the current one that has all the fixes? https://github.com/elconas/puppet-jenkins/commits/fix_749_withbootstrapuser doesn't seem to have changes since a few days ;-)

@elconas
Copy link
Contributor

elconas commented May 17, 2017

Yes this one https://github.com/elconas/puppet-jenkins/tree/fix_749_withbootstrapuser, I always rebase and push --force :)

@stefanandres
Copy link

Ah, okay - yep, this doesn't create the bootstrap file any longer now when no user is defined

@madAndroid
Copy link
Contributor

Thank you for this! we need this with our LDAP config as well (managed via Augeas) - will be testing this out extensively, and will give feedback

madAndroid pushed a commit to madAndroid/puppet-jenkins that referenced this issue May 22, 2017
@stefanandres
Copy link

stefanandres commented Jun 6, 2017

After upgrading to the recent apt-4.1.0, the branch no longer works:

Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Evaluation Error: Error while evaluating a Resource Statement, Apt::Source[jenkins]:
  has no parameter named 'key_source'
  has no parameter named 'include_src' at /etc/puppetlabs/code/environments/pp_3875/modules/external/jenkins/manifests/repo/debian.pp:13 on node...

Can you make this compatible?

@yetanotherion
Copy link

yetanotherion commented Jun 12, 2017

FYI prefixing groovy with -remoting may provide a workaround.

java -jar cli.jar -s http://url -remoting groovy /path/to/groovy

rtyler pushed a commit that referenced this issue Jun 30, 2017
hlaf pushed a commit to hlaf/puppet-jenkins that referenced this issue Sep 17, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants