gns3-server 3.0.1__py3-none-any.whl → 3.0.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of gns3-server might be problematic. Click here for more details.
- {gns3_server-3.0.1.dist-info → gns3_server-3.0.3.dist-info}/METADATA +22 -21
- {gns3_server-3.0.1.dist-info → gns3_server-3.0.3.dist-info}/RECORD +29 -27
- {gns3_server-3.0.1.dist-info → gns3_server-3.0.3.dist-info}/WHEEL +1 -1
- gns3server/api/routes/compute/iou_nodes.py +1 -1
- gns3server/api/routes/controller/images.py +58 -21
- gns3server/api/routes/controller/templates.py +23 -2
- gns3server/appliances/alpine-cloud.gns3a +56 -0
- gns3server/appliances/stormshield-eva.gns3a +50 -0
- gns3server/compute/docker/__init__.py +1 -1
- gns3server/compute/virtualbox/virtualbox_vm.py +29 -25
- gns3server/controller/__init__.py +27 -18
- gns3server/controller/appliance_manager.py +2 -2
- gns3server/controller/compute.py +7 -2
- gns3server/crash_report.py +1 -1
- gns3server/db/repositories/images.py +22 -3
- gns3server/db/repositories/templates.py +11 -0
- gns3server/db/tasks.py +120 -79
- gns3server/main.py +40 -2
- gns3server/server.py +26 -41
- gns3server/services/authentication.py +9 -6
- gns3server/static/web-ui/index.html +1 -1
- gns3server/static/web-ui/main.2e807eb4bc32f838.js +1 -0
- gns3server/utils/asyncio/__init__.py +4 -12
- gns3server/utils/asyncio/pool.py +1 -4
- gns3server/utils/images.py +17 -4
- gns3server/version.py +2 -2
- gns3server/static/web-ui/main.e55eeff5c0ba1cf4.js +0 -1
- {gns3_server-3.0.1.dist-info → gns3_server-3.0.3.dist-info}/LICENSE +0 -0
- {gns3_server-3.0.1.dist-info → gns3_server-3.0.3.dist-info}/entry_points.txt +0 -0
- {gns3_server-3.0.1.dist-info → gns3_server-3.0.3.dist-info}/top_level.txt +0 -0
gns3server/server.py
CHANGED
|
@@ -23,7 +23,6 @@ Start the program. Use main.py to load it.
|
|
|
23
23
|
import os
|
|
24
24
|
import datetime
|
|
25
25
|
import locale
|
|
26
|
-
import argparse
|
|
27
26
|
import psutil
|
|
28
27
|
import sys
|
|
29
28
|
import asyncio
|
|
@@ -33,13 +32,10 @@ import uvicorn
|
|
|
33
32
|
import secrets
|
|
34
33
|
import string
|
|
35
34
|
|
|
36
|
-
from gns3server.controller import Controller
|
|
37
|
-
from gns3server.compute.port_manager import PortManager
|
|
38
35
|
from gns3server.logger import init_logger
|
|
39
36
|
from gns3server.version import __version__
|
|
40
37
|
from gns3server.config import Config
|
|
41
38
|
from gns3server.crash_report import CrashReport
|
|
42
|
-
from gns3server.api.server import app
|
|
43
39
|
from pydantic import ValidationError, SecretStr
|
|
44
40
|
|
|
45
41
|
import logging
|
|
@@ -90,40 +86,13 @@ class Server:
|
|
|
90
86
|
else:
|
|
91
87
|
log.info(f"Current locale is {language}.{encoding}")
|
|
92
88
|
|
|
93
|
-
def
|
|
89
|
+
def _setup_logging(self, args):
|
|
94
90
|
"""
|
|
95
|
-
|
|
91
|
+
Setup logging.
|
|
96
92
|
|
|
97
|
-
:
|
|
93
|
+
:param args: command line arguments
|
|
98
94
|
"""
|
|
99
95
|
|
|
100
|
-
parser = argparse.ArgumentParser(description=f"GNS3 server version {__version__}")
|
|
101
|
-
parser.add_argument("-v", "--version", help="show the version", action="version", version=__version__)
|
|
102
|
-
parser.add_argument("--host", help="run on the given host/IP address")
|
|
103
|
-
parser.add_argument("--port", help="run on the given port", type=int)
|
|
104
|
-
parser.add_argument("--ssl", action="store_true", help="run in SSL mode")
|
|
105
|
-
parser.add_argument("--config", help="Configuration file")
|
|
106
|
-
parser.add_argument("--certfile", help="SSL cert file")
|
|
107
|
-
parser.add_argument("--certkey", help="SSL key file")
|
|
108
|
-
parser.add_argument("-L", "--local", action="store_true", help="local mode (allows some insecure operations)")
|
|
109
|
-
parser.add_argument(
|
|
110
|
-
"-A", "--allow", action="store_true", help="allow remote connections to local console ports"
|
|
111
|
-
)
|
|
112
|
-
parser.add_argument("-q", "--quiet", default=False, action="store_true", help="do not show logs on stdout")
|
|
113
|
-
parser.add_argument("-d", "--debug", default=False, action="store_true", help="show debug logs")
|
|
114
|
-
parser.add_argument("--logfile", "--log", help="send output to logfile instead of console")
|
|
115
|
-
parser.add_argument("--logmaxsize", default=10000000, help="maximum logfile size in bytes (default is 10MB)")
|
|
116
|
-
parser.add_argument(
|
|
117
|
-
"--logbackupcount", default=10, help="number of historical log files to keep (default is 10)"
|
|
118
|
-
)
|
|
119
|
-
parser.add_argument(
|
|
120
|
-
"--logcompression", default=False, action="store_true", help="compress inactive (historical) logs"
|
|
121
|
-
)
|
|
122
|
-
parser.add_argument("--daemon", action="store_true", help="start as a daemon")
|
|
123
|
-
parser.add_argument("--pid", help="store process pid")
|
|
124
|
-
parser.add_argument("--profile", help="Settings profile (blank will use default settings files)")
|
|
125
|
-
|
|
126
|
-
args = parser.parse_args(argv)
|
|
127
96
|
level = logging.INFO
|
|
128
97
|
if args.debug:
|
|
129
98
|
level = logging.DEBUG
|
|
@@ -137,6 +106,15 @@ class Server:
|
|
|
137
106
|
quiet=args.quiet,
|
|
138
107
|
)
|
|
139
108
|
|
|
109
|
+
@staticmethod
|
|
110
|
+
def _load_config_and_set_defaults(parser, args, argv=None):
|
|
111
|
+
"""
|
|
112
|
+
Parse command line arguments and override local configuration
|
|
113
|
+
|
|
114
|
+
:param parser: ArgumentParser instance
|
|
115
|
+
:param args: command line arguments
|
|
116
|
+
"""
|
|
117
|
+
|
|
140
118
|
try:
|
|
141
119
|
if args.config:
|
|
142
120
|
Config.instance(files=[args.config], profile=args.profile)
|
|
@@ -157,7 +135,10 @@ class Server:
|
|
|
157
135
|
}
|
|
158
136
|
|
|
159
137
|
parser.set_defaults(**defaults)
|
|
160
|
-
|
|
138
|
+
if argv is None:
|
|
139
|
+
argv = sys.argv[1:]
|
|
140
|
+
args = parser.parse_args(argv)
|
|
141
|
+
return args
|
|
161
142
|
|
|
162
143
|
@staticmethod
|
|
163
144
|
def _set_config_defaults_from_command_line(args):
|
|
@@ -174,6 +155,8 @@ class Server:
|
|
|
174
155
|
config.Server.enable_ssl = args.ssl
|
|
175
156
|
|
|
176
157
|
def _signal_handling(self):
|
|
158
|
+
|
|
159
|
+
from gns3server.controller import Controller
|
|
177
160
|
def signal_handler(signame, *args):
|
|
178
161
|
|
|
179
162
|
try:
|
|
@@ -239,9 +222,10 @@ class Server:
|
|
|
239
222
|
log.critical("Can't write pid file %s: %s", path, str(e))
|
|
240
223
|
sys.exit(1)
|
|
241
224
|
|
|
242
|
-
async def run(self):
|
|
225
|
+
async def run(self, parser, args):
|
|
243
226
|
|
|
244
|
-
|
|
227
|
+
self._setup_logging(args)
|
|
228
|
+
args = self._load_config_and_set_defaults(parser, args)
|
|
245
229
|
|
|
246
230
|
if args.pid:
|
|
247
231
|
self._pid_lock(args.pid)
|
|
@@ -256,7 +240,6 @@ class Server:
|
|
|
256
240
|
|
|
257
241
|
self._set_config_defaults_from_command_line(args)
|
|
258
242
|
config = Config.instance().settings
|
|
259
|
-
|
|
260
243
|
if not config.Server.compute_password.get_secret_value():
|
|
261
244
|
alphabet = string.ascii_letters + string.digits + string.punctuation
|
|
262
245
|
generated_password = ''.join(secrets.choice(alphabet) for _ in range(16))
|
|
@@ -267,9 +250,9 @@ class Server:
|
|
|
267
250
|
else:
|
|
268
251
|
log.info(f"Compute authentication is enabled with username '{config.Server.compute_username}'")
|
|
269
252
|
|
|
270
|
-
# we only support Python 3 version >= 3.
|
|
271
|
-
if sys.version_info < (3,
|
|
272
|
-
raise SystemExit("Python 3.
|
|
253
|
+
# we only support Python 3 version >= 3.9
|
|
254
|
+
if sys.version_info < (3, 9, 0):
|
|
255
|
+
raise SystemExit("Python 3.9 or higher is required")
|
|
273
256
|
|
|
274
257
|
log.info(
|
|
275
258
|
"Running with Python {major}.{minor}.{micro} and has PID {pid}".format(
|
|
@@ -297,11 +280,13 @@ class Server:
|
|
|
297
280
|
host = config.Server.host
|
|
298
281
|
port = config.Server.port
|
|
299
282
|
|
|
283
|
+
from gns3server.compute.port_manager import PortManager
|
|
300
284
|
PortManager.instance().console_host = host
|
|
301
285
|
self._signal_handling()
|
|
302
286
|
|
|
303
287
|
try:
|
|
304
288
|
log.info(f"Starting server on {host}:{port}")
|
|
289
|
+
from gns3server.api.server import app
|
|
305
290
|
|
|
306
291
|
# only show uvicorn access logs in debug mode
|
|
307
292
|
access_log = False
|
|
@@ -14,8 +14,9 @@
|
|
|
14
14
|
# You should have received a copy of the GNU General Public License
|
|
15
15
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
from
|
|
17
|
+
from joserfc import jwt
|
|
18
|
+
from joserfc.jwk import OctKey
|
|
19
|
+
from joserfc.errors import JoseError
|
|
19
20
|
from datetime import datetime, timedelta, timezone
|
|
20
21
|
import bcrypt
|
|
21
22
|
|
|
@@ -56,7 +57,8 @@ class AuthService:
|
|
|
56
57
|
secret_key = DEFAULT_JWT_SECRET_KEY
|
|
57
58
|
log.error("A JWT secret key must be configured to secure the server, using an unsecured default key!")
|
|
58
59
|
algorithm = Config.instance().settings.Controller.jwt_algorithm
|
|
59
|
-
|
|
60
|
+
key = OctKey.import_key(secret_key)
|
|
61
|
+
encoded_jwt = jwt.encode({"alg": algorithm}, to_encode, key)
|
|
60
62
|
return encoded_jwt
|
|
61
63
|
|
|
62
64
|
def get_username_from_token(self, token: str, secret_key: str = None) -> Optional[str]:
|
|
@@ -73,11 +75,12 @@ class AuthService:
|
|
|
73
75
|
secret_key = DEFAULT_JWT_SECRET_KEY
|
|
74
76
|
log.error("A JWT secret key must be configured to secure the server, using an unsecured default key!")
|
|
75
77
|
algorithm = Config.instance().settings.Controller.jwt_algorithm
|
|
76
|
-
|
|
77
|
-
|
|
78
|
+
key = OctKey.import_key(secret_key)
|
|
79
|
+
payload = jwt.decode(token, key, algorithms=[algorithm])
|
|
80
|
+
username: str = payload.claims.get("sub")
|
|
78
81
|
if username is None:
|
|
79
82
|
raise credentials_exception
|
|
80
83
|
token_data = TokenData(username=username)
|
|
81
|
-
except (
|
|
84
|
+
except (JoseError, ValidationError, ValueError):
|
|
82
85
|
raise credentials_exception
|
|
83
86
|
return token_data.username
|
|
@@ -46,6 +46,6 @@
|
|
|
46
46
|
|
|
47
47
|
gtag('config', 'G-0BT7QQV1W1');
|
|
48
48
|
</script>
|
|
49
|
-
<script src="runtime.24fa95b7061d7056.js" type="module"></script><script src="polyfills.319c79dd175e50d0.js" type="module"></script><script src="main.
|
|
49
|
+
<script src="runtime.24fa95b7061d7056.js" type="module"></script><script src="polyfills.319c79dd175e50d0.js" type="module"></script><script src="main.2e807eb4bc32f838.js" type="module"></script>
|
|
50
50
|
|
|
51
51
|
</body></html>
|