gnetcli-adapter 2.8.2__tar.gz → 2.8.3__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gnetcli_adapter
3
- Version: 2.8.2
3
+ Version: 2.8.3
4
4
  Summary: Gnetcli-server adapter for Annet
5
5
  Author-email: Aleksandr Balezin <gescheit12@gmail.com>
6
6
  Requires-Python: >=3.10
@@ -84,4 +84,30 @@ Host mybastion
84
84
 
85
85
  `~/.annet/context.yml` the same because gnetcli read .ssh/config by default.
86
86
 
87
+ ## Connecting to an externally-running gnetcli_server
88
+
89
+ If `gnetcli_server` is already running on a bastion host, set `url` and the
90
+ adapter will connect to it instead of spawning a local server binary. `login`
91
+ and `password` authenticate to the gnetcli server itself (Basic auth);
92
+ `dev_login`/`dev_password` are still the network device credentials.
93
+
94
+ ```yaml
95
+ fetcher:
96
+ default:
97
+ adapter: gnetcli
98
+ params: &gnetcli
99
+ url: 192.0.2.10:50051
100
+ login: gnetcli-user
101
+ password: gnetcli-secret
102
+ dev_login: mylogin
103
+ dev_password: mypassword
104
+ deployer:
105
+ default:
106
+ adapter: gnetcli
107
+ params:
108
+ <<: *gnetcli
109
+ ```
110
+
111
+ When `url` is unset, the adapter starts a local `gnetcli_server` subprocess
112
+ (`server_path` defaults to `gnetcli_server` on `$PATH`).
87
113
 
@@ -43,3 +43,29 @@ Host mybastion
43
43
 
44
44
  `~/.annet/context.yml` the same because gnetcli read .ssh/config by default.
45
45
 
46
+ ## Connecting to an externally-running gnetcli_server
47
+
48
+ If `gnetcli_server` is already running on a bastion host, set `url` and the
49
+ adapter will connect to it instead of spawning a local server binary. `login`
50
+ and `password` authenticate to the gnetcli server itself (Basic auth);
51
+ `dev_login`/`dev_password` are still the network device credentials.
52
+
53
+ ```yaml
54
+ fetcher:
55
+ default:
56
+ adapter: gnetcli
57
+ params: &gnetcli
58
+ url: 192.0.2.10:50051
59
+ login: gnetcli-user
60
+ password: gnetcli-secret
61
+ dev_login: mylogin
62
+ dev_password: mypassword
63
+ deployer:
64
+ default:
65
+ adapter: gnetcli
66
+ params:
67
+ <<: *gnetcli
68
+ ```
69
+
70
+ When `url` is unset, the adapter starts a local `gnetcli_server` subprocess
71
+ (`server_path` defaults to `gnetcli_server` on `$PATH`).
@@ -7,6 +7,7 @@ from collections.abc import AsyncIterator, Iterable
7
7
  from contextlib import asynccontextmanager
8
8
  import logging
9
9
  from typing import Any, Dict, List, Optional, Tuple
10
+ import getpass
10
11
 
11
12
  import annet.annlib.command
12
13
 
@@ -52,6 +53,7 @@ breed_to_device = {
52
53
  "h3c": "h3c",
53
54
  "vrp85": "huawei",
54
55
  "vrp55": "huawei",
56
+ "ipn": "sitonica",
55
57
  }
56
58
 
57
59
 
@@ -76,6 +78,9 @@ class AppSettings(BaseSettings):
76
78
  def make_dev_credentials(self) -> Optional[Credentials]:
77
79
  if not self.dev_login and not self.dev_password:
78
80
  return None
81
+ if self.dev_login == 'ask_for_login' and self.dev_password == 'ask_for_password':
82
+ self.dev_login = input('Login: ')
83
+ self.dev_password = getpass.getpass('Password: ')
79
84
  return Credentials(self.dev_login, self.dev_password)
80
85
 
81
86
  def make_server_credentials(self) -> Optional[str]:
@@ -110,7 +115,7 @@ async def get_config(breed: str) -> List[str]:
110
115
  return ["show configuration"]
111
116
  elif breed.startswith("eos4"):
112
117
  return ["show running-config | no-more"]
113
- elif breed.startswith(("h3c", "vrp")):
118
+ elif breed.startswith(("h3c", "vrp", "ipn")):
114
119
  return ["display current-configuration"]
115
120
  elif breed.startswith("aruos"):
116
121
  return ["show ap-env", "show running-config no-encrypt"]
@@ -153,14 +158,21 @@ class ApiMaker(metaclass=abc.ABCMeta):
153
158
 
154
159
  @asynccontextmanager
155
160
  async def make_api(self) -> AsyncIterator[Gnetcli]:
156
- async with GnetcliStarter(self.conf.server_path, self.conf.server_conf) as gnetcli_url:
157
- yield Gnetcli(
158
- server=gnetcli_url,
161
+ def _client(server_url: str) -> Gnetcli:
162
+ return Gnetcli(
163
+ server=server_url,
159
164
  auth_token=self.conf.make_server_credentials(),
160
165
  insecure_grpc=self.conf.insecure_grpc,
161
166
  user_agent="annet",
162
167
  )
163
168
 
169
+ if self.conf.url:
170
+ yield _client(self.conf.url)
171
+ return
172
+
173
+ async with GnetcliStarter(self.conf.server_path, self.conf.server_conf) as gnetcli_url:
174
+ yield _client(gnetcli_url)
175
+
164
176
 
165
177
  class GnetcliFetcher(Fetcher, AdapterWithConfig, AdapterWithName, ApiMaker):
166
178
  def __init__(
File without changes