Skip to content

Instantly share code, notes, and snippets.

@CodyKochmann
Created June 14, 2021 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CodyKochmann/46c46c84b7ccfe630ca4fac48fe1186f to your computer and use it in GitHub Desktop.
Save CodyKochmann/46c46c84b7ccfe630ca4fac48fe1186f to your computer and use it in GitHub Desktop.
api for accessing gitlab project environment variables as a python dictionary
#!/usr/bin/env python
# author: Cody Kochmann
# created: 2021-06-13
# license: MIT
from functools import partial
import json, logging
import requests
''' This is an api to access GitLab project
environment variables as python dictionaries
for easy analysis and configuring of the
project variables
'''
def loads(s):
assert isinstance(s, str), s
if len(s.strip()) == 0:
return None
else:
try:
return json.loads(s)
except Exception as e:
logging.exception(e)
return s
class _ProjectVariables(dict):
def __init__(self, project_id, api_key, gitlab='https://gitlab.com'):
assert isinstance(project_id, int) or (isinstance(project_id, str) and project_id.isdigit()), project_id
assert isinstance(api_key, str), api_key
assert isinstance(gitlab, str), gitlab
assert hasattr(self, 'protected')
assert self.protected in {True, False}, self.protected
assert hasattr(self, 'masked')
assert self.masked in {True, False}, self.masked
self.project_id = project_id
self.headers = {'PRIVATE-TOKEN': api_key}
self.api_defaults = {
'headers': self.headers,
'timeout': 3
}
self.gitlab = gitlab.strip('/')
self.get = partial(
requests.get,
**self.api_defaults
)
self.post = partial(
requests.post,
**self.api_defaults
#headers=self.headers
)
self.put = partial(
requests.put,
**self.api_defaults
#headers=self.headers
)
self.delete = partial(
requests.delete,
**self.api_defaults
#headers=self.headers
)
dict.__init__(self)
@property
def variables_url(self):
return f'{self.gitlab}/api/v4/projects/{self.project_id}/variables'
@property
def data(self):
return [
i
for i in loads(self.get(self.variables_url).text)
if i['protected'] == self.protected
]
def items(self):
for i in self.data:
#if i['variable_type'] == 'env_var':
yield i['key'], i['value']
def keys(self):
for k, v in self.items():
yield k
def values(self):
for k, v in self.items():
yield v
def update(self, target):
assert isinstance(target, dict), target
for k, v in target.items():
self[k] = v
__iter__ = keys
def __len__(self):
return sum(1 for k, v in self.items())
def __str__(self):
return str({k:v for k,v in self.items()})
def __repr__(self):
return repr({k:v for k,v in self.items()})
def __contains__(self, key):
return any(k==key for k in self.keys())
def __getitem__(self, key):
assert isinstance(key, str), key
for k, v in self.items():
if k == key:
return v
raise KeyError(key)
def __setitem__(self, k, v):
assert isinstance(k, str), k
if k in self:
# update the var
return loads(
self.put(
f'{self.variables_url}/{k}',
data={
'value': v,
'protected': self.protected,
'masked': self.masked
}
).text
)
else:
# create the var
return loads(
self.post(
self.variables_url,
data={
'key': k,
'value': v,
'protected': self.protected,
'masked': self.masked
}
).text
)
def __delitem__(self, k):
return loads(
self.delete(
f'{self.variables_url}/{k}'
).text
)
class ProtectedProjectVariables(_ProjectVariables):
protected = True
masked = True
class UnprotectedProjectVariables(_ProjectVariables):
protected = False
masked = False
class ProjectVariables(object):
def __init__(self, project_id, api_key, gitlab='https://gitlab.com'):
_settings = {k:v for k,v in locals().items() if k!='self'}
self.protected = ProtectedProjectVariables(**_settings)
self.unprotected = UnprotectedProjectVariables(**_settings)
if __name__ == '__main__':
settings = dict(
project_id='12345678',
api_key='abcdef-ghijklmnopqrs'
)
pv = ProtectedProjectVariables(**settings)
uv = UnprotectedProjectVariables(**settings)
print('protected', len(pv))
print(pv)
print('unprotected', len(uv))
print(uv)
p = ProjectVariables(**settings)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment