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

Add Openshift appDomain in Quickstarter Pipeline context #1078

Merged
merged 52 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
1bcd2f1
add ocp domain in qs pipeline
BraisVQ Mar 11, 2024
86b0a9b
restore missing
BraisVQ Mar 11, 2024
d6fc194
remove return
BraisVQ Mar 11, 2024
f1b8046
test with set app domain
BraisVQ Mar 11, 2024
669bd4d
use set function only
BraisVQ Mar 11, 2024
86a48e7
clean code
BraisVQ Mar 11, 2024
c198351
codenarc
BraisVQ Mar 11, 2024
993be7d
update tests
BraisVQ Mar 11, 2024
bc2789f
fix tests
BraisVQ Mar 11, 2024
fa3ea78
fix tests
BraisVQ Mar 11, 2024
91f0330
Merge branch 'master' into feature/ocp-domain-quickstarter-pipeline
BraisVQ Mar 28, 2024
b3f0a7e
test wmoving the logic to pipeline
BraisVQ Apr 2, 2024
b5ea371
imported steps
BraisVQ Apr 2, 2024
9d2d59a
move to node
BraisVQ Apr 2, 2024
a22ad32
move to script.node
BraisVQ Apr 2, 2024
9f19251
typo
BraisVQ Apr 2, 2024
7cbbbd2
clean code and use function
BraisVQ Apr 2, 2024
fcb9f6b
restore test
BraisVQ Apr 2, 2024
10bac02
Merge branch 'feature/ocp-domain-quickstarter-pipeline' of https://gi…
BraisVQ Apr 2, 2024
b6dcd37
clean
BraisVQ Apr 2, 2024
212d51f
test with whoami command instead of route creation to get domain
BraisVQ Apr 4, 2024
a585399
test with output
BraisVQ Apr 4, 2024
f7bb245
clean code
BraisVQ Apr 5, 2024
8aa2a97
modify route and prefix
BraisVQ Apr 5, 2024
e21841f
remove static for debuging
BraisVQ Apr 5, 2024
e98ce64
added split
BraisVQ Apr 5, 2024
526b541
fix
BraisVQ Apr 5, 2024
3d8ec1a
double split
BraisVQ Apr 5, 2024
3e03073
test split
BraisVQ Apr 5, 2024
17a0339
test
BraisVQ Apr 5, 2024
93b91cf
separe oc into a separate method, use indexOf
BraisVQ Apr 5, 2024
45edce7
test
BraisVQ Apr 5, 2024
822d358
remove char convert
BraisVQ Apr 5, 2024
6967975
add trim
BraisVQ Apr 5, 2024
aae16fc
adapt to updated service methof
BraisVQ Apr 5, 2024
975deed
CodeNarc fix
BraisVQ Apr 5, 2024
518650b
Update CHANGELOG.md
BraisVQ Apr 9, 2024
7c887e1
Use same methods when getting OCP domain across the library
BraisVQ Apr 15, 2024
69c5bf0
rename methof
BraisVQ Apr 15, 2024
bf31f90
Check route when getting it
BraisVQ Apr 15, 2024
957744c
Merge branch 'feature/ocp-domain-quickstarter-pipeline' of https://gi…
BraisVQ Apr 15, 2024
47b41ab
Fix trim and adjust error message
BraisVQ Apr 16, 2024
60abd45
added tests for the changes in Openshift service
BraisVQ Apr 16, 2024
ee55156
clean test
BraisVQ Apr 16, 2024
193ee8c
added tests for openshift domain
BraisVQ Apr 17, 2024
2dc7bc0
Update tests
BraisVQ Apr 17, 2024
411ac22
uncomment tests
BraisVQ Apr 17, 2024
090efed
codeNarc
BraisVQ Apr 17, 2024
fa79c42
fix test
BraisVQ Apr 17, 2024
287e412
test without to string
BraisVQ Apr 18, 2024
8ecfc80
update method in context and tests
BraisVQ Apr 18, 2024
62bcdd2
added import
BraisVQ Apr 18, 2024
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

* Fix Tailor deployment drifts for D, Q envs ([#1055](https://github.com/opendevstack/ods-jenkins-shared-library/pull/1055))
* Update api version in ocp templates for image, buildconfig, route and deploymentconfig ([#1072](https://github.com/opendevstack/ods-jenkins-shared-library/issues/1072))
* Add Openshift appDomain context value in Quickstarter pipeline, optimize the way to get appDomain from cluster ([#997](https://github.com/opendevstack/ods-quickstarters/issues/997))
* Fix excessive number of Api calls to Jira to retrieve the last document version ([#654](https://github.com/opendevstack/ods-jenkins-shared-library/issues/654))

## [4.3.4] - 2024-02-20
Expand Down
19 changes: 8 additions & 11 deletions src/org/ods/component/Context.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package org.ods.component

import org.ods.util.ShellWithRetry
import org.ods.util.Logger
import org.ods.services.ServiceRegistry
import org.ods.services.BitbucketService
import org.ods.services.GitService
import org.ods.services.NexusService
Expand All @@ -11,6 +10,8 @@ import com.cloudbees.groovy.cps.NonCPS
import groovy.json.JsonSlurperClassic
import groovy.json.JsonOutput
import java.util.concurrent.ExecutionException
import org.ods.util.IPipelineSteps
import org.ods.util.PipelineSteps

@SuppressWarnings(['MethodCount', 'UnnecessaryObjectReferences'])
class Context implements IContext {
Expand All @@ -23,6 +24,7 @@ class Context implements IContext {
private final def script
// config is a map of config properties to customise the behaviour.
private final Map config
private final IPipelineSteps steps
private final Logger logger
// artifact store, the interface to MRP
private final def artifactUriStore = [builds: [:], deployments: [:]]
Expand All @@ -37,6 +39,7 @@ class Context implements IContext {
this.config = config
this.logger = logger
this.localCheckoutEnabled = localCheckoutEnabled
this.steps = new PipelineSteps(script)
}

def assemble() {
Expand Down Expand Up @@ -571,17 +574,11 @@ class Context implements IContext {
}

String getOpenshiftApplicationDomain () {
if (!config.environment) {
logger.debug('Could not get application domain, as no environment is available')
return ''
}
if (!this.appDomain) {
logger.startClocked("${config.componentId}-get-oc-app-domain")
this.appDomain = ServiceRegistry.instance.get(OpenShiftService).
getApplicationDomain(config.targetProject)
logger.debugClocked("${config.componentId}-get-oc-app-domain")
def appDomain = appDomain
if (!appDomain) {
this.appDomain = appDomain = OpenShiftService.getApplicationDomain(steps)
}
this.appDomain
return appDomain
}

// set the rollout retry
Expand Down
2 changes: 1 addition & 1 deletion src/org/ods/component/ScanWithTrivyStage.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class ScanWithTrivyStage extends Stage {
String errorMessages = ''
int returnCode = scanViaCli(options.scanners, options.vulType, options.format,
options.additionalFlags, options.reportFile, options.nexusDataBaseRepository,
openShift.getApplicationDomain(context.cdProject))
openShift.getApplicationDomain())
if ([TrivyService.TRIVY_SUCCESS].contains(returnCode)) {
try {
URI reportUriNexus = archiveReportInNexus(options.reportFile, options.nexusReportRepository)
Expand Down
5 changes: 5 additions & 0 deletions src/org/ods/quickstarter/Context.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -145,4 +145,9 @@ class Context implements IContext {
config.odsGitRef
}

@NonCPS
String getAppDomain() {
config.appDomain
}

}
3 changes: 3 additions & 0 deletions src/org/ods/quickstarter/IContext.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,7 @@ interface IContext {
// alias for odsGitRef
String getGitBranch()

// get app domain of the Openshift cluster
String getAppDomain()

}
15 changes: 10 additions & 5 deletions src/org/ods/quickstarter/Pipeline.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@ package org.ods.quickstarter

import org.ods.services.BitbucketService
import org.ods.services.NexusService

import org.ods.util.Logger
import org.ods.util.ILogger
import org.ods.services.OpenShiftService
import org.ods.util.IPipelineSteps
import org.ods.util.PipelineSteps

class Pipeline implements Serializable {

private final def script
private final Map config
private final ILogger logger
private final IPipelineSteps steps

Pipeline(def script, Map config) {
this.script = script
this.config = config
this.logger = new Logger(script, false)
this.steps = new PipelineSteps(script)
}

@SuppressWarnings(['AbcMetric', 'UnnecessaryObjectReferences'])
Expand Down Expand Up @@ -99,6 +99,10 @@ class Pipeline implements Serializable {
}
}

private initappDomain() {
config.appDomain = OpenShiftService.getApplicationDomain(steps)
}

private onAgentNode(Map config, Closure block) {
if (!config.podContainers) {
if (!config.containsKey('alwaysPullImage')) {
Expand Down Expand Up @@ -148,6 +152,7 @@ class Pipeline implements Serializable {
annotations: config.annotations,
) {
script.node(podLabel) {
initappDomain()
IContext context = new Context(config)
block(context)
}
Expand Down
2 changes: 1 addition & 1 deletion src/org/ods/quickstarter/RenderJenkinsfileStage.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class RenderJenkinsfileStage extends Stage {
def target = "${context.targetDir}/${config.target}"
script.sh(
script: """
sed 's|@project_id@|${context.projectId}|g; s|@component_id@|${context.componentId}|g; s|@component_type@|${context.sourceDir}|g; s|@git_url_http@|${context.gitUrlHttp}|g; s|@ods_namespace@|${context.odsNamespace}|g; s|@ods_image_tag@|${context.odsImageTag}|g; s|@ods_git_ref@|${context.odsGitRef}|g; s|@agent_image_tag@|${context.agentImageTag}|g; s|@shared_library_ref@|${context.sharedLibraryRef}|g' ${source} > ${target}
sed 's|@project_id@|${context.projectId}|g; s|@component_id@|${context.componentId}|g; s|@component_type@|${context.sourceDir}|g; s|@git_url_http@|${context.gitUrlHttp}|g; s|@ods_namespace@|${context.odsNamespace}|g; s|@ods_image_tag@|${context.odsImageTag}|g; s|@ods_git_ref@|${context.odsGitRef}|g; s|@agent_image_tag@|${context.agentImageTag}|g; s|@shared_library_ref@|${context.sharedLibraryRef}|g; s|@app_domain@|${context.appDomain}|g' ${source} > ${target}
""",
label: "Render '${config.source}' to '${config.target}'"
)
Expand Down
54 changes: 24 additions & 30 deletions src/org/ods/services/OpenShiftService.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import org.ods.util.ILogger
import org.ods.util.IPipelineSteps
import org.ods.util.PodData

import java.security.SecureRandom

@SuppressWarnings(['ClassSize', 'MethodCount'])
@TypeChecked
class OpenShiftService {
Expand Down Expand Up @@ -51,6 +49,18 @@ class OpenShiftService {
).toString().trim()
}

static String getConsoleUrl(IPipelineSteps steps) {
String routeUrl = steps.sh(
script: 'oc whoami --show-console',
label: 'Get OpenShift Console URL',
returnStdout: true
)
if (!routeUrl) {
throw new RuntimeException ("Cannot get cluster console url!")
}
return routeUrl.trim()
}

static boolean tooManyEnvironments(IPipelineSteps steps, String projectId, Integer limit) {
steps.sh(
returnStdout: true,
Expand All @@ -69,30 +79,15 @@ class OpenShiftService {
exists
}

static String getApplicationDomainOfProject(IPipelineSteps steps, String project) {
if (!envExists(steps, project)) {
String currentClusterUrl = getApiUrl(steps)
throw new IOException ("OCP project ${project} on server ${currentClusterUrl}" +
' does not exist - cannot create route to retrieve host / domain name!' +
' If this is needed, please create project on cluster!')
static String getApplicationDomain(IPipelineSteps steps) {
def routeUrl = getConsoleUrl(steps)

def routePrefixLength = routeUrl.indexOf('.')
if (routePrefixLength < 0) {
throw new RuntimeException ("Route does not contain a dot: ${routeUrl}")
}
def routeName = 'test-route-' + (System.currentTimeMillis() +
new SecureRandom().nextInt(1000))
steps.sh (
script: "oc -n ${project} create route edge ${routeName} --service=dummy --port=80 | true",
label: "create dummy route for extraction (${routeName})"
)
def routeUrl = steps.sh (
script: "oc -n ${project} get route ${routeName} -o jsonpath='{.spec.host}'",
returnStdout: true,
label: 'get cluster route domain'
).toString().trim()
def routePrefixLength = "${routeName}-${project}".length() + 1
def openShiftPublicHost = routeUrl[routePrefixLength..-1]
steps.sh (
script: "oc -n ${project} delete route ${routeName} | true",
label: "delete dummy route for extraction (${routeName})"
)

def openShiftPublicHost = routeUrl[routePrefixLength+1..-1]
return openShiftPublicHost
}

Expand Down Expand Up @@ -168,7 +163,7 @@ class OpenShiftService {
def excludeFlag = target.exclude ? "--exclude ${target.exclude}" : ''
def includeArg = target.include ?: ''
def paramFileFlag = paramFile ? "--param-file ${paramFile}" : ''
params << "ODS_OPENSHIFT_APP_DOMAIN=${getApplicationDomain(project)}".toString()
params << "ODS_OPENSHIFT_APP_DOMAIN=${getApplicationDomain()}".toString()
def paramFlags = params.collect { "--param ${it}" }.join(' ')
def preserveFlags = preserve.collect { "--preserve ${it}" }.join(' ')
doTailorApply(project, "${selectorFlag} ${excludeFlag} ${paramFlags} ${preserveFlags} ${paramFileFlag} ${tailorPrivateKeyFlag} ${verifyFlag} --ignore-unknown-parameters ${includeArg}")
Expand Down Expand Up @@ -474,8 +469,8 @@ class OpenShiftService {
m
}

String getApplicationDomain(String project) {
getApplicationDomainOfProject(steps, project)
String getApplicationDomain() {
getApplicationDomain(steps)
}

// imageInfoForImageUrl expects an image URL like one of the following:
Expand Down Expand Up @@ -1304,7 +1299,6 @@ class OpenShiftService {
} catch (ex) {
throw new TailorDeploymentException(ex)
}

}

private void doTailorExport(
Expand Down Expand Up @@ -1338,7 +1332,7 @@ class OpenShiftService {
}

// Replace values from envParams with parameters, and add parameters into template.
envParams['ODS_OPENSHIFT_APP_DOMAIN'] = getApplicationDomain(project)
envParams['ODS_OPENSHIFT_APP_DOMAIN'] = getApplicationDomain()
def templateParams = ''
def sedReplacements = ''
envParams.each { key, val ->
Expand Down
17 changes: 17 additions & 0 deletions test/groovy/org/ods/component/ContextSpec.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import org.ods.PipelineScript
import org.ods.util.ILogger
import org.ods.util.Logger
import org.ods.util.ShellWithRetry
import org.ods.util.IPipelineSteps
import spock.lang.*
import org.ods.services.OpenShiftService

class ContextSpec extends Specification {

Expand Down Expand Up @@ -154,4 +156,19 @@ class ContextSpec extends Specification {
uut.determineEnvironment()
}

def "get openshift cluster domain"() {
given:
def steps = Stub(IPipelineSteps)
GroovySpy(OpenShiftService, constructorArgs: [steps, new Logger(steps, false)], global: true)
def context = new Context(steps, null, logger)
def expectedDomain = 'apps.openshift.com'
OpenShiftService.getApplicationDomain(_) >> expectedDomain

when:
def domain = context.getOpenshiftApplicationDomain()

then:
domain == expectedDomain
}

}
59 changes: 59 additions & 0 deletions test/groovy/org/ods/services/OpenShiftServiceSpec.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -566,4 +566,63 @@ class OpenShiftServiceSpec extends SpecHelper {
'Deployment' | 'rs'
}

def "getConsoleUrl from cluster"() {
given:
def steps = Stub(IPipelineSteps)
def service = new OpenShiftService(steps, new Logger(steps, false))
def routeUrl = 'https://console-openshift-console.apps.openshift.com'
steps.sh( { it.script == 'oc whoami --show-console' } ) >> routeUrl

when:
def result = service.getConsoleUrl(steps)

then:
result == routeUrl
}

@Unroll
def "getConsoleUrl from cluster if null or empty"() {
given:
def steps = Stub(IPipelineSteps)
def service = new OpenShiftService(steps, new Logger(steps, false))
steps.sh(_) >> routeUrl

when:
def result = service.getConsoleUrl(steps)

then:
thrown(RuntimeException)

where:
routeUrl << [null, '']
}

def "getApplicationDomain from consoleUrl"() {
given:
def steps = Stub(IPipelineSteps)
GroovySpy(OpenShiftService, constructorArgs: [steps, new Logger(steps, false)], global: true)
def routeUrl = 'https://console-openshift-console.apps.openshift.com'
def expectedDomain = "apps.openshift.com"
OpenShiftService.getConsoleUrl(_) >> routeUrl

when:
def domain = OpenShiftService.getApplicationDomain(steps)

then:
domain == expectedDomain
}

def "getApplicationDomain from consoleUrl if no dot"() {
given:
def steps = Stub(IPipelineSteps)
GroovySpy(OpenShiftService, constructorArgs: [steps, new Logger(steps, false)], global: true)
def routeUrl = 'https://console-openshift-console-apps-openshift-com'
OpenShiftService.getConsoleUrl(_) >> routeUrl

when:
def domain = OpenShiftService.getApplicationDomain(steps)

then:
thrown(RuntimeException)
}
}