Skip to content

Commit 6dc2a75

Browse files
argo-cd-sync for GitOps Runtimes (#580)
* argo-cd-sync for GitOps Runtimes * argo-cd-sync - Adding code * Adding IMAGE_NAME property * argo-cd-sync - Making it an official plugin * argo-cd-sync | Adding an example
1 parent 0eb14ee commit 6dc2a75

File tree

6 files changed

+205
-0
lines changed

6 files changed

+205
-0
lines changed

incubating/argo-cd-sync/Dockerfile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
FROM python:3.11.2-slim-buster
2+
WORKDIR /app
3+
COPY requirements.txt requirements.txt
4+
RUN pip3 install -r requirements.txt
5+
COPY queries queries/
6+
COPY argocd_sync.py run.py
7+
8+
CMD [ "python3", "run.py"]
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
from gql import Client, gql
2+
from gql.transport.requests import RequestsHTTPTransport
3+
import os
4+
5+
RUNTIME = os.getenv('RUNTIME')
6+
APPLICATION = os.getenv('APPLICATION')
7+
8+
CF_URL = os.getenv('CF_URL', 'https://g.codefresh.io')
9+
CF_API_KEY = os.getenv('CF_API_KEY')
10+
CF_STEP_NAME= os.getenv('CF_STEP_NAME', 'STEP_NAME')
11+
12+
#######################################################################
13+
14+
15+
def main():
16+
ingress_host = get_runtime_ingress_host()
17+
execute_argocd_sync(ingress_host)
18+
## Generating link to the Apps Dashboard
19+
CF_OUTPUT_URL_VAR = CF_STEP_NAME + '_CF_OUTPUT_URL'
20+
link_to_app = get_link_to_apps_dashboard()
21+
export_variable(CF_OUTPUT_URL_VAR, link_to_app)
22+
23+
24+
#######################################################################
25+
26+
def get_query(query_name):
27+
## To do: get query content from a variable, failback to a file
28+
with open('queries/'+query_name+'.graphql', 'r') as file:
29+
query_content = file.read()
30+
return gql(query_content)
31+
32+
33+
def get_runtime():
34+
transport = RequestsHTTPTransport(
35+
url = CF_URL + '/2.0/api/graphql',
36+
headers={'authorization': CF_API_KEY},
37+
verify=True,
38+
retries=3,
39+
)
40+
client = Client(transport=transport, fetch_schema_from_transport=False)
41+
query = get_query('getRuntime') ## gets gql query
42+
variables = {
43+
"runtime": RUNTIME
44+
}
45+
runtime = client.execute(query, variable_values=variables)
46+
return runtime
47+
48+
49+
def get_runtime_ingress_host():
50+
ingress_host = None
51+
runtime = get_runtime()
52+
ingress_host = runtime['runtime']['ingressHost']
53+
return ingress_host
54+
55+
56+
def get_link_to_apps_dashboard():
57+
runtime = get_runtime()
58+
runtime_ns = runtime['runtime']['metadata']['namespace']
59+
url_to_app = CF_URL+'/2.0/applications-dashboard/'+RUNTIME+'/'+runtime_ns+'/'+APPLICATION+'/timeline'
60+
return url_to_app
61+
62+
63+
def execute_argocd_sync(ingress_host):
64+
runtime_api_endpoint = ingress_host + '/app-proxy/api/graphql'
65+
transport = RequestsHTTPTransport(
66+
url=runtime_api_endpoint,
67+
headers={'authorization': CF_API_KEY},
68+
verify=True,
69+
retries=3,
70+
)
71+
client = Client(transport=transport, fetch_schema_from_transport=False)
72+
query = get_query('argocd_sync') ## gets gql query
73+
variables = {
74+
"applicationName": APPLICATION,
75+
"options": {
76+
"prune": True
77+
}
78+
}
79+
print("Syncing app: ", variables)
80+
result = client.execute(query, variable_values=variables)
81+
print(result)
82+
83+
84+
def export_variable(var_name, var_value):
85+
path = os.getenv('CF_VOLUME_PATH') if os.getenv('CF_VOLUME_PATH') != None else './'
86+
with open(path+'/env_vars_to_export', 'a') as a_writer:
87+
a_writer.write(var_name + "=" + var_value+'\n')
88+
print("Exporting variable: "+var_name+"="+var_value)
89+
90+
##############################################################
91+
92+
if __name__ == "__main__":
93+
main()
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
query sync($applicationName: String!, $options: SyncOptions) {
2+
sync(applicationName: $applicationName, options: $options) {
3+
metadata {
4+
name
5+
__typename
6+
}
7+
__typename
8+
}
9+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
query getRuntime(
2+
$runtime: String!) {
3+
runtime(name: $runtime) {
4+
metadata {
5+
name
6+
namespace
7+
}
8+
ingressHost
9+
}
10+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
backoff==2.2.1
2+
certifi==2022.12.7
3+
charset-normalizer==3.1.0
4+
gql==3.4.0
5+
graphql-core==3.2.3
6+
idna==3.4
7+
multidict==6.0.4
8+
requests==2.28.2
9+
requests-toolbelt==0.10.1
10+
urllib3==1.26.15
11+
yarl==1.8.2

incubating/argo-cd-sync/step.yaml

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
kind: step-type
2+
metadata:
3+
name: argo-cd-sync
4+
version: 0.1.0
5+
isPublic: true
6+
description: Syncs Argo CD apps managed by our GitOps Runtimes
7+
sources:
8+
- 'https://github.com/codefresh-io/steps/tree/master/incubating/argo-sync'
9+
stage: incubating
10+
maintainers:
11+
- name: Francisco Cocozza
12+
13+
categories:
14+
- GitOps
15+
official: true
16+
tags: []
17+
icon:
18+
type: svg
19+
url: https://cdn.jsdelivr.net/gh/codefresh-io/steps/graduated/argocd-sync/argo.svg
20+
background: "#f4f4f4"
21+
examples:
22+
- description: Sync an Argo CD app called "my-app" in a GitOps Runtime called "my-runtime"
23+
workflow:
24+
sync_argo_cd_app:
25+
title: Sync Argo CD app
26+
type: argo-cd-sync
27+
arguments:
28+
RUNTIME: my-runtime
29+
APPLICATION: my-app
30+
31+
spec:
32+
arguments: |-
33+
{
34+
"definitions": {},
35+
"$schema": "http://json-schema.org/draft-07/schema#",
36+
"type": "object",
37+
"additionalProperties": true,
38+
"patterns": [],
39+
"required": [
40+
"RUNTIME",
41+
"APPLICATION"
42+
],
43+
"properties": {
44+
"RUNTIME": {
45+
"type": "string",
46+
"description": "The name of the GitOps Runtime managing the Argo CD Application"
47+
},
48+
"APPLICATION": {
49+
"type": "string",
50+
"description": "The name of the Argo CD Application to be synced"
51+
},
52+
"IMAGE_NAME": {
53+
"type": "string",
54+
"default": "quay.io/codefreshplugins/argo-cd-sync",
55+
}
56+
"IMAGE_TAG": {
57+
"type": "string",
58+
"default": "0.4.0",
59+
}
60+
}
61+
}
62+
stepsTemplate: |-
63+
argo-cd-sync:
64+
image: '[[.Arguments.IMAGE_NAME]]:[[.Arguments.IMAGE_NAME]]'
65+
working_directory: /app
66+
environment:
67+
[[ range $key, $val := .Arguments ]]
68+
- '[[ $key ]]=[[ $val ]]'
69+
[[- end ]]
70+
commands:
71+
- python3 run.py
72+
delimiters:
73+
left: '[['
74+
right: ']]'

0 commit comments

Comments
 (0)