Skip to content

Commit

Permalink
feat(Gitea): add support for actions [WIP]
Browse files Browse the repository at this point in the history
  • Loading branch information
kosmoz committed Oct 18, 2023
1 parent 0a977ae commit 318f23c
Show file tree
Hide file tree
Showing 17 changed files with 415 additions and 3 deletions.
40 changes: 40 additions & 0 deletions deploy/crd/giteaactionrunners.glasskube.eu-v1.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Generated by Fabric8 CRDGenerator, manual edits might get overwritten!
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: giteaactionrunners.glasskube.eu
spec:
group: glasskube.eu
names:
kind: GiteaActionRunner
plural: giteaactionrunners
singular: giteaactionrunner
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
properties:
spec:
properties:
token:
type: string
gitea:
properties:
name:
type: string
type: object
required:
- token
- gitea
type: object
status:
properties:
ready:
type: boolean
type: object
type: object
served: true
storage: true
subresources:
status: {}
14 changes: 14 additions & 0 deletions deploy/crd/giteas.glasskube.eu-v1.yml
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,20 @@ spec:
type: string
type: object
type: object
actions:
properties:
enabled:
type: boolean
runners:
items:
properties:
token:
type: string
required:
- token
type: object
type: array
type: object
required:
- host
type: object
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package eu.glasskube.kubernetes.api.model.apps

import eu.glasskube.kubernetes.api.annotation.KubernetesDslMarker
import eu.glasskube.kubernetes.api.model.intOrString
import io.fabric8.kubernetes.api.model.apps.RollingUpdateStatefulSetStrategy
import io.fabric8.kubernetes.api.model.apps.RollingUpdateStatefulSetStrategyBuilder

@KubernetesDslMarker
class RollingUpdateStatefulSetStrategyDsl private constructor() {
private val builder = RollingUpdateStatefulSetStrategyBuilder(true)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package eu.glasskube.operator.apps.gitea

import io.fabric8.generator.annotation.Required

data class GiteaActionRunnerSpecTemplate(
@field:Required
val token: String
)

val GiteaActionRunnerSpecTemplate.tokenHash: String
get() = (token.hashCode().toLong() + Int.MAX_VALUE).toString(16)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package eu.glasskube.operator.apps.gitea

data class GiteaActionsSpec(
val enabled: Boolean = false,
val runners: List<GiteaActionRunnerSpecTemplate> = emptyList()
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import eu.glasskube.kubernetes.client.patchOrUpdateStatus
import eu.glasskube.operator.Labels
import eu.glasskube.operator.api.reconciler.informerEventSource
import eu.glasskube.operator.api.reconciler.secondaryResource
import eu.glasskube.operator.apps.gitea.dependent.GiteaActionRunners
import eu.glasskube.operator.apps.gitea.dependent.GiteaConfigMap
import eu.glasskube.operator.apps.gitea.dependent.GiteaDeployment
import eu.glasskube.operator.apps.gitea.dependent.GiteaHttpService
Expand Down Expand Up @@ -75,7 +76,8 @@ import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent
type = GiteaDeployment::class,
name = "GiteaDeployment",
dependsOn = ["GiteaPostgresCluster", "GiteaVolume", "GiteaSecret", "GiteaConfigMap", "GiteaIniConfigMap", "GiteaRedisService"],
useEventSourceWithName = GiteaReconciler.DEPLOYMENT_EVENT_SOURCE
useEventSourceWithName = GiteaReconciler.DEPLOYMENT_EVENT_SOURCE,
readyPostcondition = GiteaDeployment.ReadyCondition::class
),
Dependent(
type = GiteaHttpService::class,
Expand All @@ -96,6 +98,11 @@ import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent
type = GiteaServiceMonitor::class,
name = "GiteaServiceMonitor",
dependsOn = ["GiteaHttpService"]
),
Dependent(
type = GiteaActionRunners::class,
name = "GiteaActionRunners",
dependsOn = ["GiteaDeployment"]
)
]
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@ data class GiteaSpec(
@field:Pattern(SEMVER)
val version: String = "1.20.4",
@field:Nullable
override val database: PostgresDatabaseSpec = PostgresDatabaseSpec()
override val database: PostgresDatabaseSpec = PostgresDatabaseSpec(),
val actions: GiteaActionsSpec = GiteaActionsSpec()
) : HasDatabaseSpec<PostgresDatabaseSpec>
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package eu.glasskube.operator.apps.gitea.dependent

import eu.glasskube.kubernetes.api.model.metadata
import eu.glasskube.kubernetes.api.model.namespace
import eu.glasskube.operator.apps.gitea.Gitea
import eu.glasskube.operator.apps.gitea.GiteaActionRunnerSpecTemplate
import eu.glasskube.operator.apps.gitea.GiteaReconciler
import eu.glasskube.operator.apps.gitea.resourceLabels
import eu.glasskube.operator.apps.gitea.runner.GiteaActionRunner
import eu.glasskube.operator.apps.gitea.runner.GiteaActionRunnerSpec
import eu.glasskube.operator.apps.gitea.runner.giteaActionRunner
import eu.glasskube.operator.apps.gitea.tokenHash
import io.fabric8.kubernetes.api.model.LocalObjectReference
import io.javaoperatorsdk.operator.api.reconciler.Context
import io.javaoperatorsdk.operator.processing.dependent.BulkDependentResource
import io.javaoperatorsdk.operator.processing.dependent.Matcher
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDKubernetesDependentResource
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent

@KubernetesDependent(labelSelector = GiteaReconciler.SELECTOR)
class GiteaActionRunners :
CRUDKubernetesDependentResource<GiteaActionRunner, Gitea>(GiteaActionRunner::class.java),
BulkDependentResource<GiteaActionRunner, Gitea> {

fun desired(primary: Gitea, template: GiteaActionRunnerSpecTemplate) = giteaActionRunner {
metadata {
name = "${primary.metadata.name}-${template.tokenHash}"
namespace = primary.namespace
labels = primary.resourceLabels
}
spec = GiteaActionRunnerSpec(
template.token,
LocalObjectReference(primary.metadata.name)
)
}

override fun desiredResources(primary: Gitea, context: Context<Gitea>) = primary.spec.actions.run {
if (enabled) {
runners.map { desired(primary, it) }.associateBy { it.metadata.name }
} else {
emptyMap()
}
}

override fun getSecondaryResources(primary: Gitea, context: Context<Gitea>) =
context.getSecondaryResources(GiteaActionRunner::class.java)
.filter { it.spec.gitea.name == primary.metadata.name }
.associateBy { it.metadata.name }

override fun match(
actualResource: GiteaActionRunner,
desired: GiteaActionRunner,
primary: Gitea,
context: Context<Gitea>
): Matcher.Result<GiteaActionRunner> =
super<CRUDKubernetesDependentResource>.match(actualResource, desired, primary, context)
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import eu.glasskube.operator.apps.gitea.resourceLabelSelector
import eu.glasskube.operator.apps.gitea.resourceLabels
import eu.glasskube.operator.apps.gitea.secretName
import eu.glasskube.operator.config.ConfigService
import eu.glasskube.operator.generic.condition.DeploymentReadyCondition
import eu.glasskube.utils.addTo
import io.fabric8.kubernetes.api.model.HTTPGetAction
import io.fabric8.kubernetes.api.model.Probe
Expand All @@ -50,6 +51,7 @@ import io.javaoperatorsdk.operator.processing.event.ResourceID
class GiteaDeployment(private val configService: ConfigService) :
CRUDKubernetesDependentResource<Deployment, Gitea>(Deployment::class.java) {
internal class Discriminator : ResourceIDMatcherDiscriminator<Deployment, Gitea>({ ResourceID(it.deploymentName) })
internal class ReadyCondition : DeploymentReadyCondition<Gitea>()

override fun desired(primary: Gitea, context: Context<Gitea>) = deployment {
metadata {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class GiteaIniConfigMap : CRUDKubernetesDependentResource<ConfigMap, Gitea>(Conf
namespace = primary.metadata.namespace
labels = primary.resourceLabels
}
data = primary.baseConfig + primary.smtpConfig
data = primary.baseConfig + primary.smtpConfig + primary.actionsConfig
}

private val Gitea.baseConfig: Map<String, String>
Expand Down Expand Up @@ -78,6 +78,11 @@ class GiteaIniConfigMap : CRUDKubernetesDependentResource<ConfigMap, Gitea>(Conf
}
}

private val Gitea.actionsConfig: Map<String, String>
get() = mapOf(
"GITEA__actions__ENABLED" to spec.actions.enabled.toString()
)

override fun onUpdated(primary: Gitea, updated: ConfigMap, actual: ConfigMap, context: Context<Gitea>) {
super.onUpdated(primary, updated, actual, context)
context.getSecondaryResource(GiteaDeployment.Discriminator()).ifPresent {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package eu.glasskube.operator.apps.gitea.runner

import eu.glasskube.operator.Labels
import eu.glasskube.operator.apps.gitea.Gitea
import io.fabric8.kubernetes.api.model.Namespaced
import io.fabric8.kubernetes.client.CustomResource
import io.fabric8.kubernetes.model.annotation.Group
import io.fabric8.kubernetes.model.annotation.Version

@Group("glasskube.eu")
@Version("v1alpha1")
class GiteaActionRunner : CustomResource<GiteaActionRunnerSpec, GiteaActionRunnerStatus>(), Namespaced {
companion object {
internal const val APP_NAME = "act-runner"
internal const val APP_VERSION = "0.2.6"
internal const val APP_IMAGE = "${Gitea.APP_NAME}/act_runner:$APP_VERSION"
internal const val DOCKER_IMAGE = "docker:23.0.6-dind"
}
}

fun giteaActionRunner(block: GiteaActionRunner.() -> Unit) = GiteaActionRunner().apply(block)

internal val GiteaActionRunner.resourceLabels
get() = Labels.resourceLabels(
GiteaActionRunner.APP_NAME,
metadata.name,
Gitea.APP_NAME,
GiteaActionRunner.APP_VERSION,
GiteaActionRunner.APP_NAME
)
internal val GiteaActionRunner.resourceLabelSelector
get() = Labels.resourceLabelSelector(GiteaActionRunner.APP_NAME, metadata.name, Gitea.APP_NAME)
internal val GiteaActionRunner.genericResourceName get() = "${GiteaActionRunner.APP_NAME}-${metadata.name}"
internal val GiteaActionRunner.secretName get() = "$genericResourceName-token"
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package eu.glasskube.operator.apps.gitea.runner

import eu.glasskube.kubernetes.client.patchOrUpdateStatus
import eu.glasskube.operator.Labels
import eu.glasskube.operator.api.reconciler.getSecondaryResource
import eu.glasskube.operator.apps.gitea.Gitea
import eu.glasskube.operator.apps.gitea.runner.dependent.GiteaActionRunnerSecret
import eu.glasskube.operator.apps.gitea.runner.dependent.GiteaActionRunnerStatefulSet
import eu.glasskube.operator.generic.condition.isReady
import io.fabric8.kubernetes.api.model.apps.StatefulSet
import io.javaoperatorsdk.operator.api.reconciler.Context
import io.javaoperatorsdk.operator.api.reconciler.ControllerConfiguration
import io.javaoperatorsdk.operator.api.reconciler.Reconciler
import io.javaoperatorsdk.operator.api.reconciler.dependent.Dependent
import kotlin.jvm.optionals.getOrDefault

@ControllerConfiguration(
dependents = [
Dependent(type = GiteaActionRunnerStatefulSet::class),
Dependent(type = GiteaActionRunnerSecret::class)
]
)
class GiteaActionRunnerReconciler : Reconciler<GiteaActionRunner> {
override fun reconcile(resource: GiteaActionRunner, context: Context<GiteaActionRunner>) = with(context) {
resource.patchOrUpdateStatus(
GiteaActionRunnerStatus(
getSecondaryResource<StatefulSet>().map { it.isReady }.getOrDefault(false)
)
)
}

companion object {
internal const val SELECTOR =
"${Labels.MANAGED_BY_GLASSKUBE},${Labels.PART_OF}=${Gitea.APP_NAME},${Labels.NAME}=${GiteaActionRunner.APP_NAME}"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package eu.glasskube.operator.apps.gitea.runner

import io.fabric8.generator.annotation.Required
import io.fabric8.kubernetes.api.model.LocalObjectReference

data class GiteaActionRunnerSpec(
@field:Required
val token: String,
@field:Required
val gitea: LocalObjectReference
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package eu.glasskube.operator.apps.gitea.runner

data class GiteaActionRunnerStatus(
val ready: Boolean
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package eu.glasskube.operator.apps.gitea.runner.dependent

import eu.glasskube.kubernetes.api.model.metadata
import eu.glasskube.kubernetes.api.model.namespace
import eu.glasskube.kubernetes.api.model.secret
import eu.glasskube.operator.apps.gitea.runner.GiteaActionRunner
import eu.glasskube.operator.apps.gitea.runner.GiteaActionRunnerReconciler
import eu.glasskube.operator.apps.gitea.runner.resourceLabels
import eu.glasskube.operator.apps.gitea.runner.secretName
import eu.glasskube.utils.encodeBase64
import io.fabric8.kubernetes.api.model.Secret
import io.javaoperatorsdk.operator.api.reconciler.Context
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.CRUDKubernetesDependentResource
import io.javaoperatorsdk.operator.processing.dependent.kubernetes.KubernetesDependent

@KubernetesDependent(labelSelector = GiteaActionRunnerReconciler.SELECTOR)
class GiteaActionRunnerSecret : CRUDKubernetesDependentResource<Secret, GiteaActionRunner>(Secret::class.java) {
override fun desired(primary: GiteaActionRunner, context: Context<GiteaActionRunner>) = secret {
metadata {
name = primary.secretName
namespace = primary.namespace
labels = primary.resourceLabels
}
data = mapOf("GITEA_RUNNER_REGISTRATION_TOKEN" to primary.spec.token.encodeBase64())
}
}

0 comments on commit 318f23c

Please sign in to comment.