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