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 # Field IDs [1..RESERVED_IDS] will not be used in the wrapping protobuf. |
| 185 RESERVED_IDS = 2 |
| 186 |
| 187 |
| 188 def _WritePolicyProto(file, policy, fields): |
| 189 file.write('message %sProto {\n' % policy['name']) |
| 190 file.write(' optional PolicyOptions policy_options = 1;\n') |
| 191 file.write(' optional %s %s = 2;\n' % |
| 192 (PROTOBUF_TYPE[policy['type']], policy['name'])) |
| 193 file.write('}\n\n') |
| 194 fields += [' optional %sProto %s = %s;\n' % |
| 195 (policy['name'], policy['name'], policy['id'] + RESERVED_IDS)] |
| 196 |
| 197 |
| 198 def _WriteProtobuf(template_file_contents, args, outfilepath): |
| 199 with open(outfilepath, 'w') as f: |
| 200 _OutputGeneratedWarningForC(f, args[1]) |
| 201 f.write(PROTO_HEAD) |
| 202 |
| 203 fields = [] |
| 204 f.write('// PBs for individual settings.\n\n') |
| 205 for policy in template_file_contents['policy_definitions']: |
| 206 if policy['type'] == 'group': |
| 207 for sub_policy in policy['policies']: |
| 208 _WritePolicyProto(f, sub_policy, fields) |
| 209 else: |
| 210 _WritePolicyProto(f, policy, fields) |
| 211 |
| 212 f.write('// --------------------------------------------------\n' |
| 213 '// Big wrapper PB containing the above groups.\n\n' |
| 214 'message CloudPolicySettings {\n') |
| 215 f.write(''.join(fields)) |
| 216 f.write('}\n\n') |
| 217 |
| 218 |
| 219 #------------------ protobuf decoder -------------------------------# |
| 220 CPP_HEAD = ''' |
| 221 #include <limits> |
| 222 #include <map> |
| 223 #include <string> |
| 224 |
| 225 #include "base/logging.h" |
| 226 #include "base/values.h" |
| 227 #include "chrome/browser/policy/configuration_policy_provider.h" |
| 228 #include "chrome/browser/policy/proto/device_management_backend.pb.h" |
| 229 #include "policy/configuration_policy_type.h" |
| 230 |
| 231 using google::protobuf::RepeatedPtrField; |
| 232 |
| 233 namespace policy { |
| 234 |
| 235 namespace em = enterprise_management; |
| 236 |
| 237 Value* DecodeIntegerValue(google::protobuf::int64 value) { |
| 238 if (value < std::numeric_limits<int>::min() || |
| 239 value > std::numeric_limits<int>::max()) { |
| 240 LOG(WARNING) << "Integer value " << value |
| 241 << " out of numeric limits, ignoring."; |
| 242 return NULL; |
| 243 } |
| 244 |
| 245 return Value::CreateIntegerValue(static_cast<int>(value)); |
| 246 } |
| 247 |
| 248 ListValue* DecodeStringList(const em::StringList& string_list) { |
| 249 ListValue* list_value = new ListValue; |
| 250 RepeatedPtrField<std::string>::const_iterator entry; |
| 251 for (entry = string_list.entries().begin(); |
| 252 entry != string_list.entries().end(); ++entry) { |
| 253 list_value->Append(Value::CreateStringValue(*entry)); |
| 254 } |
| 255 return list_value; |
| 256 } |
| 257 |
| 258 void DecodePolicy(const em::CloudPolicySettings& policy, |
| 259 ConfigurationPolicyProvider::PolicyMapType* mandatory, |
| 260 ConfigurationPolicyProvider::PolicyMapType* recommended) { |
| 261 DCHECK(mandatory); |
| 262 DCHECK(recommended); |
| 263 ''' |
| 264 |
| 265 |
| 266 CPP_FOOT = '''} |
| 267 |
| 268 } // namespace policy |
| 269 ''' |
| 270 |
| 271 |
| 272 def _CreateValue(type): |
| 273 if type == 'main': |
| 274 return "Value::CreateBooleanValue" |
| 275 elif type in ('int', 'int-enum'): |
| 276 return "DecodeIntegerValue" |
| 277 elif type in ('string', 'string-enum'): |
| 278 return "Value::CreateStringValue" |
| 279 elif type == 'list': |
| 280 return "DecodeStringList" |
| 281 else: |
| 282 raise NotImplementedError() |
| 283 |
| 284 |
| 285 def _WritePolicyCode(file, policy): |
| 286 membername = policy['name'].lower() |
| 287 proto_type = "%sProto" % policy['name'] |
| 288 proto_name = "%s_proto" % membername |
| 289 file.write(' if (policy.has_%s()) {\n' % membername) |
| 290 file.write(' const em::%s& %s = policy.%s();\n' % |
| 291 (proto_type, proto_name, membername)) |
| 292 file.write(' if (%s.has_%s()) {\n' % (proto_name, membername)) |
| 293 file.write(' Value* value = %s(%s.%s());\n' % |
| 294 (_CreateValue(policy['type']), proto_name, membername)) |
| 295 file.write(' ConfigurationPolicyProvider::PolicyMapType* destination =' |
| 296 ' mandatory;\n' |
| 297 ' if (%s.has_policy_options()) {\n' |
| 298 ' switch(%s.policy_options().mode()) {\n' % |
| 299 (proto_name, proto_name)) |
| 300 file.write(' case em::PolicyOptions::RECOMMENDED:\n' |
| 301 ' destination = recommended;\n' |
| 302 ' break;\n' |
| 303 ' case em::PolicyOptions::MANDATORY:\n' |
| 304 ' break;\n' |
| 305 ' }\n' |
| 306 ' }\n' |
| 307 ' destination->insert(std::make_pair(kPolicy%s, value));\n' % |
| 308 policy['name']) |
| 309 file.write(' }\n' |
| 310 ' }\n') |
| 311 |
| 312 |
| 313 def _WriteProtobufParser(template_file_contents, args, outfilepath): |
| 314 with open(outfilepath, 'w') as f: |
| 315 _OutputGeneratedWarningForC(f, args[1]) |
| 316 f.write(CPP_HEAD) |
| 317 for policy in template_file_contents['policy_definitions']: |
| 318 if policy['type'] == 'group': |
| 319 for sub_policy in policy['policies']: |
| 320 _WritePolicyCode(f, sub_policy) |
| 321 else: |
| 322 _WritePolicyCode(f, policy) |
| 323 f.write(CPP_FOOT) |
| 324 |
| 325 |
| 326 #------------------ main() -----------------------------------------# |
141 if __name__ == '__main__': | 327 if __name__ == '__main__': |
142 main(); | 328 main(); |
OLD | NEW |