-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcreate_identity.py
More file actions
161 lines (121 loc) · 4.13 KB
/
create_identity.py
File metadata and controls
161 lines (121 loc) · 4.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
"""Create a node identity object."""
import argparse
import json
import logging
import os
import sys
import uuid
from datetime import datetime, timezone
from importlib.metadata import PackageNotFoundError, version
from typing import Final
import requests
logging.basicConfig(
format="%(asctime)-15s %(levelname)s :: %(filename)s:%(lineno)s:%(funcName)s() :: %(message)s", # noqa: E501
datefmt="%Y-%m-%d %H:%M:%S",
level="INFO",
)
logger = logging.getLogger(__name__)
NODE_IDENTITY_LOC: Final[str] = os.path.join("/var/tmp", ".node-identity.json")
def get_version():
"""Return package version to the calling code.
Version is set to None if it isn't picked up by importlib correctly
we return `None` or `null` for now.
"""
__version__ = None
try:
__version__ = version("orcfax-collector-node")
except PackageNotFoundError:
# package is not installed
pass
logging.info(__version__)
return __version__
def validate_ws_string(validator_ws: str) -> bool:
"""Perform some rudimentary validation on the init string for the
validator websocket.
ws:// is the only supported protocol until we implement an
encrypted tls connection and can provide wss://.
"""
if not validator_ws.startswith("ws://") and not validator_ws.startswith("wss://"):
return False
return True
def where_am_i():
"""Tell me where I am."""
resp = requests.get("https://ipinfo.io/ip", timeout=30)
ip_addr = resp.text
resp = requests.get(f"https://ipinfo.io/{ip_addr}", timeout=30)
return json.loads(resp.text)
def keygen():
"""Public/private keypair generation.
TMP: returns a uuid4 in v1.
"""
return f"{uuid.uuid4()}"
def who_am_i():
"""Declare me who I am.
NB. replace with keygen procedure and return public key.
"""
return keygen()
def when_am_i():
"""Declare when I was brought online."""
return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
def create_id(validator_ws: str, cert: str):
"""Create an identity for me."""
who = who_am_i()
where = where_am_i()
ws_endpoint = f"{validator_ws}/{who}/"
logger.info("Validator ws is: %s", ws_endpoint)
id_obj = {}
id_obj["node_id"] = who
id_obj["location"] = where
id_obj["initialization"] = when_am_i()
id_obj["init_version"] = get_version()
id_obj["validator_web_socket"] = validator_ws
id_obj["validator_certificate"] = cert
return id_obj
def save_id(id_: dict) -> None:
"""Save the ID to a location on disk."""
with open(NODE_IDENTITY_LOC, "w", encoding="utf-8") as identity:
identity.write(json.dumps(id_))
def main():
"""Primary entry point for this script."""
parser = argparse.ArgumentParser(
prog="coop-node-init",
description="Initializes a COOP node by creating an identity and declaring its validator",
epilog="for more information visit https://orcfax.io",
)
parser.add_argument(
"--websocket",
help="provide the websocket location of the coop-validator web-socket",
required=False,
)
parser.add_argument(
"--cert",
help="provide the websocket certificate to enable wss://",
required=False,
)
parser.add_argument(
"--version",
help="return script version",
required=False,
action="store_true",
)
args = parser.parse_args()
if args.version:
print(f"coop-node-init: {get_version()}")
sys.exit()
validator_ws = None
if args.websocket:
validator_ws = args.websocket
if not validate_ws_string(validator_ws):
logger.error(
"validator string '%s' is invalid, exiting (do not pass init arg if testing without validator)",
validator_ws,
)
sys.exit(1)
if args.cert:
logger.info("self-signed certificate testing is not yet implemented")
logger.info("websocket set to: %s", validator_ws)
id_obj = create_id(validator_ws, args.cert)
save_id(id_obj)
logger.info("identity output to: %s", NODE_IDENTITY_LOC)
if __name__ == "__main__":
main()