Skip to content

Commit

Permalink
Fix CLI commands (#121)
Browse files Browse the repository at this point in the history
* Fix CLI commands

Signed-off-by: Anja Strunk <anja.strunk@cloudandheat.com>

* Revert unneccessary changes

Signed-off-by: Anja Strunk <anja.strunk@cloudandheat.com>

* Revert unneccessary changes

Signed-off-by: Anja Strunk <anja.strunk@cloudandheat.com>

* Revert unneccessary changes

Signed-off-by: Anja Strunk <anja.strunk@cloudandheat.com>

* Revert unneccessary changes

Signed-off-by: Anja Strunk <anja.strunk@cloudandheat.com>

* Fix pipeline

Signed-off-by: Anja Strunk <anja.strunk@cloudandheat.com>

* Update docu. Add config.yaml to gitignore

Signed-off-by: Anja Strunk <anja.strunk@cloudandheat.com>

* Fix test cases

Signed-off-by: Anja Strunk <anja.strunk@cloudandheat.com>

* Change file names to be in sync with VC ids

Signed-off-by: Anja Strunk <anja.strunk@cloudandheat.com>

* Fix test cases

Signed-off-by: Anja Strunk <anja.strunk@cloudandheat.com>

* Change default path of config file

Signed-off-by: Anja Strunk <anja.strunk@cloudandheat.com>

* Delete obsolete vsmo.json

Signed-off-by: Anja Strunk <anja.strunk@cloudandheat.com>

* Revert move cli.py out

Signed-off-by: Anja Strunk <anja.strunk@cloudandheat.com>

* Fix test cases

Signed-off-by: Anja Strunk <anja.strunk@cloudandheat.com>

* Update README.md

Signed-off-by: Anja Strunk <anja.strunk@cloudandheat.com>

* Fix markdown lint

Signed-off-by: Anja Strunk <anja.strunk@cloudandheat.com>

---------

Signed-off-by: Anja Strunk <anja.strunk@cloudandheat.com>
  • Loading branch information
anjastrunk authored Oct 18, 2024
1 parent 0de383e commit abdea61
Show file tree
Hide file tree
Showing 10 changed files with 38 additions and 37 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ coverage.xml
os_secret
k8s_secret
.gx-credentials
config/config.yaml
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
![Static Badge](https://img.shields.io/badge/version-1.0.0-green)
![Static Badge](https://img.shields.io/badge/Gaia--X_Release-Tagus-blue?color=%23D901D9)
![Static Badge](https://img.shields.io/badge/Gaia--X_Compliance-Conformity-blue?color=%23D901D9)
![Python 3.10](https://img.shields.io/badge/python-3.10-blue.svg)

Tool for creating compliant Gaia-X Credentials, previously known as Gaia-X Self-Description, for SCS-compliant cloud infrastructures.
To get familiar with Gaia-X Credentials, please consult the corresponding [documentation](https://docs.gaia-x.eu/).
Expand Down Expand Up @@ -80,6 +81,8 @@ Installing dependecies into a Python [virtualenv](https://virtualenv.pypa.io/en/
pip install -r requirements.txt
```

Please use python version 3.10!

### Cloud Service Provider

#### 1. Create configuration file
Expand Down
2 changes: 1 addition & 1 deletion config/config.yaml → config/config.yaml.template
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ IaaS:
format-type: "plain"

# Endpoints of Gaia-X Digital Clearing House
gxdch:
GXDCH:
notary-service: https://registrationnumber.notary.lab.gaia-x.eu/v1-staging
compliance-service: https://compliance.lab.gaia-x.eu/v1-staging
registry-service: https://registry.lab.gaia-x.eu/v1-staging
Expand Down
25 changes: 11 additions & 14 deletions generator/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,11 @@
DATA_FILE_FORMAT = "json-ld"

VC_NAME_LOOKUP = {
"lp": "Legal Person",
"legal_person": "Legal Person",
"lrn": "Legal Registration Number",
"tandc": "Gaia-X Terms and Conditions",
"cs_csp": "GXDCH Compliance Service",
"cs_so": "GXDCH Compliance Service",
"csp_compliance": "GXDCH Compliance Service",
"so_compliance": "GXDCH Compliance Service",
"so": "Service Offering",
"vmso": "Virtual Machine Service Offering",
}
Expand Down Expand Up @@ -94,7 +94,7 @@ def cli_commands():
pass


@click.command()
@cli_commands.command()
@add_logging_options
@click.option(
"--auto-sign/--no-auto-sign",
Expand Down Expand Up @@ -147,7 +147,7 @@ def openstack(cloud, timeout, config, out_dir, auto_sign):
_print_vcs(vcs, out_dir)


@click.command()
@cli_commands.command()
@add_logging_options
def kubernetes():
"""Generates Gaia-X Credentials for CSP and Kubernetes."""
Expand All @@ -160,7 +160,7 @@ def kubernetes():
# graph.parse(filepath, format=file_format)
# return graph

@click.command()
@cli_commands.command()
@add_logging_options
@click.option(
"--auto-sign/--no-auto-sign",
Expand Down Expand Up @@ -232,6 +232,7 @@ def create_vmso_vcs(conf: Config, cloud: str, csp_vcs: List[dict], timeout: int
@param timeout: timeout for connection to OpenStack cloud. If timeout expires, connection is initialed a second time.
@return: A list of Gaia-X Credentials describing given OpenStack cloud.
"""

csp = conf.get_value([const.CONFIG_CSP])
# iaas = conf.get_value([const.CONFIG_IAAS]) not yet used, as Gaia-X "abuses" id attribute of Verifiable Credentials
cred_settings = conf.get_value([const.CONFIG_CRED])
Expand All @@ -247,7 +248,7 @@ def create_vmso_vcs(conf: Config, cloud: str, csp_vcs: List[dict], timeout: int
vmso_vc = {
'@context': [const.VC_CONTEXT, const.JWS_CONTEXT, const.REG_CONTEXT],
'type': "VerifiableCredential",
'id': cred_settings[const.CONFIG_CRED_BASE_CRED_URL] + "/vmo.json",
'id': cred_settings[const.CONFIG_CRED_BASE_CRED_URL] + "/vmso.json",
'issuer': csp['did'],
'issuanceDate': str(datetime.now(tz=timezone.utc).isoformat()),
'credentialSubject': json.loads(json.dumps(vm_offering, default=json_ld.to_json_ld)),
Expand All @@ -269,7 +270,7 @@ def create_vmso_vcs(conf: Config, cloud: str, csp_vcs: List[dict], timeout: int
"type": "gx:ServiceOffering",
"id": cred_settings[const.CONFIG_CRED_BASE_CRED_URL] + "/so.json#subject", # iaas['did'],
"gx:providedBy": {
'id': csp_vcs['lp']['credentialSubject']['id']
'id': csp_vcs['legal_person']['credentialSubject']['id']
},
"gx:termsAndConditions": [
{'gx:URL': s_tac.url, 'gx:hash': s_tac.hash}
Expand All @@ -291,12 +292,12 @@ def create_vmso_vcs(conf: Config, cloud: str, csp_vcs: List[dict], timeout: int

# Request Gaia-X Compliance Credential for Service Offering
logging.info('Request VC of type "gx:compliance" for Service Offering at GXDCH Compliance Service...')
vp = credentials.convert_to_vp(creds=[csp_vcs['tandc'], csp_vcs['lrn'], csp_vcs['lp'], so_vc_signed])
vp = credentials.convert_to_vp(creds=[csp_vcs['tandc'], csp_vcs['lrn'], csp_vcs['legal_person'], so_vc_signed])
comp_vc = compliance.request_compliance_vc(vp,
cred_settings[const.CONFIG_CRED_BASE_CRED_URL] + "/so_compliance.json")

logging.info('ok')
return {'so': so_vc, 'cs_so': json.loads(comp_vc), 'vmso': vmso_vc_signed, 'vp_so': vp}
return {'so': so_vc, 'so_compliance': json.loads(comp_vc), 'vmso': vmso_vc_signed, 'vp_so': vp}


def _get_timestamp():
Expand Down Expand Up @@ -356,9 +357,5 @@ def _are_gaiax_tandc_signed(conf: Config) -> bool:
return False


cli_commands.add_command(openstack)
cli_commands.add_command(kubernetes)
cli_commands.add_command(csp)

if __name__ == "__main__":
cli_commands()
2 changes: 1 addition & 1 deletion generator/common/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
CONFIG_CSP_EUID = "euid"

# GXDCH
CONST_GXDCH = "gxdch"
CONST_GXDCH = "GXDCH"
CONST_GXDCH_NOT = "notary-service"
CONST_GXDCH_COMP = "compliance-service"
CONST_GXDCH_REG = "registry-service"
Expand Down
2 changes: 1 addition & 1 deletion generator/discovery/csp_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def generate(self) -> dict:
vp = credentials.convert_to_vp(creds=[tandc_vc, lrn_vc, lp_vc])
cs_vc = self.compliance.request_compliance_vc(vp, self.cred_base_url + "/csp_compliance.json")
logging.info('ok')
return {'tandc': tandc_vc, 'lrn': lrn_vc, 'lp': lp_vc, 'cs_csp': json.loads(cs_vc), 'vp_csp': vp}
return {'tandc': tandc_vc, 'lrn': lrn_vc, 'legal_person': lp_vc, 'csp_compliance': json.loads(cs_vc), 'vp_csp': vp}

def _sign_gaia_x_terms_and_conditions(self) -> dict:
"""
Expand Down
2 changes: 1 addition & 1 deletion generator/discovery/openstack/server_flavor_discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def _convert_to_gx(self, os_flavor: OS_Flavor) -> GX_Flavor:
# Initialize Gaia-X Server Flavor
disks = self._get_disks(os_flavor, flavorname)
gx_flavor = GX_Flavor(
# name=os_flavor.name,
name=os_flavor.name,
cpu=self._get_cpu(os_flavor, flavorname),
ram=self._get_ram(os_flavor, flavorname),
bootVolume=disks[0],
Expand Down
2 changes: 1 addition & 1 deletion tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def get_absolute_path(relative_path: str) -> str:


def get_config() -> Config:
with open(get_absolute_path("config/config.yaml"), "r") as config_file:
with open(get_absolute_path("config/config.yaml.template"), "r") as config_file:
return Config(yaml.safe_load(config_file))


Expand Down
22 changes: 11 additions & 11 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from jwcrypto.jwt import JWK

from generator import cli
from generator.common import config, const
from generator.common import config
from generator.common.gx_schema import (DataAccountExport, TermsAndConditions,
VirtualMachineServiceOffering)
from tests.common import MockConnection, get_absolute_path
Expand Down Expand Up @@ -45,10 +45,10 @@ def test_generate_vsmo(self, cli_print_vs, os_connect, os_discover, load_jwk, gx
encryption_algorithm=serialization.NoEncryption()))
csp_vcs = {'tandc': {"credentialSubject": {"type": "gx:GaiaXTermsAndConditions"}},
"lrn": {"credentialSubject": {"type": "gx:LegalRegistrationNumber", "id": "foo"}},
"lp": {"credentialSubject": {"type": "gx:LegalParticipant", "id": "foo"}}}
"legal_person": {"credentialSubject": {"type": "gx:LegalParticipant", "id": "foo"}}}
gxdch_req_compl.return_value = "{\"credentialSubject\": {\"type\": \"gx:ComplianceCredential\", \"id\": \"foo\"}}"

with open(get_absolute_path(const.CONFIG_FILE), "r") as config_file:
with open(get_absolute_path("config/config.yaml.template"), "r") as config_file:
conf = config.Config(yaml.safe_load(config_file))

vcs = cli.create_vmso_vcs(conf, "myCloud", csp_vcs)
Expand All @@ -58,7 +58,7 @@ def test_generate_vsmo(self, cli_print_vs, os_connect, os_discover, load_jwk, gx

self.assertEqual(4, len(vcs))
self.assertEqual("gx:ServiceOffering", vcs['so']['credentialSubject']["type"])
self.assertEqual("gx:ComplianceCredential", vcs['cs_so']['credentialSubject']["type"])
self.assertEqual("gx:ComplianceCredential", vcs['so_compliance']['credentialSubject']["type"])
self.assertEqual("gx:VirtualMachineServiceOffering", vcs['vmso']['credentialSubject']["type"])
self.assertIsNotNone(vcs['vp_so'])

Expand All @@ -72,7 +72,7 @@ def test_openstack(self, cli_print_vs, gen_vmso, gen_csp):

runner = CliRunner()
result = runner.invoke(
cli.openstack, "myCloud --config=" + get_absolute_path(const.CONFIG_FILE) + " --auto-sign"
cli.openstack, "myCloud --config=" + get_absolute_path("config/config.yaml.template") + " --auto-sign"
)

gen_csp.assert_called_once()
Expand All @@ -91,7 +91,7 @@ def test_openstack_auto_sign(self, cli_print_vs, gen_vmso, gen_csp):

runner = CliRunner()
result = runner.invoke(
cli.openstack, "myCloud --config=" + get_absolute_path(const.CONFIG_FILE) + " --auto-sign"
cli.openstack, "myCloud --config=" + get_absolute_path("config/config.yaml.template") + " --auto-sign"
)

gen_csp.assert_called_once()
Expand All @@ -111,7 +111,7 @@ def test_openstack_no_auto_sign(self, cli_print_vs, gen_vmso, gen_csp):
with patch('builtins.input', return_value="n"):
runner = CliRunner()
result = runner.invoke(
cli.openstack, "myCloud --config=" + get_absolute_path(const.CONFIG_FILE) + " --no-auto-sign"
cli.openstack, "myCloud --config=" + get_absolute_path("config/config.yaml.template") + " --no-auto-sign"
)

self.assertEqual(0, gen_csp.call_count)
Expand All @@ -131,7 +131,7 @@ def test_openstack_sign(self, cli_print_vs, gen_vmso, gen_csp):
with patch('builtins.input', return_value="y"):
runner = CliRunner()
result = runner.invoke(
cli.openstack, "myCloud --config=" + get_absolute_path(const.CONFIG_FILE)
cli.openstack, "myCloud --config=" + get_absolute_path("config/config.yaml.template")
)

gen_csp.assert_called_once()
Expand Down Expand Up @@ -159,7 +159,7 @@ def test_csp_auto_sign(self, cli_print_vs, gen_csp):

runner = CliRunner()
result = runner.invoke(
cli.csp, "--config=" + get_absolute_path(const.CONFIG_FILE) + " --auto-sign"
cli.csp, "--config=" + get_absolute_path("config/config.yaml.template") + " --auto-sign"
)

gen_csp.assert_called_once()
Expand All @@ -175,7 +175,7 @@ def test_csp_sign(self, cli_print_vs, gen_csp):
with patch('builtins.input', return_value="y"):
runner = CliRunner()
result = runner.invoke(
cli.csp, "--config=" + get_absolute_path(const.CONFIG_FILE)
cli.csp, "--config=" + get_absolute_path("config/config.yaml.template")
)
gen_csp.assert_called_once()
self.assertIsNone(result.exception)
Expand All @@ -190,7 +190,7 @@ def test_csp_no_auto_sign(self, cli_print_vs, gen_csp):
with patch('builtins.input', return_value="n"):
runner = CliRunner()
result = runner.invoke(
cli.csp, "--config=" + get_absolute_path(const.CONFIG_FILE) + " --no-auto-sign"
cli.csp, "--config=" + get_absolute_path("config/config.yaml.template") + " --no-auto-sign"
)

self.assertEqual(0, gen_csp.call_count)
Expand Down
14 changes: 7 additions & 7 deletions tests/test_csp_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class CspPGeneratorTestCase(unittest.TestCase):

@classmethod
def setUpClass(cls):
with open(get_absolute_path(const.CONFIG_FILE), "r") as config_file:
with open(get_absolute_path("config/config.yaml.template"), "r") as config_file:
cls.conf = config.Config(yaml.safe_load(config_file))

cls.private_key = JWK.from_pem(rsa.generate_private_key(
Expand Down Expand Up @@ -70,14 +70,14 @@ def _verify_csp_gen(self, csp_vcs, get_tandc, request_req_number, request_comp_v
self.assertEqual("gx:legalRegistrationNumber", csp_vcs['lrn']['credentialSubject']['type'])
self.assertEqual(
self.conf.get_value([const.CONFIG_CRED, const.CONFIG_CRED_BASE_CRED_URL]) + "/legal_person.json",
csp_vcs['lp']['id'])
csp_vcs['legal_person']['id'])
self.assertEqual(
self.conf.get_value([const.CONFIG_CRED, const.CONFIG_CRED_BASE_CRED_URL]) + "/legal_person.json#subject",
csp_vcs['lp']['credentialSubject']['id'])
self.assertEqual(self.conf.get_value([const.CONFIG_CSP, const.CONFIG_DID]), csp_vcs['lp']['issuer'])
self.assertIsNotNone(csp_vcs['lp']['proof'])
self.assertEqual("gx:LegalParticipant", csp_vcs['lp']['credentialSubject']['type'])
self.assertEqual("gx:ComplianceCredential", csp_vcs['cs_csp']['credentialSubject']['type'])
csp_vcs['legal_person']['credentialSubject']['id'])
self.assertEqual(self.conf.get_value([const.CONFIG_CSP, const.CONFIG_DID]), csp_vcs['legal_person']['issuer'])
self.assertIsNotNone(csp_vcs['legal_person']['proof'])
self.assertEqual("gx:LegalParticipant", csp_vcs['legal_person']['credentialSubject']['type'])
self.assertEqual("gx:ComplianceCredential", csp_vcs['csp_compliance']['credentialSubject']['type'])


if __name__ == '__main__':
Expand Down

0 comments on commit abdea61

Please sign in to comment.