mirror of
https://github.com/tektoncd/catalog.git
synced 2024-11-22 06:02:51 +00:00
Add github app token 0.2
Added a new params to allow getting the application_id from the secrets workspace, still allowing as params directly if user would like to use this instead. Signed-off-by: Chmouel Boudjnah <chmouel@redhat.com>
This commit is contained in:
parent
94aede7853
commit
0a59b634f7
9
task/github-app-token/0.2/Dockerfile
Normal file
9
task/github-app-token/0.2/Dockerfile
Normal file
@ -0,0 +1,9 @@
|
||||
FROM python:3.8-alpine as build
|
||||
RUN apk update && apk upgrade && pip install -U pip && \
|
||||
apk add --update alpine-sdk make gcc python3-dev libffi-dev openssl-dev \
|
||||
&& rm -rf /var/cache/apk/*
|
||||
RUN pip --no-cache-dir install requests jwcrypto
|
||||
|
||||
FROM python:3.8-alpine
|
||||
COPY --from=build /usr/local/share /usr/local/share
|
||||
COPY --from=build /usr/local/lib /usr/local/lib
|
42
task/github-app-token/0.2/README.md
Normal file
42
task/github-app-token/0.2/README.md
Normal file
@ -0,0 +1,42 @@
|
||||
# GitHub app token
|
||||
|
||||
A task to get a user token from a github application
|
||||
|
||||
## Workspaces
|
||||
|
||||
- **secrets**: A workspace containing the private key of the application.
|
||||
|
||||
## Secret
|
||||
|
||||
This GitHub applications needs a private key to sign your request with JWT.
|
||||
|
||||
[This](../0.2/samples/secret.yaml) example can be referred to create the secret
|
||||
|
||||
Refer [this](https://docs.aws.amazon.com/sdk-for-java/v1/developer-guide/setup-credentials.html) guide for setting up AWS Credentials and Region.
|
||||
|
||||
|
||||
## Params
|
||||
|
||||
* **installation_id:** The GitHub app installation ID _eg:_ `123456`
|
||||
* **application_id:** The GitHub application ID. _e.g:_ `123456`
|
||||
* **private_key_path:** The path to the key inside the secret workspace, _default:_
|
||||
`private.key`
|
||||
* **application_id_path:** The path to installation_id inside the secret workspace, it will use it if it can find it or use the params.application_id instead, _default:_ `application_id_path`
|
||||
|
||||
* **token_expiration_minutes:**: The time to expirations of the token in minutes _default:_ `10`
|
||||
|
||||
|
||||
### Install the Task
|
||||
|
||||
```
|
||||
kubectl apply -f https://raw.githubusercontent.com/tektoncd/catalog/main/task/github-app-token/0.2/github-app-token.yaml
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
After creating the task with the parameters, you should have the token as result in the task which can
|
||||
be used in your pipeline to do github operations from the app as the target user.
|
||||
|
||||
See [this](../0.2/samples/run.yaml) taskrun example on how to start the task directly.
|
||||
|
159
task/github-app-token/0.2/github-app-token.yaml
Normal file
159
task/github-app-token/0.2/github-app-token.yaml
Normal file
@ -0,0 +1,159 @@
|
||||
# TODO: Submit this in catalog upstream
|
||||
---
|
||||
apiVersion: tekton.dev/v1beta1
|
||||
kind: Task
|
||||
metadata:
|
||||
name: github-app-token
|
||||
labels:
|
||||
app.kubernetes.io/version: "0.2"
|
||||
annotations:
|
||||
tekton.dev/pipelines.minVersion: "0.12.1"
|
||||
tekton.dev/tags: github
|
||||
tekton.dev/displayName: "github app token"
|
||||
spec:
|
||||
description: >-
|
||||
Retrive a user token from a GitHub application
|
||||
|
||||
This task will get a user token for an installation_id for a GitHub application.
|
||||
This could be then reuse to do user operations.
|
||||
|
||||
workspaces:
|
||||
- name: secrets
|
||||
|
||||
results:
|
||||
- name: token
|
||||
description: The user token to use.
|
||||
|
||||
params:
|
||||
- name: installation_id
|
||||
description: The installation id for the GitHub application to request a token for.
|
||||
type: string
|
||||
|
||||
- name: application_id
|
||||
description: The application id for the GitHub application to request a token for.
|
||||
type: string
|
||||
default: ""
|
||||
|
||||
- name: private_key_path
|
||||
description: The key path inside the secret workspace
|
||||
type: string
|
||||
default: "private.key"
|
||||
|
||||
- name: application_id_path
|
||||
description: The path for the application id inside the secret workspace
|
||||
type: string
|
||||
default: "application_id"
|
||||
|
||||
- name: token_expiration_minutes
|
||||
description: Token expiration time in minutes
|
||||
type: string
|
||||
default: "10"
|
||||
|
||||
steps:
|
||||
- name: get-token
|
||||
image: quay.io/chmouel/github-app-token@sha256:bc45937ae588df876555ebb56c36350ed74592c7f55f2df255cabef39c926a88
|
||||
env:
|
||||
- name: GITHUBAPP_KEY_PATH
|
||||
value: $(workspaces.secrets.path)/$(params.private_key_path)
|
||||
- name: GITHUBAPP_APP_ID_PATH
|
||||
value: $(workspaces.secrets.path)/$(params.application_id_path)
|
||||
- name: GITHUBAPP_APP_ID
|
||||
value: $(params.application_id)
|
||||
- name: GITHUBAPP_INSTALLATION_ID
|
||||
value: $(params.installation_id)
|
||||
- name: GITHUBAPP_TOKEN_EXPIRATION_MINUTES
|
||||
value: $(params.token_expiration_minutes)
|
||||
- name: GITHUBAPP_RESULT_PATH
|
||||
value: $(results.token.path)
|
||||
script: |
|
||||
#!/usr/bin/env python3
|
||||
import json
|
||||
import os
|
||||
import time
|
||||
|
||||
import requests
|
||||
from jwcrypto import jwk, jwt
|
||||
|
||||
EXPIRE_MINUTES_AS_SECONDS = int(os.environ.get('GITHUBAPP_TOKEN_EXPIRATION_MINUTES', 10)) * 60
|
||||
# TODO support github enteprise
|
||||
GITHUB_API_URL = "https://api.github.com"
|
||||
|
||||
|
||||
class GitHub():
|
||||
token = None
|
||||
|
||||
def __init__(self, private_key, app_id=None, installation_id=None):
|
||||
if not isinstance(private_key, bytes):
|
||||
raise ValueError(f'"{private_key}" parameter must be byte-string')
|
||||
self._private_key = private_key
|
||||
self.app_id = app_id
|
||||
self.token = self._get_token(installation_id)
|
||||
|
||||
def _load_private_key(self, pem_key_bytes):
|
||||
return jwk.JWK.from_pem(pem_key_bytes)
|
||||
|
||||
def _app_token(self, expire_in=EXPIRE_MINUTES_AS_SECONDS):
|
||||
key = self._load_private_key(self._private_key)
|
||||
now = int(time.time())
|
||||
token = jwt.JWT(
|
||||
header={"alg": "RS256"},
|
||||
claims={
|
||||
"iat": now,
|
||||
"exp": now + expire_in,
|
||||
"iss": self.app_id
|
||||
},
|
||||
algs=["RS256"],
|
||||
)
|
||||
token.make_signed_token(key)
|
||||
return token.serialize()
|
||||
|
||||
def _get_token(self, installation_id=None):
|
||||
app_token = self._app_token()
|
||||
if not installation_id:
|
||||
return app_token
|
||||
|
||||
req = self._request(
|
||||
"POST",
|
||||
f"/app/installations/{installation_id}/access_tokens",
|
||||
headers={
|
||||
"Authorization": f"Bearer {app_token}",
|
||||
"Accept": "application/vnd.github.machine-man-preview+json"
|
||||
})
|
||||
|
||||
ret = req.json()
|
||||
if 'token' not in ret:
|
||||
raise Exception("Authentication errors")
|
||||
|
||||
return ret['token']
|
||||
|
||||
def _request(self, method, url, headers={}, data={}):
|
||||
if self.token and 'Authorization' not in headers:
|
||||
headers.update({"Authorization": "Bearer " + self.token})
|
||||
if not url.startswith("http"):
|
||||
url = f"{GITHUB_API_URL}{url}"
|
||||
return requests.request(method,
|
||||
url,
|
||||
headers=headers,
|
||||
data=json.dumps(data))
|
||||
|
||||
|
||||
def main():
|
||||
with open(os.environ['GITHUBAPP_KEY_PATH'], 'rb') as key_file:
|
||||
key = key_file.read()
|
||||
|
||||
if os.path.exists(os.environ['GITHUBAPP_APP_ID_PATH']):
|
||||
app_id = open(os.environ['GITHUBAPP_APP_ID_PATH']).read()
|
||||
elif os.environ.get('GITHUBAPP_APP_ID'):
|
||||
app_id = os.environ['GITHUBAPP_APP_ID']
|
||||
else:
|
||||
raise Exception("application id is not set")
|
||||
|
||||
print(f"Getting user token for application_id: {app_id}")
|
||||
github_app = GitHub(
|
||||
key,
|
||||
app_id=app_id,
|
||||
installation_id=os.environ.get('GITHUBAPP_INSTALLATION_ID'))
|
||||
open(os.environ.get('GITHUBAPP_RESULT_PATH'), 'w').write(github_app.token)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
16
task/github-app-token/0.2/samples/run.yaml
Normal file
16
task/github-app-token/0.2/samples/run.yaml
Normal file
@ -0,0 +1,16 @@
|
||||
apiVersion: tekton.dev/v1beta1
|
||||
kind: TaskRun
|
||||
metadata:
|
||||
generateName: github-app-token-
|
||||
spec:
|
||||
taskRef:
|
||||
name: github-app-token
|
||||
params:
|
||||
- name: installation_id
|
||||
value: 12345
|
||||
- name: application_id
|
||||
value: 67890
|
||||
workspaces:
|
||||
- name: secrets
|
||||
secret:
|
||||
secretName: github-app-secret
|
22
task/github-app-token/0.2/samples/secret.yaml
Normal file
22
task/github-app-token/0.2/samples/secret.yaml
Normal file
@ -0,0 +1,22 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: github-app-secret
|
||||
type: Opaque
|
||||
stringData:
|
||||
private.key: |-
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICXAIBAAKBgQCxiQEUg+S3LmCUDVUaa6q1GM5+phvoL4UXkzr8aa1VZGJCWEEQ
|
||||
ualGonn5DmCN99NPIuQRZwMa8xLT0yShGPqar9XxGpoinejrxbL10tqQ20EfBDB9
|
||||
z1duIaXsdCckq/oyvpsSH6akQddzzQCXSHYRZI1UQVyiFRYQyJhjcRSyRQIDAQAB
|
||||
AoGAOqVITw+WsRBH5QBWeYjRdktAg0O5+kQgUf5XwOPj1052yvW+YJkEGwo3ApfG
|
||||
O39/NSgQcNM3imJ7eK/J7NGEjqAjwZwlLWgAe5LeLYctJG6GhRyDkQ1dui8UJg4X
|
||||
Wmq+kRcfExKSy1qAwDi1jRvK9dEjxwZdDJNGdIfpWLHH0W0CQQD5vPUBF2dNwXOs
|
||||
KN8qyPQ4LhgH/EeexM40d5knkgKZ2+9VthdG9VEhdigz2MH/CwI20IsnXwY84lAB
|
||||
uaODjADjAkEAtfyVgcM7DobOucuMEyj+nH0E8GUBwiQ1O0gFA79Uoii39f0cydeO
|
||||
TqZwgrPa/oSF76w0dZMZ+m9spjX5zEywtwJAIKNeTb82RAY1TNmmmNvcdv8nKtwA
|
||||
rDJCVL8QqAhACMWimMwMbLyg1sOva183s1JH/svwc7vKf+h/1knhoc6JSwJBALW0
|
||||
Eyaz4lRXvzJ9DEfZJ5bhsLvBbicEde3Rs8gREhSyqTK/3S2evqTCxBWMNHzpnr01
|
||||
6E74Z/jHpeiyfc5BSDMCQEegoccNEAtBNl48gfSDVvFCBpDePIQoqC90j6xHx++O
|
||||
NZsjlNUJXgVQZ5ghrGCQEc6beTvBSIEeNvwxX7S1h04=
|
||||
-----END RSA PRIVATE KEY-----
|
Loading…
Reference in New Issue
Block a user