-
Notifications
You must be signed in to change notification settings - Fork 411
/
createTeamMasterK8s.groovy
305 lines (273 loc) · 12 KB
/
createTeamMasterK8s.groovy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
/**
Create a Managed Master on PSE using code
Notes:
1./ This script has been tested for CJE1 (Mesosphere) -Legacy
2./ For Managed Team Management see: https://go.cloudbees.com/docs/cloudbees-documentation/admin-cje/cje-ux/#_command_line_interface
**/
/*** BEGIN META {
"name" : "Create a Team Master in CloudBees Core on Modern Cloud Platform",
"comment" : "This script creates a Kubernetes Managed Master programmatically similarly to what can be done through the UI.
It has been tested with version 2.289.1.2 of CloudBees Core",
"parameters" : [],
"core": "2.289.1.2",
"authors" : [
{ name : "Allan Burdajewicz" }
]
} END META**/
import com.cloudbees.hudson.plugins.folder.AbstractFolder
import com.cloudbees.masterprovisioning.kubernetes.KubernetesImagePullSecret
import com.cloudbees.masterprovisioning.kubernetes.KubernetesMasterProvisioning
import com.cloudbees.opscenter.bluesteel.BlueSteelConstants
import com.cloudbees.opscenter.bluesteel.model.Member
import com.cloudbees.opscenter.bluesteel.model.PredefinedRecipes
import com.cloudbees.opscenter.bluesteel.model.TeamModel
import com.cloudbees.opscenter.server.bluesteel.BlueSteelHelper
import com.cloudbees.opscenter.server.bluesteel.ConnectedMasterTeamProperty
import com.cloudbees.opscenter.server.bluesteel.TeamInfo
import com.cloudbees.opscenter.server.bluesteel.TeamMasterSetupScheduler
import com.cloudbees.opscenter.server.bluesteel.security.BlueSteelDefaultRoleManager
import com.cloudbees.opscenter.server.bluesteel.security.BlueSteelSecurityUtils
import com.cloudbees.opscenter.server.bluesteel.security.xml.TeamSecurity
import com.cloudbees.opscenter.server.model.ConnectedMasterProperty
import com.cloudbees.opscenter.server.model.ConnectedMasterPropertyDescriptor
import com.cloudbees.opscenter.server.model.ManagedMaster
import com.cloudbees.opscenter.server.properties.ConnectedMasterLicenseServerProperty
import com.cloudbees.opscenter.server.properties.ConnectedMasterOwnerProperty
import hudson.Util
import hudson.model.User
import hudson.util.DescribableList
/*****************
* INPUTS *
*****************/
def teamName = "team-from-groovy"
/**
* Following attributes may be specified. The values proposed are the default from version 2.2.9 of Master Provisioning
*
* Note: If not setting properties explicitly, the defaults will be used.
*/
/* Master */
String masterDescription = ""
String masterPropertyOwners = ""
Integer masterPropertyOwnersDelay = 5
/* Master Provisioning */
Integer k8sDisk = 50
Integer k8sMemory = 3072
/**
* Since version 2.235.4.1, we recommend not using the Heap Ratio. Instead add `-XX:MinRAMPercentage` and
* `-XX:MaxRAMPercentage` to the Java options. For example, a ratio of 0.5d translate to a percentage of 50:
* `-XX:MinRAMPercentage=50.0 -XX:MaxRAMPercentage=50.0`
*
* See https://support.cloudbees.com/hc/en-us/articles/204859670-Java-Heap-settings-best-practice and
* https://docs.cloudbees.com/docs/release-notes/latest/cloudbees-ci/modern-cloud-platforms/2.235.4.1.
*/
Double k8sMemoryRatio = null
Double k8sCpus = 1
String k8sFsGroup = "1000"
Boolean k8sAllowExternalAgents = false
String k8sClusterEndpointId = "default"
String k8sEnvVars = ""
String k8sJavaOptions = "-XX:MinRAMPercentage=50.0 -XX:MaxRAMPercentage=50.0"
String k8sJenkinsOptions = ""
String k8sImage = 'CloudBees CI - Managed Master - 2.289.1.2'
List<KubernetesImagePullSecret> k8sImagePullSecrets = Collections.emptyList()
// Example:
// def k8sImagePullSecret1 = new KubernetesImagePullSecret(); k8sImagePullSecret1.setValue("useast-reg")
// List<KubernetesImagePullSecret> k8sImagePullSecrets = Arrays.asList(k8sImagePullSecret1)
Integer k8sLivenessInitialDelaySeconds = 300
Integer k8sLivenessPeriodSeconds = 10
Integer k8sLivenessTimeoutSeconds = 10
Integer k8sReadinessInitialDelaySeconds = 30
Integer k8sReadinessFailureThreshold = 100
Integer k8sReadinessTimeoutSeconds = 5
String k8sStorageClassName = ""
String k8sSystemProperties = ""
String k8sNamespace = ""
String k8sNodeSelectors = ""
Long k8sTerminationGracePeriodSeconds = 1200L
String k8sYaml = ""
/**
* cascBundle (optional). Configuration as Code Configuration Bundle
*/
String cascBundle = ""
/* Team */
String iconName = "cloudbees"
String iconNColor = "#7ac2d6"
Member [] members = [
new Member(User.current().getId(), Arrays.asList("TEAM_ADMIN")),
new Member("authenticated", Arrays.asList("TEAM_GUEST"))
// ... Add more TEAM_ADMIN, TEAM_MEMBER or TEAM_GUEST
] as Member[]
/*****************
* VALIDATION *
*****************/
/**
* Validate that the master name is not empty
*/
name = Util.fixEmpty(teamName)
if (name == null) {
println("[ERROR] A team name must be provided")
return
}
/**
* Validate that there is a "teams" folder
*/
AbstractFolder teamsFolder = jenkins.model.Jenkins.instanceOrNull.getItemByFullName(BlueSteelConstants.CJOC_TEAMS_FOLDER_NAME, AbstractFolder.class)
if (teamsFolder == null) {
println("[ERROR] Could not create the 'Teams' folder on Operations Center There may be another item which is " +
"not a folder, with the same name. No Teams can be created until this item is removed")
return
}
teamName = BlueSteelHelper.sanitizeName(name)
String teamDisplayName = name
if(BlueSteelHelper.getTeamMaster(teamName) != null) {
println("[ERROR] Another team is named that already!")
return
}
/**
* Validate there isn't any item already with the same name, only validating in the root folder where we are going to create it
*/
if (teamsFolder.getItem(teamName) != null) {
printf("The Team \"%s\" has a naming collision with an Item named \"%s\" in the folder \"%s\"", teamDisplayName, teamName,
BlueSteelConstants.CJOC_TEAMS_FOLDER_NAME)
return
}
/**********************
* PREPARE TEAM MODEL *
**********************/
/**
* Provide Team configuration (similar to what is configured through the Teams UI)
*/
TeamModel teamModel = new TeamModel()
teamModel.setName(teamName)
teamModel.setDisplayName(teamDisplayName)
teamModel.setMembers(members)
teamModel.setIcon(new TeamModel.TeamIcon(iconName, iconNColor))
teamModel.setCreationRecipe(PredefinedRecipes.BASIC)
/*****************
* CREATE MASTER *
*****************/
/**
* Create a Managed Masters with just a name (this will automatically fill required values for id, idName, grantId, etc...)
* Similar to creating an item in the UI
*/
ManagedMaster master = teamsFolder.createProject(ManagedMaster.class, teamName)
master.setDisplayName(teamModel.getDisplayName())
master.setDescription(masterDescription)
/************************
* CONFIGURATION BUNDLE *
************************/
if(cascBundle?.trim()) {
// Properties must follow this order
// Note: ConnectedMasterTokenProperty supported since 2.289.1.2. For earlier version, comment out the following.
newInstance.getProperties().replace(new com.cloudbees.opscenter.server.casc.config.ConnectedMasterTokenProperty(hudson.util.Secret.fromString(UUID.randomUUID().toString())))
// Note: ConnectedMasterCascProperty supported since 2.277.4.x. For earlier version, comment out the following.
newInstance.getProperties().replace(new com.cloudbees.opscenter.server.casc.config.ConnectedMasterCascProperty(cascBundle))
}
/********************
* CONFIGURE MASTER *
********************/
/**
* Initialize the default MasterProvisioning configuration
*/
KubernetesMasterProvisioning masterProvisioning = new KubernetesMasterProvisioning()
masterProvisioning.setDomain(teamName.toLowerCase())
/**
* Apply Managed Master provisioning configuration (similar to what is configured through the Managed Master UI)
* Note: If not setting properties explicitly, the defaults will be used.
*/
masterProvisioning.setDisk(k8sDisk)
masterProvisioning.setMemory(k8sMemory)
if(k8sMemoryRatio) {
masterProvisioning.setHeapRatio(new com.cloudbees.jce.masterprovisioning.Ratio(k8sMemoryRatio))
/**
* For versions earlier than 2.235.4.1 (Master Provisioning plugin 2.5.6), use setRatio
* masterProvisioning.setRatio(k8sMemoryRatio)
*/
}
masterProvisioning.setCpus(k8sCpus)
masterProvisioning.setFsGroup(k8sFsGroup)
masterProvisioning.setAllowExternalAgents(k8sAllowExternalAgents)
masterProvisioning.setClusterEndpointId(k8sClusterEndpointId)
masterProvisioning.setEnvVars(k8sEnvVars)
masterProvisioning.setJavaOptions(k8sJavaOptions)
masterProvisioning.setJenkinsOptions(k8sJenkinsOptions)
masterProvisioning.setImage(k8sImage)
masterProvisioning.setImagePullSecrets(k8sImagePullSecrets)
masterProvisioning.setLivenessInitialDelaySeconds(k8sLivenessInitialDelaySeconds)
masterProvisioning.setLivenessPeriodSeconds(k8sLivenessPeriodSeconds)
masterProvisioning.setLivenessTimeoutSeconds(k8sLivenessTimeoutSeconds)
masterProvisioning.setReadinessInitialDelaySeconds(k8sReadinessInitialDelaySeconds)
masterProvisioning.setReadinessFailureThreshold(k8sReadinessFailureThreshold)
masterProvisioning.setReadinessTimeoutSeconds(k8sReadinessTimeoutSeconds)
masterProvisioning.setStorageClassName(k8sStorageClassName)
masterProvisioning.setSystemProperties(k8sSystemProperties)
masterProvisioning.setNamespace(k8sNamespace)
masterProvisioning.setNodeSelectors(k8sNodeSelectors)
masterProvisioning.setTerminationGracePeriodSeconds(k8sTerminationGracePeriodSeconds)
masterProvisioning.setYaml(k8sYaml)
/**
* Save the configuration
*/
master.setConfiguration(masterProvisioning)
master.save()
/**
* Team Master required configuration
*/
// Force install the plugins we needs
BlueSteelHelper.replaceSystemProperty(master, BlueSteelConstants.IM_PLUGIN_WAR_PROFILE_PROPERTY_NAME, BlueSteelConstants.IM_PLUGIN_WAR_PROFILE)
// Force auto install of incremental updates during first boot
BlueSteelHelper.replaceSystemProperty(master, BlueSteelConstants.BK_AUTO_INTALL_INCREMENTAL_PROPERTY_NAME, Boolean.TRUE.toString())
// Disable full upgrades for this first boot or the incremental updates won't be taken into account
BlueSteelHelper.replaceSystemProperty(master, BlueSteelConstants.BK_NO_FULL_UPGRADE_PROPERTY_NAME, Boolean.TRUE.toString())
/**
* Team Master properties
*/
// Properties
DescribableList<ConnectedMasterProperty, ConnectedMasterPropertyDescriptor> masterProperties = master.getProperties()
if (masterPropertyOwners != null && !masterPropertyOwners.isEmpty()) {
masterProperties.replace(new ConnectedMasterOwnerProperty(masterPropertyOwners, masterPropertyOwnersDelay))
}
masterProperties.replace(new ConnectedMasterLicenseServerProperty(new ConnectedMasterLicenseServerProperty.DescriptorImpl().defaultStrategy()))
/**
* Team Master required property
*/
ConnectedMasterTeamProperty property = new ConnectedMasterTeamProperty()
masterProperties.replace(property)
// Set Team information
TeamInfo teamInfo = new TeamInfo(
teamModel.getName(),
teamModel.getDisplayName(),
teamModel.getIcon() != null ? new TeamInfo.TeamIcon(teamModel.getIcon()) : null,
null,
teamModel.getCreationRecipe())
property.setTeamInfo(teamInfo)
// Set Team security
TeamSecurity teamSecurity = new TeamSecurity(
BlueSteelDefaultRoleManager.getDefaultRolesMap(),
BlueSteelSecurityUtils.toUserMapping(teamModel.getMembers()),
BlueSteelDefaultRoleManager.getDefaultRole())
BlueSteelSecurityUtils.checkTeamSecurityRule(teamSecurity)
property.setTeamSecurity(teamSecurity)
/**
* Save the configuration
*/
master.save()
/**
* Retrieve the master from the API and print the details of the created Managed Master
*/
def instance = jenkins.model.Jenkins.instanceOrNull.getItemByFullName(master.fullName, ManagedMaster.class)
println "${instance.name}"
println " id: ${instance.id}"
println " idName: ${instance.idName}"
println " info: ${instance.properties.get(ConnectedMasterTeamProperty.class).getTeamInfo()}"
println " security: ${instance.properties.get(ConnectedMasterTeamProperty.class).getTeamSecurity()}"
/******************************
* PROVISION AND START MASTER *
******************************/
master.provisionAndStartAction()
println "Started the master..."
/**
* Schedule the Team Master creation and setup
*/
TeamMasterSetupScheduler.get().submitTeamSetup(master)
return