Seed policysync container code
[dcaegen2/deployments.git] / dcae-services-policy-sync / policysync / cmd.py
1 # ============LICENSE_START=======================================================
2 # Copyright (c) 2021 AT&T Intellectual Property. All rights reserved.
3 # ================================================================================
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 #      http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 # ============LICENSE_END=========================================================
16 """
17 CLI parsing for the sync utility.
18 convert flags/env variables to configuration
19 """
20 import argparse
21 import collections
22 import os
23 import sys
24 import logging
25 import logging.config
26 from urllib.parse import urlsplit
27 import yaml
28 import policysync.clients as clients
29 import policysync.coroutines
30 from .util import get_module_logger
31
32
33 logger = get_module_logger(__name__)
34
35 APPLICATION_JSON = "application/json"
36
37
38 Config = collections.namedtuple(
39     'Config', ['out_file', 'check_period', 'filters', 'ids', 'client', 'bind'])
40
41
42 def parsecmd(args):
43     """
44     Parse the command into a config object
45     :param args: arguments list for parsing
46     :returns: Config for the policy sync
47     """
48     parser = argparse.ArgumentParser(
49         description="Keeps a file updated with policies matching a filter.",
50         formatter_class=argparse.ArgumentDefaultsHelpFormatter,
51     )
52
53     parser.add_argument(
54         "--out",
55         type=str,
56         default=os.environ.get("POLICY_SYNC_OUTFILE", "policies.json"),
57         help="Output file to dump to",
58     )
59
60     parser.add_argument(
61         "--duration",
62         type=int,
63         default=os.environ.get("POLICY_SYNC_DURATION", 1200),
64         help="frequency (in seconds) to conduct periodic check",
65     )
66
67     parser.add_argument(
68         "--filters",
69         type=str,
70         default=os.environ.get("POLICY_SYNC_FILTER", "[]"),
71         help="Regex of policies that you are interested in.",
72     )
73     parser.add_argument(
74         "--ids",
75         type=str,
76         default=os.environ.get("POLICY_SYNC_ID", "[]"),
77         help="Specific names of policies you are interested in.",
78     )
79
80     parser.add_argument(
81         "--pdp-user",
82         type=str,
83         default=os.environ.get("POLICY_SYNC_PDP_USER", None),
84         help="PDP basic auth username",
85     )
86     parser.add_argument(
87         "--pdp-pass",
88         type=str,
89         default=os.environ.get("POLICY_SYNC_PDP_PASS", None),
90         help="PDP basic auth password",
91     )
92
93     parser.add_argument(
94         "--pdp-url",
95         type=str,
96         default=os.environ.get("POLICY_SYNC_PDP_URL", None),
97         help="PDP to connect to",
98     )
99
100     parser.add_argument(
101         "--http-bind",
102         type=str,
103         default=os.environ.get("POLICY_SYNC_HTTP_BIND", "localhost:8000"),
104         help="The bind address for container metrics",
105     )
106
107     parser.add_argument(
108         "--http-metrics",
109         type=bool,
110         default=os.environ.get("POLICY_SYNC_HTTP_METRICS", True),
111         help="turn on or off the prometheus metrics",
112     )
113
114     parser.add_argument(
115         "--use-v0",
116         type=bool,
117         default=os.environ.get("POLICY_SYNC_V0_ENABLE", False),
118         help="Turn on usage of the legacy v0 policy API",
119     )
120
121     parser.add_argument(
122         "--logging-config",
123         type=str,
124         default=os.environ.get("POLICY_SYNC_LOGGING_CONFIG", None),
125         help="Python formatted logging configuration file",
126     )
127
128     # V0 API specific configuration
129     parser.add_argument(
130         "--v0-notify-endpoint",
131         type=str,
132         default=os.environ.get(
133             "POLICY_SYNC_V0_NOTIFIY_ENDPOINT", "pdp/notifications"
134         ),
135         help="Path of the v0 websocket notification",
136     )
137
138     parser.add_argument(
139         "--v0-decision-endpoint",
140         type=str,
141         default=os.environ.get("POLICY_SYNC_V0_DECISION_ENDPOINT", "pdp/api"),
142         help="path of the v0 decision endpoint",
143     )
144
145     # V1 API specific configuration
146     parser.add_argument(
147         "--v1-dmaap-topic",
148         type=str,
149         default=os.environ.get("POLICY_SYNC_V1_DMAAP_URL", None),
150         help="URL of the dmaap topic used in v1 api for notifications",
151     )
152
153     parser.add_argument(
154         "--v1-dmaap-user",
155         type=str,
156         default=os.environ.get("POLICY_SYNC_V1_DMAAP_USER", None),
157         help="User to use with with the dmaap topic"
158     )
159
160     parser.add_argument(
161         "--v1-dmaap-pass",
162         type=str,
163         default=os.environ.get("POLICY_SYNC_V1_DMAAP_PASS", None),
164         help="Password to use with the dmaap topic"
165     )
166
167     parser.add_argument(
168         "--v1-decision-endpoint",
169         type=str,
170         default=os.environ.get(
171             "POLICY_SYNC_V1_PDP_DECISION_ENDPOINT",
172             "policy/pdpx/v1/decision"
173         ),
174         help="Decision endpoint used in the v1 api for notifications",
175     )
176
177     args = parser.parse_args(args)
178
179     if args.logging_config:
180         logging.config.fileConfig(
181             args.logging_config,
182             disable_existing_loggers=False
183         )
184     else:
185         handler = logging.StreamHandler()
186         formatter = logging.Formatter(
187             "[%(asctime)s][%(levelname)-5s]%(message)s"
188         )
189         root = logging.getLogger()
190         handler.setFormatter(formatter)
191         root.addHandler(handler)
192         root.setLevel(logging.INFO)
193
194     bind = args.http_bind if args.http_metrics else None
195
196     client = clients.get_client(
197         args.pdp_url,
198         pdp_user=args.pdp_user,
199         pdp_password=args.pdp_pass,
200         use_v0=args.use_v0,
201         v0_decision=args.v0_decision_endpoint,
202         v0_notifications=args.v0_notify_endpoint,
203         v1_decision=args.v1_decision_endpoint,
204         dmaap_url=args.v1_dmaap_topic,
205         dmaap_user=args.v1_dmaap_user,
206         dmaap_password=args.v1_dmaap_pass
207     )
208
209     if bind is not None:
210         bind = urlsplit("//" + bind)
211
212     return Config(
213         out_file=args.out,
214         check_period=args.duration,
215         filters=yaml.safe_load(args.filters),
216         ids=yaml.safe_load(args.ids),
217         client=client,
218         bind=bind,
219     )
220
221
222 def main():
223     """
224     Parse the arguments passed in via the command line and start the app
225     """
226     try:
227         config = parsecmd(sys.argv[1:])
228     except ValueError:
229         logger.error(
230             "There was no POLICY_SYNC_PDP_URL set or --pdp flag set"
231         )
232         return -1
233     policysync.coroutines.start_event_loop(config)
234     return 0