OLD | NEW |
---|---|
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 '''python %prog [options] platform template | 6 '''python %prog [options] platform template |
7 | 7 |
8 platform specifies which platform source is being generated for | 8 platform specifies which platform source is being generated for |
9 and can be one of (win, mac, linux). | 9 and can be one of (win, mac, linux). |
10 template is the path to a .json policy template file.''' | 10 template is the path to a .json policy template file.''' |
(...skipping 11 matching lines...) Expand all Loading... | |
22 parser = OptionParser(usage=__doc__); | 22 parser = OptionParser(usage=__doc__); |
23 parser.add_option("--pch", "--policy-constants-header", dest="header_path", | 23 parser.add_option("--pch", "--policy-constants-header", dest="header_path", |
24 help="generate header file of policy constants", | 24 help="generate header file of policy constants", |
25 metavar="FILE"); | 25 metavar="FILE"); |
26 parser.add_option("--pcc", "--policy-constants-source", dest="source_path", | 26 parser.add_option("--pcc", "--policy-constants-source", dest="source_path", |
27 help="generate source file of policy constants", | 27 help="generate source file of policy constants", |
28 metavar="FILE"); | 28 metavar="FILE"); |
29 parser.add_option("--pth", "--policy-type-header", dest="type_path", | 29 parser.add_option("--pth", "--policy-type-header", dest="type_path", |
30 help="generate header file for policy type enumeration", | 30 help="generate header file for policy type enumeration", |
31 metavar="FILE"); | 31 metavar="FILE"); |
32 parser.add_option("--ppb", "--policy-protobuf", dest="proto_path", | |
33 help="generate cloud policy protobuf file", | |
34 metavar="FILE"); | |
35 parser.add_option("--ppd", "--protobuf-decoder", dest="decoder_path", | |
36 help="generate C++ code decoding the policy protobuf", | |
37 metavar="FILE"); | |
32 | 38 |
33 (opts, args) = parser.parse_args(); | 39 (opts, args) = parser.parse_args(); |
34 | 40 |
35 if len(args) < 2 or len(args) > 2: | 41 if len(args) < 2 or len(args) > 2: |
36 print "exactly one platform and input file must be specified." | 42 print "exactly one platform and input file must be specified." |
37 parser.print_help() | 43 parser.print_help() |
38 sys.exit(2) | 44 sys.exit(2) |
39 template_file_contents = _LoadJSONFile(args[1]); | 45 template_file_contents = _LoadJSONFile(args[1]); |
40 if opts.header_path is not None: | 46 if opts.header_path is not None: |
41 _WritePolicyConstantHeader(template_file_contents, | 47 _WritePolicyConstantHeader(template_file_contents, args, opts); |
42 args, | |
43 opts); | |
44 if opts.source_path is not None: | 48 if opts.source_path is not None: |
45 _WritePolicyConstantSource(template_file_contents, | 49 _WritePolicyConstantSource(template_file_contents, args, opts); |
46 args, | |
47 opts); | |
48 if opts.type_path is not None: | 50 if opts.type_path is not None: |
49 _WritePolicyTypeEnumerationHeader(template_file_contents, | 51 _WritePolicyTypeEnumerationHeader(template_file_contents, args, opts); |
50 args, | 52 if opts.proto_path is not None: |
51 opts); | 53 _WriteProtobuf(template_file_contents, args, opts.proto_path) |
54 if opts.decoder_path is not None: | |
55 _WriteProtobufParser(template_file_contents, args, opts.decoder_path) | |
52 | 56 |
53 | 57 |
58 #------------------ shared helpers ---------------------------------# | |
54 def _OutputGeneratedWarningForC(f, template_file_path): | 59 def _OutputGeneratedWarningForC(f, template_file_path): |
55 f.write('//\n' | 60 f.write('//\n' |
56 '// DO NOT MODIFY THIS FILE DIRECTLY!\n' | 61 '// DO NOT MODIFY THIS FILE DIRECTLY!\n' |
57 '// IT IS GENERATED BY generate_policy_source.py\n' | 62 '// IT IS GENERATED BY generate_policy_source.py\n' |
58 '// FROM ' + template_file_path + ' \n' | 63 '// FROM ' + template_file_path + '\n' |
59 '//\n\n') | 64 '//\n\n') |
60 | 65 |
61 | 66 |
67 def _GetPolicyNameList(template_file_contents): | |
68 policy_names = []; | |
69 for policy in template_file_contents['policy_definitions']: | |
70 if policy['type'] == 'group': | |
71 for sub_policy in policy['policies']: | |
72 policy_names.append(sub_policy['name']) | |
73 else: | |
74 policy_names.append(policy['name']) | |
75 policy_names.sort() | |
76 return policy_names | |
77 | |
78 | |
79 def _LoadJSONFile(json_file): | |
80 with open(json_file, "r") as f: | |
81 text = f.read() | |
82 return eval(text) | |
83 | |
84 | |
85 #------------------ policy constants header ------------------------# | |
62 def _WritePolicyConstantHeader(template_file_contents, args, opts): | 86 def _WritePolicyConstantHeader(template_file_contents, args, opts): |
63 platform = args[0]; | 87 platform = args[0]; |
64 with open(opts.header_path, "w") as f: | 88 with open(opts.header_path, "w") as f: |
65 _OutputGeneratedWarningForC(f, args[1]) | 89 _OutputGeneratedWarningForC(f, args[1]) |
66 f.write('#ifndef CHROME_COMMON_POLICY_CONSTANTS_H_\n' | 90 f.write('#ifndef CHROME_COMMON_POLICY_CONSTANTS_H_\n' |
67 '#define CHROME_COMMON_POLICY_CONSTANTS_H_\n' | 91 '#define CHROME_COMMON_POLICY_CONSTANTS_H_\n' |
68 '#pragma once\n' | 92 '#pragma once\n' |
69 '\n' | 93 '\n' |
70 'namespace policy {\n\n') | 94 'namespace policy {\n\n') |
71 if platform == "win": | 95 if platform == "win": |
72 f.write('// The windows registry path where policy configuration ' | 96 f.write('// The windows registry path where policy configuration ' |
73 'resides.\nextern const wchar_t kRegistrySubKey[];\n\n') | 97 'resides.\nextern const wchar_t kRegistrySubKey[];\n\n') |
74 f.write('// Key names for the policy settings.\n' | 98 f.write('// Key names for the policy settings.\n' |
75 'namespace key {\n\n') | 99 'namespace key {\n\n') |
76 for policy_name in _GetPolicyNameList(template_file_contents): | 100 for policy_name in _GetPolicyNameList(template_file_contents): |
77 f.write('extern const char k' + policy_name + '[];\n') | 101 f.write('extern const char k' + policy_name + '[];\n') |
78 f.write('\n} // namespace key\n\n' | 102 f.write('\n} // namespace key\n\n' |
79 '} // namespace policy\n\n' | 103 '} // namespace policy\n\n' |
80 '#endif // CHROME_COMMON_POLICY_CONSTANTS_H_\n') | 104 '#endif // CHROME_COMMON_POLICY_CONSTANTS_H_\n') |
81 | 105 |
82 | 106 |
107 #------------------ policy constants source ------------------------# | |
83 def _WritePolicyConstantSource(template_file_contents, args, opts): | 108 def _WritePolicyConstantSource(template_file_contents, args, opts): |
84 platform = args[0]; | 109 platform = args[0]; |
85 with open(opts.source_path, "w") as f: | 110 with open(opts.source_path, "w") as f: |
86 _OutputGeneratedWarningForC(f, args[1]) | 111 _OutputGeneratedWarningForC(f, args[1]) |
87 f.write('#include "policy/policy_constants.h"\n' | 112 f.write('#include "policy/policy_constants.h"\n' |
88 '\n' | 113 '\n' |
89 'namespace policy {\n' | 114 'namespace policy {\n' |
90 '\n') | 115 '\n') |
91 if platform == "win": | 116 if platform == "win": |
92 f.write('#if defined(GOOGLE_CHROME_BUILD)\n' | 117 f.write('#if defined(GOOGLE_CHROME_BUILD)\n' |
93 'const wchar_t kRegistrySubKey[] = ' | 118 'const wchar_t kRegistrySubKey[] = ' |
94 'L"' + CHROME_SUBKEY + '";\n' | 119 'L"' + CHROME_SUBKEY + '";\n' |
95 '#else\n' | 120 '#else\n' |
96 'const wchar_t kRegistrySubKey[] = ' | 121 'const wchar_t kRegistrySubKey[] = ' |
97 'L"' + CHROMIUM_SUBKEY + '";\n' | 122 'L"' + CHROMIUM_SUBKEY + '";\n' |
98 '#endif\n\n') | 123 '#endif\n\n') |
99 f.write('namespace key {\n\n') | 124 f.write('namespace key {\n\n') |
100 for policy_name in _GetPolicyNameList(template_file_contents): | 125 for policy_name in _GetPolicyNameList(template_file_contents): |
101 f.write('const char k%s[] = "%s";\n' % (policy_name, policy_name)) | 126 f.write('const char k%s[] = "%s";\n' % (policy_name, policy_name)) |
102 f.write('\n} // namespace key\n\n' | 127 f.write('\n} // namespace key\n\n' |
103 '} // namespace policy\n') | 128 '} // namespace policy\n') |
104 | 129 |
105 | 130 |
131 #------------------ policy type enumeration header -----------------# | |
106 def _WritePolicyTypeEnumerationHeader(template_file_contents, args, opts): | 132 def _WritePolicyTypeEnumerationHeader(template_file_contents, args, opts): |
107 with open(opts.type_path, "w") as f: | 133 with open(opts.type_path, "w") as f: |
108 _OutputGeneratedWarningForC(f, args[1]) | 134 _OutputGeneratedWarningForC(f, args[1]) |
109 f.write('#ifndef CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_TYPE_H_\n' | 135 f.write('#ifndef CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_TYPE_H_\n' |
110 '#define CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_TYPE_H_\n' | 136 '#define CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_TYPE_H_\n' |
111 '#pragma once\n' | 137 '#pragma once\n' |
112 '\n' | 138 '\n' |
113 'namespace policy {\n' | 139 'namespace policy {\n' |
114 '\n' | 140 '\n' |
115 'enum ConfigurationPolicyType {\n') | 141 'enum ConfigurationPolicyType {\n') |
116 for policy_name in _GetPolicyNameList(template_file_contents): | 142 for policy_name in _GetPolicyNameList(template_file_contents): |
117 f.write(' kPolicy' + policy_name + ",\n"); | 143 f.write(' kPolicy' + policy_name + ",\n"); |
118 f.write('};\n\n' | 144 f.write('};\n\n' |
119 '} // namespace policy\n\n' | 145 '} // namespace policy\n\n' |
120 '#endif // CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_TYPE_H_\n') | 146 '#endif // CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_TYPE_H_\n') |
121 | 147 |
122 | 148 |
123 def _GetPolicyNameList(template_file_contents): | 149 #------------------ policy protobuf --------------------------------# |
124 policy_names = []; | 150 PROTO_HEAD = ''' |
125 for policy in template_file_contents['policy_definitions']: | 151 syntax = "proto2"; |
126 if policy['type'] == 'group': | 152 |
127 for sub_policy in policy['policies']: | 153 option optimize_for = LITE_RUNTIME; |
128 policy_names.append(sub_policy['name']) | 154 |
129 else: | 155 package enterprise_management; |
130 policy_names.append(policy['name']) | 156 |
131 policy_names.sort() | 157 message StringList { |
132 return policy_names | 158 repeated string entries = 1; |
159 } | |
160 | |
161 message PolicyOptions { | |
162 enum PolicyMode { | |
163 // The given settings are applied regardless of user choice. | |
164 MANDATORY = 0; | |
165 // The user may choose to override the given settings. | |
166 RECOMMENDED = 1; | |
167 } | |
168 optional PolicyMode mode = 1 [default = MANDATORY]; | |
169 } | |
170 | |
171 ''' | |
133 | 172 |
134 | 173 |
135 def _LoadJSONFile(json_file): | 174 PROTOBUF_TYPE = { |
136 with open(json_file, "r") as f: | 175 'main': 'bool', |
137 text = f.read() | 176 'string': 'string', |
138 return eval(text) | 177 'string-enum': 'string', |
178 'int': 'int64', | |
179 'int-enum': 'int64', | |
180 'list': 'StringList', | |
181 } | |
139 | 182 |
140 | 183 |
184 def _WritePolicyProto(file, policy, fields): | |
185 file.write('message %sProto {\n' % policy['name']) | |
186 file.write(' optional PolicyOptions policy_options = 1;\n') | |
187 file.write(' optional %s %s = 2;\n' % | |
188 (PROTOBUF_TYPE[policy['type']], policy['name'])) | |
189 file.write('}\n\n') | |
190 fields += [' optional %sProto %s = %s;\n' % | |
191 (policy['name'], policy['name'], policy['id'] + 2)] | |
gfeher
2011/02/09 17:50:43
Nit: please extract 2 as a constant.
Jakob Kummerow
2011/02/10 12:10:15
Done.
| |
192 | |
193 | |
194 def _WriteProtobuf(template_file_contents, args, outfilepath): | |
195 with open(outfilepath, 'w') as f: | |
196 _OutputGeneratedWarningForC(f, args[1]) | |
197 f.write(PROTO_HEAD) | |
198 | |
199 fields = [] | |
200 f.write('// PBs for individual settings.\n\n') | |
201 for policy in template_file_contents['policy_definitions']: | |
202 if policy['type'] == 'group': | |
203 for sub_policy in policy['policies']: | |
204 _WritePolicyProto(f, sub_policy, fields) | |
205 else: | |
206 _WritePolicyProto(f, policy, fields) | |
207 | |
208 f.write('// --------------------------------------------------\n' | |
209 '// Big wrapper PB containing the above groups.\n\n' | |
210 'message CloudPolicySettings {\n') | |
211 f.write(''.join(fields)) | |
212 f.write('}\n\n') | |
213 | |
214 | |
215 #------------------ protobuf decoder -------------------------------# | |
216 CPP_HEAD = ''' | |
217 #include <limits> | |
218 #include <map> | |
219 #include <string> | |
220 | |
221 #include "base/logging.h" | |
222 #include "base/values.h" | |
223 #include "chrome/browser/policy/configuration_policy_provider.h" | |
224 #include "chrome/browser/policy/proto/device_management_backend.pb.h" | |
225 #include "policy/configuration_policy_type.h" | |
226 | |
227 using google::protobuf::RepeatedPtrField; | |
228 | |
229 namespace policy { | |
230 | |
231 namespace em = enterprise_management; | |
232 | |
233 Value* DecodeIntegerValue(google::protobuf::int64 value) { | |
234 if (value < std::numeric_limits<int>::min() || | |
235 value > std::numeric_limits<int>::max()) { | |
236 LOG(WARNING) << "Integer value " << value | |
237 << " out of numeric limits, ignoring."; | |
238 return NULL; | |
239 } | |
240 | |
241 return Value::CreateIntegerValue(static_cast<int>(value)); | |
242 } | |
243 | |
244 ListValue* DecodeStringList(const em::StringList& string_list) { | |
245 ListValue* list_value = new ListValue; | |
246 RepeatedPtrField<std::string>::const_iterator entry; | |
247 for (entry = string_list.entries().begin(); | |
248 entry != string_list.entries().end(); ++entry) { | |
249 list_value->Append(Value::CreateStringValue(*entry)); | |
250 } | |
251 return list_value; | |
252 } | |
253 | |
254 void DecodePolicy(const em::CloudPolicySettings& policy, | |
255 ConfigurationPolicyProvider::PolicyMapType* mandatory, | |
256 ConfigurationPolicyProvider::PolicyMapType* recommended) { | |
257 DCHECK(mandatory); | |
258 DCHECK(recommended); | |
259 ''' | |
260 | |
261 | |
262 CPP_FOOT = '''} | |
263 | |
264 } // namespace policy | |
265 ''' | |
266 | |
267 | |
268 def _CreateValue(type): | |
269 if type == 'main': | |
270 return "Value::CreateBooleanValue" | |
271 elif type in ('int', 'int-enum'): | |
272 return "DecodeIntegerValue" | |
273 elif type in ('string', 'string-enum'): | |
274 return "Value::CreateStringValue" | |
275 elif type == 'list': | |
276 return "DecodeStringList" | |
277 else: | |
278 raise NotImplementedError() | |
279 | |
280 | |
281 def _WritePolicyCode(file, policy): | |
282 membername = policy['name'].lower() | |
283 proto_type = "%sProto" % policy['name'] | |
284 proto_name = "%s_proto" % membername | |
285 file.write(' if (policy.has_%s()) {\n' % membername) | |
286 file.write(' const em::%s& %s = policy.%s();\n' % | |
287 (proto_type, proto_name, membername)) | |
288 file.write(' if (%s.has_%s()) {\n' % (proto_name, membername)) | |
289 file.write(' Value* value = %s(%s.%s());\n' % | |
290 (_CreateValue(policy['type']), proto_name, membername)) | |
291 file.write(' ConfigurationPolicyProvider::PolicyMapType* destination =' | |
292 ' mandatory;\n' | |
293 ' if (%s.has_policy_options()) {\n' | |
294 ' switch(%s.policy_options().mode()) {\n' % | |
295 (proto_name, proto_name)) | |
296 file.write(' case em::PolicyOptions::RECOMMENDED:\n' | |
297 ' destination = recommended;\n' | |
298 ' break;\n' | |
299 ' case em::PolicyOptions::MANDATORY:\n' | |
300 ' break;\n' | |
301 ' }\n' | |
302 ' }\n' | |
303 ' destination->insert(std::make_pair(kPolicy%s, value));\n' % | |
304 policy['name']) | |
305 file.write(' }\n' | |
306 ' }\n') | |
307 | |
308 | |
309 def _WriteProtobufParser(template_file_contents, args, outfilepath): | |
310 with open(outfilepath, 'w') as f: | |
311 _OutputGeneratedWarningForC(f, args[1]) | |
312 f.write(CPP_HEAD) | |
313 for policy in template_file_contents['policy_definitions']: | |
314 #policyname = policy['name'] | |
315 #membername = policyname.lower() | |
316 #proto_type = "%sProto" % policyname | |
317 #protoname = "%s_proto" % membername | |
318 #f.write(' if (policy.has_%s()) {\n' % membername) | |
319 #f.write(' const em::%s& %s = policy.%s();\n' % | |
320 # (proto_type, protoname, membername)) | |
gfeher
2011/02/09 17:50:43
Please clean comments.
Jakob Kummerow
2011/02/10 12:10:15
Sure. Done.
| |
321 if policy['type'] == 'group': | |
322 for sub_policy in policy['policies']: | |
323 _WritePolicyCode(f, sub_policy) | |
324 else: | |
325 _WritePolicyCode(f, policy) | |
326 f.write(CPP_FOOT) | |
327 | |
328 | |
329 #------------------ main() -----------------------------------------# | |
141 if __name__ == '__main__': | 330 if __name__ == '__main__': |
142 main(); | 331 main(); |
OLD | NEW |