{"id":18514814,"url":"https://github.com/java-operator-sdk/kubernetes-glue-operator","last_synced_at":"2025-10-20T03:26:58.510Z","repository":{"id":231509857,"uuid":"717551196","full_name":"java-operator-sdk/kubernetes-glue-operator","owner":"java-operator-sdk","description":"Meta-operator to compose Kubernetes resources and define resource workflows","archived":false,"fork":false,"pushed_at":"2024-12-15T21:39:21.000Z","size":667,"stargazers_count":5,"open_issues_count":24,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-12-15T22:26:28.200Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/java-operator-sdk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"contributing/eclipse-google-style.xml","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-11T20:11:35.000Z","updated_at":"2024-12-15T21:21:26.000Z","dependencies_parsed_at":"2024-04-15T09:47:48.236Z","dependency_job_id":"fbee2383-9dbe-4d5a-ab73-8a061f9c024e","html_url":"https://github.com/java-operator-sdk/kubernetes-glue-operator","commit_stats":null,"previous_names":["csviri/resource-glue-operator","csviri/kubernetes-glue-operator","java-operator-sdk/kubernetes-glue-operator"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/java-operator-sdk%2Fkubernetes-glue-operator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/java-operator-sdk%2Fkubernetes-glue-operator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/java-operator-sdk%2Fkubernetes-glue-operator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/java-operator-sdk%2Fkubernetes-glue-operator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/java-operator-sdk","download_url":"https://codeload.github.com/java-operator-sdk/kubernetes-glue-operator/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247993599,"owners_count":21030043,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-06T15:45:36.899Z","updated_at":"2025-10-20T03:26:58.490Z","avatar_url":"https://github.com/java-operator-sdk.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kubernetes Glue Operator\n\nKubernetes Glue Operator is a powerful Kubernetes **meta operator** that allows you to create other **operators in a declarative** way by **simply\napplying a custom resource**. (**NOT** related to AWS Glue)\n\nIt provides facilities to compose Kubernetes resources and describes how the resource\nshould be reconciled. It supports conditional resources at runtime and ordering of resource reconciliation.\nIn other words, it also allows you to write **workflows** over resources in a **GitOps** friendly way. \n\nThe project is implemented as a thin layer on top of battle-tested [workflow](https://javaoperatorsdk.io/docs/workflows/) and [dependent resources](https://javaoperatorsdk.io/docs/dependent-resources/) features of Java Operator SDK, using [Quarkus based](https://github.com/quarkiverse/quarkus-operator-sdk) version of the framework.\n\n## Documentation\n\n[Getting started](/docs/getting-started.md)\n\n[Reference documentation](/docs/reference.md)\n\n[Rational and comparison with similar solutions](/docs/comparison.md)\n\n[Sample index](/docs/sample-index.md)\n\n## Contact Us\n\nEither in the discussion section here on GitHub, on our server [Discord](https://discord.gg/DacEhAy), or at [Kubernetes Slack Operator Channel](https://kubernetes.slack.com/archives/CAW0GV7A5). While\nin \"object\" form only placeholder substitutions are possible; in a string template, you can use all the \nfeatures of qute.\n\n## Quick Introduction\n\n### The `GlueOperator` Resource\n\nThe project introduces two Kubernetes custom resources `Glue` and `GlueOperator`.\nYou can use `GlueOperator` to define your own operator.\nLet's take a look at an example, where we define an operator for WebPage custom resource, that represents a static website served from the Cluster. (You can see the\n[full example here](https://github.com/java-operator-sdk/kubernetes-glue-operator/blob/main/src/test/resources/sample/webpage))\n\n```yaml\n\napiVersion: \"glueoperator.sample/v1\"\nkind: WebPage\nmetadata:\n  name: hellows\nspec:\n  exposed: false  # should be an ingress created or not\n  html: |  # the target html\n    \u003chtml\u003e\n      \u003chead\u003e\n        \u003ctitle\u003eHello Operator World\u003c/title\u003e\n      \u003c/head\u003e\n      \u003cbody\u003e\n        Hello World! \n      \u003c/body\u003e\n    \u003c/html\u003e\n```\n\nTo create an operator (or more precisely the controller part) with `kubernetes-glue-operator`, we first have to apply\nthe [CRD for WebPage](https://github.com/java-operator-sdk/kubernetes-glue-operator/blob/main/src/test/resources/sample/webpage/webpage.crd.yml).\nTo define how the `WebPage` should be reconciled, thus what resources should be created for\na `WebPage`, we prepare a `GlueOperator`:\n\n```yaml\napiVersion: io.javaoperatorsdk.operator.glue/v1beta1\nkind: GlueOperator\nmetadata:\n  name: webpage-operator\nspec:\n  parent:\n    apiVersion: glueoperator.sample/v1  # watches all the custom resource of type WebPage\n    kind: WebPage\n    status:  # update the status of the custom resource at the end of reconciliation\n      observedGeneration: \"{{parent.metadata.generation}}\" # since it's a non-string value needs double curly brackets \n  childResources:\n    - name: htmlconfigmap\n      resource:\n        apiVersion: v1\n        kind: ConfigMap\n        metadata:\n          name: \"{parent.metadata.name}\"  # the parent resource (target webpage instance) can be referenced as \"parent\"\n        data:\n          index.html: \"{parent.spec.html}\" # adding the html from spec to a config map\n    - name: deployment\n      resource:\n        apiVersion: apps/v1\n        kind: Deployment\n        metadata:\n          name: \"{parent.metadata.name}\"\n        spec: # details omitted\n          spec:\n            containers:\n              - name: nginx\n                image: nginx:1.17.0\n                volumeMounts:\n                  - name: html-volume\n                    mountPath: /usr/share/nginx/html\n            volumes:\n              - name: html-volume\n                configMap:\n                  name: \"{parent.metadata.name}\" # mounting the html using the config map to nginx server\n    - name: service\n      resource:\n        apiVersion: v1\n        kind: Service\n        metadata:\n          name: \"{parent.metadata.name}\"\n        spec: # Omitted details\n    - name: ingress\n      condition:\n        type: JSCondition\n        script: | # creating just ingress only if the exposed is true (this can be changed in runtime)\n          parent.spec.exposed == \"true\";\n      resource:\n        apiVersion: networking.k8s.io/v1\n        kind: Ingress\n        metadata:\n          name: \"{parent.metadata.name}\"\n      # Omitted Details\n```\n\nThere are multiple aspects to see here. The four related resources will be templated\nand applied to the cluster if such a resource is created. The reconciliation will be triggered if anything changes in the custom or child resources. \n\nNote also the `condition` part for `Ingress` resource contains multiple types of conditions, `JSCondition` is\nused in this example, which allows writing conditions in Javascript. The `Ingress` will be created if the `.spec.exposed` property\nis true. If the property is changed to `false` after, the resource is deleted.\n\n### The `Glue` Resource\n\n`Glue` is very similar to `GlueOperator`, with identical properties, except it does not have a parent. Thus, it does not define a controller, just a set of resources to reconcile. \nWhy is this useful? Note the **`dependsOn`** and **`readyPostCondition`** features, this allows you to write workflows on resources in a GitOps friendly way. Thus to make sure\nthat resources are reconciled in a certain order after some conditions are met. To understand this better, see use cases like [this](https://github.com/kubernetes/kubernetes/issues/106802) in \nKubernetes, are typically meant to be solved by `Glue`.\n\nLet's look at another example, that will show the mentioned features (available both for `Glue` and `GlueOperator`). Again, Kubernetes does not require ordering regarding how\nresources are applied, however, there are certain cases when this is needed also for Kubernetes, but especially useful when Kubernetes controllers manage external resources.\n\nThe following example shows how to deploy a [dynamic admission controller](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/) that mutates \nall the `Pods`, adding annotation on them. Note that this is a tricky situation since the endpoint for the `MutatingWebhookConfiguration` is also a `Pod`, thus 'Pods' should be \nfirst up and running before the configuration is applied, otherwise, the mutation webhook will block the changes on the pods, which would render the cluster unable to manage `Pods'.\n(Irrelevant details are omitted, see the full version [here](https://github.com/java-operator-sdk/kubernetes-glue-operator/blob/main/src/test/resources/sample/mutation/mutation.glue.yaml), \nsee the full E2E test [here](https://github.com/java-operator-sdk/kubernetes-glue-operator/blob/main/src/test/java/io/java-operator-sdk/operator/glue/sample/mutation/MutationWebhookDeploymentE2E.java))\n\n```yaml\napiVersion: io.javaoperatorsdk.operator.glue/v1beta1\nkind: Glue\nmetadata:\n  name: mutation-webhook-deployment\nspec:\n  childResources:\n    - name: service\n      resource:\n        apiVersion: v1\n        kind: Service\n        metadata:\n          name: pod-mutating-hook\n        spec:\n          # spec omitted       \n    - name: deployment  # webhook web-service endpoint\n      # ready postconditions define when a Deployment is considered \"ready\",\n      # thus up and running.\n      readyPostCondition:\n        type: ReadyCondition  \n      resource:\n        apiVersion: apps/v1\n        kind: Deployment\n        metadata:\n          name: pod-mutating-hook\n        spec:\n          replicas: 2\n          template:            \n            spec:\n              containers:              \n                  image: ghcr.io/javaoperatorsdk/sample-pod-mutating-webhook:0.1.0                  \n                  name: pod-mutating-hook\n                  ports:\n                    - containerPort: 443\n                      name: https\n                      protocol: TCP\n                        \n    - name: mutation_hook_config\n      clusterScoped: true\n      # dependsOn relation means, that the resource will be reconciled only if all\n      # the listed resources are already reconciled and ready (if ready post-condition is present).\n      # This resource will be applied after the service and deployment are applied,\n      # and the deployment is ready, thus all the pods are started up and ready.\n      dependsOn:\n        - deployment\n        - service\n      resource:\n        apiVersion: admissionregistration.k8s.io/v1\n        kind: MutatingWebhookConfiguration\n        metadata:          \n          name: pod-mutating-webhook\n        webhooks:\n          - admissionReviewVersions:\n              - v1\n            clientConfig:\n              service:\n                name: pod-mutating-hook\n                namespace: default\n                path: /mutate\n            failurePolicy: Fail\n            name: sample.mutating.webhook\n            rules:\n              - apiGroups:\n                  - \"\"\n                apiVersions:\n                  - v1\n                operations:\n                  - UPDATE\n                  - CREATE\n                resources:\n                  - pods                         \n```\n\nThe `dependsOn` relation is a useful concept in certain situations, that might be familiar from other infrustructure-as-a-code tools, `kubernetes-glue-operator` adopts it to Kubernetes operators.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjava-operator-sdk%2Fkubernetes-glue-operator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjava-operator-sdk%2Fkubernetes-glue-operator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjava-operator-sdk%2Fkubernetes-glue-operator/lists"}