Jenkins as a code. Часть 4

Sep 10, 2018 07:08 · 419 words · 2 minute read jenkins CI scripts

Возникла необходимость разграничения прав доступа пользователей на Jenkins-сервере - давайте разберемся, как можно это сделать без использования webUI!

В моем случае нужно разделить пользователей на две группы - администраторов (с полным уровнем доступа) и обычных пользователей (есть доступ только на просмотр списка заданий, запуск и отмену запущенных задач). Для решения этой задачи отлично подходит плагин Role-based Authorization Strategy. Главной особенностью является наличие в данном плагине двух предустановленных групп пользователей:

  • Anonymous — незалогиненные пользователи;
  • authenticated — залогиненные пользователи.

Использование группы authenticated даст возможность не перечислять всех пользователей нашего jenkins-сервера в явном виде.

Устанавливать данный плагин мы будем при старте jenkins-сервера с помощью инит-скрипта, как описано в этой статье. Для этого в скрипте 00-install-plugins.groovy список устанавливаемых плагинов приводим к следующему виду:

...
Set<String> plugins_to_install = [
    "github-pullrequest",
    "google-login",
    "workflow-aggregator",
    "htmlpublisher",
    "locale",
    "role-strategy"
]
...

Теперь создадим еще один groovy-скрипт (назовем его 06-role-based-auth.groovy) со следующим содержанием:

import hudson.*
import hudson.model.*
import hudson.security.*
import jenkins.*
import jenkins.model.*
import java.util.*
import com.michelin.cio.hudson.plugins.rolestrategy.*
import java.lang.reflect.*

// Roles
def globalRoleRead = "builder"
def globalRoleAdmin = "admin"

// Users and Groups
def access = [
    admins: [
            "admin@example.com",
            "devops@example.com",
            "ealebed@example.com"
    ],
    builders: ["authenticated"],
]

def instance = Jenkins.getInstance()
def currentAuthenticationStrategy = Hudson.instance.getAuthorizationStrategy()

Thread.start {
    sleep 15000
    if (currentAuthenticationStrategy instanceof RoleBasedAuthorizationStrategy) {
        println "Role based authorisation already enabled."
        println "Exiting script..."
        return
    } else {
        println "Enabling role based authorisation strategy..."
    }

    // Set new authentication strategy
    RoleBasedAuthorizationStrategy roleBasedAuthenticationStrategy = new RoleBasedAuthorizationStrategy()
    instance.setAuthorizationStrategy(roleBasedAuthenticationStrategy)

    Constructor[] constrs = Role.class.getConstructors()
    for (Constructor<?> c : constrs) {
        c.setAccessible(true)
    }

    // Make the method assignRole accessible
    Method assignRoleMethod = RoleBasedAuthorizationStrategy.class.getDeclaredMethod("assignRole", String.class, Role.class, String.class)
    assignRoleMethod.setAccessible(true)

    // Create admin set of permissions
    Set<Permission> adminPermissions = new HashSet<Permission>()
    adminPermissions.add(Permission.fromId("hudson.model.Hudson.Administer"))
    adminPermissions.add(Permission.fromId("hudson.model.Hudson.Read"))
    adminPermissions.add(Permission.fromId("com.cloudbees.plugins.credentials.CredentialsProvider.View"))
    adminPermissions.add(Permission.fromId("com.cloudbees.plugins.credentials.CredentialsProvider.ManageDomains"))
    adminPermissions.add(Permission.fromId("com.cloudbees.plugins.credentials.CredentialsProvider.Create"))
    adminPermissions.add(Permission.fromId("com.cloudbees.plugins.credentials.CredentialsProvider.Update"))
    adminPermissions.add(Permission.fromId("com.cloudbees.plugins.credentials.CredentialsProvider.Delete"))
    adminPermissions.add(Permission.fromId("hudson.model.View.Read"))
    adminPermissions.add(Permission.fromId("hudson.model.View.Create"))
    adminPermissions.add(Permission.fromId("hudson.model.View.Configure"))
    adminPermissions.add(Permission.fromId("hudson.model.View.Delete"))
    adminPermissions.add(Permission.fromId("hudson.model.Item.Read"))
    adminPermissions.add(Permission.fromId("hudson.model.Item.Discover"))
    adminPermissions.add(Permission.fromId("hudson.model.Item.Workspace"))
    adminPermissions.add(Permission.fromId("hudson.model.Item.Create"))
    adminPermissions.add(Permission.fromId("hudson.model.Item.Move"))
    adminPermissions.add(Permission.fromId("hudson.model.Item.Configure"))
    adminPermissions.add(Permission.fromId("hudson.model.Item.Build"))
    adminPermissions.add(Permission.fromId("hudson.model.Item.Cancel"))
    adminPermissions.add(Permission.fromId("hudson.model.Item.Delete"))
    adminPermissions.add(Permission.fromId("hudson.model.Computer.Create"))
    adminPermissions.add(Permission.fromId("hudson.model.Computer.Connect"))
    adminPermissions.add(Permission.fromId("hudson.model.Computer.Configure"))
    adminPermissions.add(Permission.fromId("hudson.model.Computer.Build"))
    adminPermissions.add(Permission.fromId("hudson.model.Computer.Provision"))
    adminPermissions.add(Permission.fromId("hudson.model.Computer.Disconnect"))
    adminPermissions.add(Permission.fromId("hudson.model.Computer.Delete"))
    adminPermissions.add(Permission.fromId("hudson.model.Run.Update"))
    adminPermissions.add(Permission.fromId("hudson.model.Run.Replay"))
    adminPermissions.add(Permission.fromId("hudson.model.Run.Delete"))
    adminPermissions.add(Permission.fromId("hudson.scm.SCM.Tag"))

    // Create permissions for authenticated users
    Set<Permission> authenticatedPermissions = new HashSet<Permission>()
    authenticatedPermissions.add(Permission.fromId("hudson.model.Hudson.Read"))
    authenticatedPermissions.add(Permission.fromId("hudson.model.View.Read"))
    authenticatedPermissions.add(Permission.fromId("hudson.model.Item.Read"))
    authenticatedPermissions.add(Permission.fromId("hudson.model.Item.Build"))
    authenticatedPermissions.add(Permission.fromId("hudson.model.Item.Cancel"))

    // Create the admin role
    Role adminRole = new Role(globalRoleAdmin, adminPermissions)
    roleBasedAuthenticationStrategy.addRole(RoleBasedAuthorizationStrategy.GLOBAL, adminRole)

    // Create the builder role
    Role builderRole = new Role(globalRoleRead, authenticatedPermissions)
    roleBasedAuthenticationStrategy.addRole(RoleBasedAuthorizationStrategy.GLOBAL, builderRole)

    // Assign the admin role
    access.admins.each { l ->
        println("Granting admin permissions to ${l}")
        roleBasedAuthenticationStrategy.assignRole(RoleBasedAuthorizationStrategy.GLOBAL, adminRole, l)
    }

    access.builders.each { l ->
        println("Granting builder permissions to ${l}")
        roleBasedAuthenticationStrategy.assignRole(RoleBasedAuthorizationStrategy.GLOBAL, builderRole, l)
    }

    // Save the state
    println "Saving changes."
    instance.save()
}

С помощью данного скрипта создаются две роли - builder и admin, которым устанавливаются разные наборы прав доступа. Далее всем пользователям, перечисленным в access.admins, назначается роль admin, а группе authenticated (находится в access.builders) назначается роль builder.

tweet Share