Chromium Code Reviews| Index: chrome/tools/build/generate_policy_source.py |
| diff --git a/chrome/tools/build/generate_policy_source.py b/chrome/tools/build/generate_policy_source.py |
| index 1051092ece054d10ab6d4524bdecdef07fd38091..8b958989c8855278d31c5f75f379fd8e17c66a40 100644 |
| --- a/chrome/tools/build/generate_policy_source.py |
| +++ b/chrome/tools/build/generate_policy_source.py |
| @@ -29,6 +29,12 @@ def main(): |
| parser.add_option("--pth", "--policy-type-header", dest="type_path", |
| help="generate header file for policy type enumeration", |
| metavar="FILE"); |
| + parser.add_option("--ppb", "--policy-protobuf", dest="proto_path", |
| + help="generate cloud policy protobuf file", |
| + metavar="FILE"); |
| + parser.add_option("--ppd", "--protobuf-decoder", dest="decoder_path", |
| + help="generate C++ code decoding the policy protobuf", |
| + metavar="FILE"); |
| (opts, args) = parser.parse_args(); |
| @@ -38,27 +44,45 @@ def main(): |
| sys.exit(2) |
| template_file_contents = _LoadJSONFile(args[1]); |
| if opts.header_path is not None: |
| - _WritePolicyConstantHeader(template_file_contents, |
| - args, |
| - opts); |
| + _WritePolicyConstantHeader(template_file_contents, args, opts); |
| if opts.source_path is not None: |
| - _WritePolicyConstantSource(template_file_contents, |
| - args, |
| - opts); |
| + _WritePolicyConstantSource(template_file_contents, args, opts); |
| if opts.type_path is not None: |
| - _WritePolicyTypeEnumerationHeader(template_file_contents, |
| - args, |
| - opts); |
| + _WritePolicyTypeEnumerationHeader(template_file_contents, args, opts); |
| + if opts.proto_path is not None: |
| + _WriteProtobuf(template_file_contents, args, opts.proto_path) |
| + if opts.decoder_path is not None: |
| + _WriteProtobufParser(template_file_contents, args, opts.decoder_path) |
| +#------------------ shared helpers ---------------------------------# |
| def _OutputGeneratedWarningForC(f, template_file_path): |
| f.write('//\n' |
| '// DO NOT MODIFY THIS FILE DIRECTLY!\n' |
| '// IT IS GENERATED BY generate_policy_source.py\n' |
| - '// FROM ' + template_file_path + ' \n' |
| + '// FROM ' + template_file_path + '\n' |
| '//\n\n') |
| +def _GetPolicyNameList(template_file_contents): |
| + policy_names = []; |
| + for policy in template_file_contents['policy_definitions']: |
| + if policy['type'] == 'group': |
| + for sub_policy in policy['policies']: |
| + policy_names.append(sub_policy['name']) |
| + else: |
| + policy_names.append(policy['name']) |
| + policy_names.sort() |
| + return policy_names |
| + |
| + |
| +def _LoadJSONFile(json_file): |
| + with open(json_file, "r") as f: |
| + text = f.read() |
| + return eval(text) |
| + |
| + |
| +#------------------ policy constants header ------------------------# |
| def _WritePolicyConstantHeader(template_file_contents, args, opts): |
| platform = args[0]; |
| with open(opts.header_path, "w") as f: |
| @@ -80,6 +104,7 @@ def _WritePolicyConstantHeader(template_file_contents, args, opts): |
| '#endif // CHROME_COMMON_POLICY_CONSTANTS_H_\n') |
| +#------------------ policy constants source ------------------------# |
| def _WritePolicyConstantSource(template_file_contents, args, opts): |
| platform = args[0]; |
| with open(opts.source_path, "w") as f: |
| @@ -103,6 +128,7 @@ def _WritePolicyConstantSource(template_file_contents, args, opts): |
| '} // namespace policy\n') |
| +#------------------ policy type enumeration header -----------------# |
| def _WritePolicyTypeEnumerationHeader(template_file_contents, args, opts): |
| with open(opts.type_path, "w") as f: |
| _OutputGeneratedWarningForC(f, args[1]) |
| @@ -120,23 +146,186 @@ def _WritePolicyTypeEnumerationHeader(template_file_contents, args, opts): |
| '#endif // CHROME_BROWSER_POLICY_CONFIGURATION_POLICY_TYPE_H_\n') |
| -def _GetPolicyNameList(template_file_contents): |
| - policy_names = []; |
| - for policy in template_file_contents['policy_definitions']: |
| - if policy['type'] == 'group': |
| - for sub_policy in policy['policies']: |
| - policy_names.append(sub_policy['name']) |
| - else: |
| - policy_names.append(policy['name']) |
| - policy_names.sort() |
| - return policy_names |
| +#------------------ policy protobuf --------------------------------# |
| +PROTO_HEAD = ''' |
| +syntax = "proto2"; |
| +option optimize_for = LITE_RUNTIME; |
| -def _LoadJSONFile(json_file): |
| - with open(json_file, "r") as f: |
| - text = f.read() |
| - return eval(text) |
| +package enterprise_management; |
| + |
| +message StringList { |
| + repeated string entries = 1; |
| +} |
| + |
| +message PolicyOptions { |
| + enum PolicyMode { |
| + // The given settings are applied regardless of user choice. |
| + MANDATORY = 0; |
| + // The user may choose to override the given settings. |
| + RECOMMENDED = 1; |
| + } |
| + optional PolicyMode mode = 1 [default = MANDATORY]; |
| +} |
| + |
| +''' |
| + |
| + |
| +PROTOBUF_TYPE = { |
| + 'main': 'bool', |
| + 'string': 'string', |
| + 'string-enum': 'string', |
| + 'int': 'int64', |
| + 'int-enum': 'int64', |
| + 'list': 'StringList', |
| +} |
| + |
| + |
| +def _WritePolicyProto(file, policy, fields): |
| + file.write('message %sProto {\n' % policy['name']) |
| + file.write(' optional PolicyOptions policy_options = 1;\n') |
| + file.write(' optional %s %s = 2;\n' % |
| + (PROTOBUF_TYPE[policy['type']], policy['name'])) |
| + file.write('}\n\n') |
| + fields += [' optional %sProto %s = %s;\n' % |
| + (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.
|
| + |
| + |
| +def _WriteProtobuf(template_file_contents, args, outfilepath): |
| + with open(outfilepath, 'w') as f: |
| + _OutputGeneratedWarningForC(f, args[1]) |
| + f.write(PROTO_HEAD) |
| + |
| + fields = [] |
| + f.write('// PBs for individual settings.\n\n') |
| + for policy in template_file_contents['policy_definitions']: |
| + if policy['type'] == 'group': |
| + for sub_policy in policy['policies']: |
| + _WritePolicyProto(f, sub_policy, fields) |
| + else: |
| + _WritePolicyProto(f, policy, fields) |
| + |
| + f.write('// --------------------------------------------------\n' |
| + '// Big wrapper PB containing the above groups.\n\n' |
| + 'message CloudPolicySettings {\n') |
| + f.write(''.join(fields)) |
| + f.write('}\n\n') |
| + |
| + |
| +#------------------ protobuf decoder -------------------------------# |
| +CPP_HEAD = ''' |
| +#include <limits> |
| +#include <map> |
| +#include <string> |
| + |
| +#include "base/logging.h" |
| +#include "base/values.h" |
| +#include "chrome/browser/policy/configuration_policy_provider.h" |
| +#include "chrome/browser/policy/proto/device_management_backend.pb.h" |
| +#include "policy/configuration_policy_type.h" |
| + |
| +using google::protobuf::RepeatedPtrField; |
| + |
| +namespace policy { |
| + |
| +namespace em = enterprise_management; |
| + |
| +Value* DecodeIntegerValue(google::protobuf::int64 value) { |
| + if (value < std::numeric_limits<int>::min() || |
| + value > std::numeric_limits<int>::max()) { |
| + LOG(WARNING) << "Integer value " << value |
| + << " out of numeric limits, ignoring."; |
| + return NULL; |
| + } |
| + |
| + return Value::CreateIntegerValue(static_cast<int>(value)); |
| +} |
| + |
| +ListValue* DecodeStringList(const em::StringList& string_list) { |
| + ListValue* list_value = new ListValue; |
| + RepeatedPtrField<std::string>::const_iterator entry; |
| + for (entry = string_list.entries().begin(); |
| + entry != string_list.entries().end(); ++entry) { |
| + list_value->Append(Value::CreateStringValue(*entry)); |
| + } |
| + return list_value; |
| +} |
| + |
| +void DecodePolicy(const em::CloudPolicySettings& policy, |
| + ConfigurationPolicyProvider::PolicyMapType* mandatory, |
| + ConfigurationPolicyProvider::PolicyMapType* recommended) { |
| + DCHECK(mandatory); |
| + DCHECK(recommended); |
| +''' |
| + |
| + |
| +CPP_FOOT = '''} |
| + |
| +} // namespace policy |
| +''' |
| + |
| + |
| +def _CreateValue(type): |
| + if type == 'main': |
| + return "Value::CreateBooleanValue" |
| + elif type in ('int', 'int-enum'): |
| + return "DecodeIntegerValue" |
| + elif type in ('string', 'string-enum'): |
| + return "Value::CreateStringValue" |
| + elif type == 'list': |
| + return "DecodeStringList" |
| + else: |
| + raise NotImplementedError() |
| + |
| + |
| +def _WritePolicyCode(file, policy): |
| + membername = policy['name'].lower() |
| + proto_type = "%sProto" % policy['name'] |
| + proto_name = "%s_proto" % membername |
| + file.write(' if (policy.has_%s()) {\n' % membername) |
| + file.write(' const em::%s& %s = policy.%s();\n' % |
| + (proto_type, proto_name, membername)) |
| + file.write(' if (%s.has_%s()) {\n' % (proto_name, membername)) |
| + file.write(' Value* value = %s(%s.%s());\n' % |
| + (_CreateValue(policy['type']), proto_name, membername)) |
| + file.write(' ConfigurationPolicyProvider::PolicyMapType* destination =' |
| + ' mandatory;\n' |
| + ' if (%s.has_policy_options()) {\n' |
| + ' switch(%s.policy_options().mode()) {\n' % |
| + (proto_name, proto_name)) |
| + file.write(' case em::PolicyOptions::RECOMMENDED:\n' |
| + ' destination = recommended;\n' |
| + ' break;\n' |
| + ' case em::PolicyOptions::MANDATORY:\n' |
| + ' break;\n' |
| + ' }\n' |
| + ' }\n' |
| + ' destination->insert(std::make_pair(kPolicy%s, value));\n' % |
| + policy['name']) |
| + file.write(' }\n' |
| + ' }\n') |
| + |
| + |
| +def _WriteProtobufParser(template_file_contents, args, outfilepath): |
| + with open(outfilepath, 'w') as f: |
| + _OutputGeneratedWarningForC(f, args[1]) |
| + f.write(CPP_HEAD) |
| + for policy in template_file_contents['policy_definitions']: |
| + #policyname = policy['name'] |
| + #membername = policyname.lower() |
| + #proto_type = "%sProto" % policyname |
| + #protoname = "%s_proto" % membername |
| + #f.write(' if (policy.has_%s()) {\n' % membername) |
| + #f.write(' const em::%s& %s = policy.%s();\n' % |
| + # (proto_type, protoname, membername)) |
|
gfeher
2011/02/09 17:50:43
Please clean comments.
Jakob Kummerow
2011/02/10 12:10:15
Sure. Done.
|
| + if policy['type'] == 'group': |
| + for sub_policy in policy['policies']: |
| + _WritePolicyCode(f, sub_policy) |
| + else: |
| + _WritePolicyCode(f, policy) |
| + f.write(CPP_FOOT) |
| +#------------------ main() -----------------------------------------# |
| if __name__ == '__main__': |
| main(); |