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

Feature/cid 1751 fetch and publish repos #8

Merged
merged 16 commits into from
Aug 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,16 @@ To use the Broker client with a GitLab Enterprise deployment, run `docker pull l

- `LEANIX_DOMAIN` - the LeanIX domain, obtained from your LeanIX url (example if your workspace is located at `https://my-company.leanix.net` then the domain is `my-company`).
- `LEANIX_API_TOKEN` - the LeanIX token, obtained from your admin panel. :warning: Make sure the api token has `ADMIN`rights.
- `GITLAB_TOKEN` - a [personal access token](#personal-access-token) with `api` scope.
henriqamaral marked this conversation as resolved.
Show resolved Hide resolved
- `GITLAB_URL` - the hostname of your GitLab deployment, such as `https://ghe.domain.com`. This must include the protocol (http vs https) of the GitLab deployment.

### Personal Access Token
As part of the setup the vsm-broker requires a personal access token (PAT) with according rights to run effectively. For more details on how to create the PAT, see [GitLab's documentation](https://docs.gitlab.com/16.1/ee/user/profile/personal_access_tokens.html#personal-access-token-scopes).

The following scopes are required:
Gitlab Scope | VSM Usage
------------- | -------------
`api` | To read repository data and manage the webhook on system-level

#### Command-line arguments

Expand All @@ -23,5 +32,7 @@ docker run --pull=always --restart=always \
-p 8080:8080 \
-e LEANIX_DOMAIN=<region>.leanix.net \
-e LEANIX_TECHNICAL_USER_TOKEN=<technical_user-token>\
-e GITLAB_TOKEN=<secret-gitlab-token> \
-e GITLAB_URL=<GitHub Ent URL(https://ghe.domain.com)> \
leanixacrpublic.azurecr.io/vsm-gitlab-broker
```
112 changes: 65 additions & 47 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,84 +1,102 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
id("org.springframework.boot") version "3.1.2"
id("io.spring.dependency-management") version "1.1.2"
id("io.gitlab.arturbosch.detekt") version "1.23.0"
id("org.cyclonedx.bom") version "1.7.4"
kotlin("jvm") version "1.8.21"
kotlin("plugin.spring") version "1.8.21"
id("jacoco")
id("org.springframework.boot") version "3.1.2"
id("io.spring.dependency-management") version "1.1.2"
id("io.gitlab.arturbosch.detekt") version "1.23.0"
id("org.cyclonedx.bom") version "1.7.4"
id("com.expediagroup.graphql") version "6.4.0"
kotlin("jvm") version "1.8.21"
kotlin("plugin.spring") version "1.8.21"
id("jacoco")
}

group = "net.leanix.vsm"
version = "v0.0.1"

java {
sourceCompatibility = JavaVersion.VERSION_17
sourceCompatibility = JavaVersion.VERSION_17
}

repositories {
mavenCentral()
mavenCentral()
}

val springCloudVersion: String by extra("2022.0.3")

dependencies {
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("org.springframework.boot:spring-boot-starter-oauth2-client")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.cloud:spring-cloud-starter-openfeign")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.cloud:spring-cloud-starter-contract-stub-runner")
testImplementation("org.springframework.security:spring-security-test")
testImplementation("org.awaitility:awaitility-kotlin:4.2.0")
testImplementation("com.ninja-squad:springmockk:4.0.2")
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("org.springframework.boot:spring-boot-starter-oauth2-client")
implementation("org.springframework.boot:spring-boot-starter-security")
implementation("org.springframework.boot:spring-boot-starter-validation")
implementation("org.springframework.cloud:spring-cloud-starter-openfeign")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("com.expediagroup:graphql-kotlin-spring-client:6.4.0")
implementation("io.github.oshai:kotlin-logging-jvm:5.1.0")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.cloud:spring-cloud-starter-contract-stub-runner")
testImplementation("org.springframework.security:spring-security-test")
testImplementation("org.awaitility:awaitility-kotlin:4.2.0")
testImplementation("com.ninja-squad:springmockk:4.0.2")

developmentOnly("io.netty:netty-resolver-dns-native-macos:4.1.85.Final") {
artifact {
classifier = "osx-aarch_64"
}
}
}

dependencyManagement {
imports {
mavenBom("org.springframework.cloud:spring-cloud-dependencies:$springCloudVersion")
}
imports {
mavenBom("org.springframework.cloud:spring-cloud-dependencies:$springCloudVersion")
}
}

tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "17"
}
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "17"
}
}

detekt {
autoCorrect = true
parallel = true
buildUponDefaultConfig = true
dependencies {
detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.23.0")
}}
autoCorrect = true
parallel = true
buildUponDefaultConfig = true
dependencies {
detektPlugins("io.gitlab.arturbosch.detekt:detekt-formatting:1.23.0")
}
}

tasks.cyclonedxBom {
setDestination(project.file("."))
setDestination(project.file("."))
}

tasks.test {
useJUnitPlatform()
finalizedBy(tasks.jacocoTestReport)
useJUnitPlatform()
finalizedBy(tasks.jacocoTestReport)
}

tasks.jacocoTestReport {
dependsOn(tasks.test)
reports {
xml.required.set(true)
xml.outputLocation.set(File("${project.buildDir}/jacocoXml/jacocoTestReport.xml"))
}
dependsOn(tasks.test)
reports {
xml.required.set(true)
xml.outputLocation.set(File("${project.buildDir}/jacocoXml/jacocoTestReport.xml"))
}
}

tasks.processResources {
doLast {
file("build/resources/main/gradle.properties").writeText("version=${project.version}")
}
}
doLast {
file("build/resources/main/gradle.properties").writeText("version=${project.version}")
}
}

graphql {
client {
schemaFile = file("${project.projectDir}/src/main/resources/schemas/gitlab_schema.graphql")
packageName = "net.leanix.githubbroker.connector.adapter.graphql.data"
queryFileDirectory = "${project.projectDir}/src/main/resources/queries"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package net.leanix.vsm.gitlab.broker.connector.adapter.feign

import net.leanix.vsm.gitlab.broker.connector.adapter.feign.data.CommandRequest
import net.leanix.vsm.gitlab.broker.connector.domain.CommandEventAction
import net.leanix.vsm.gitlab.broker.connector.domain.CommandProvider
import net.leanix.vsm.gitlab.broker.connector.domain.EventType
import net.leanix.vsm.gitlab.broker.connector.domain.GitLabAssignment
import org.springframework.stereotype.Component

@Component
class CommandFeignProvider(private val vsmClient: VsmClient) : CommandProvider {

override fun sendCommand(assignment: GitLabAssignment, action: CommandEventAction) {
val command = CommandRequest(
type = EventType.COMMAND.type,
action = action.action,
scope = buildScope(assignment)
)
vsmClient.sendCommand(command)
}

private fun buildScope(assignment: GitLabAssignment) =
"workspace/${assignment.workspaceId}/configuration/${assignment.configurationId}"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package net.leanix.vsm.gitlab.broker.connector.adapter.feign

import net.leanix.vsm.gitlab.broker.connector.adapter.feign.data.ServiceRequest
import net.leanix.vsm.gitlab.broker.connector.domain.EventType
import net.leanix.vsm.gitlab.broker.connector.domain.GitLabAssignment
import net.leanix.vsm.gitlab.broker.connector.domain.Repository
import net.leanix.vsm.gitlab.broker.connector.domain.RepositoryProvider
import org.springframework.stereotype.Component

@Component
class RepositoryFeignProvider(private val vsmClient: VsmClient) : RepositoryProvider {
override fun save(repository: Repository, assignment: GitLabAssignment, eventType: EventType) =
vsmClient.saveService(eventType.type, ServiceRequest.fromDomain(repository, assignment))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package net.leanix.vsm.gitlab.broker.connector.adapter.feign

import net.leanix.vsm.gitlab.broker.connector.adapter.feign.data.RunState
import net.leanix.vsm.gitlab.broker.connector.adapter.feign.data.UpdateRunStateRequest
import net.leanix.vsm.gitlab.broker.connector.domain.GitLabAssignment
import net.leanix.vsm.gitlab.broker.connector.domain.RunProvider
import net.leanix.vsm.gitlab.broker.shared.Constants.GITLAB_ENTERPRISE_CONNECTOR
import org.springframework.stereotype.Component

@Component
class RunFeignProvider(private val vsmClient: VsmClient) : RunProvider {

override fun updateRun(assignment: GitLabAssignment, runState: RunState, message: String?) {
vsmClient.updateRunState(
runId = assignment.runId,
UpdateRunStateRequest(
state = RunState.FINISHED,
workspaceId = assignment.workspaceId.toString(),
connector = GITLAB_ENTERPRISE_CONNECTOR,
orgName = assignment.connectorConfiguration.orgName,
message = message
)
)
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
package net.leanix.vsm.gitlab.broker.connector.adapter.feign

import net.leanix.vsm.gitlab.broker.connector.adapter.feign.data.CommandRequest
import net.leanix.vsm.gitlab.broker.connector.adapter.feign.data.ServiceRequest
import net.leanix.vsm.gitlab.broker.connector.adapter.feign.data.UpdateRunStateRequest
import net.leanix.vsm.gitlab.broker.connector.domain.GitLabAssignment
import net.leanix.vsm.gitlab.broker.connector.domain.GitLabHeartbeatResponse
import net.leanix.vsm.gitlab.broker.shared.Constants.EVENT_TYPE_HEADER
import net.leanix.vsm.gitlab.broker.shared.auth.adapter.feign.config.MtmFeignClientConfiguration
import org.springframework.cloud.openfeign.FeignClient
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.PutMapping
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestHeader
import org.springframework.web.bind.annotation.RequestParam
import java.util.UUID

@FeignClient(
name = "vsmClient",
Expand All @@ -20,4 +28,21 @@ interface VsmClient {

@PutMapping("/gitlab-on-prem/heartbeat")
fun heartbeat(@RequestParam("runId") runId: String): GitLabHeartbeatResponse

@PostMapping("/services")
fun saveService(
@RequestHeader(name = EVENT_TYPE_HEADER) eventType: String,
@RequestBody serviceRequest: ServiceRequest,
)

@PostMapping("/commands")
fun sendCommand(
@RequestBody commandRequest: CommandRequest,
)

@PutMapping("/run/status")
fun updateRunState(
@RequestParam("runId") runId: UUID,
@RequestBody runState: UpdateRunStateRequest,
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package net.leanix.vsm.gitlab.broker.connector.adapter.feign.data

data class CommandRequest(
val type: String,
val scope: String,
val action: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package net.leanix.vsm.gitlab.broker.connector.adapter.feign.data

import net.leanix.vsm.gitlab.broker.connector.domain.GitLabAssignment
import net.leanix.vsm.gitlab.broker.connector.domain.Language
import net.leanix.vsm.gitlab.broker.connector.domain.Repository
import net.leanix.vsm.gitlab.broker.shared.Constants
import java.util.UUID

data class ServiceRequest(
val id: String,
val runId: UUID,
val configurationId: UUID?,
val source: String,
val name: String,
val description: String?,
val url: String?,
val archived: Boolean?,
val visibility: String?,
val organizationName: String,
val languages: List<Language>? = null,
val labels: List<Tag>? = null,
val contributors: List<String>? = null
) {
companion object {
fun fromDomain(repository: Repository, assignment: GitLabAssignment) = ServiceRequest(
id = repository.id,
runId = assignment.runId,
configurationId = assignment.configurationId,
source = Constants.GITLAB_ENTERPRISE,
name = repository.name,
description = repository.description,
url = repository.url,
archived = repository.archived,
visibility = repository.visibility,
languages = repository.languages,
labels = repository.tags?.map { Tag(it, it) },
contributors = emptyList(),
organizationName = repository.groupName
)
}
}

data class Tag(
val id: String,
val name: String
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package net.leanix.vsm.gitlab.broker.connector.adapter.feign.data

import com.fasterxml.jackson.annotation.JsonIgnoreProperties

@JsonIgnoreProperties(ignoreUnknown = true)
data class UpdateRunStateRequest(
val state: RunState,
val workspaceId: String? = null,
val connector: String? = null,
val orgName: String? = null,
val message: String? = null,
val region: String? = null
)

enum class RunState {
RUNNING,
FINISHED,
}
Loading
Loading