Chromium Code Reviews| 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 |