_base.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. # -*- coding: utf-8 -*-
  2. # Copyright 2014 OpenMarket Ltd
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. import argparse
  16. import sys
  17. import os
  18. import yaml
  19. class ConfigError(Exception):
  20. pass
  21. class Config(object):
  22. def __init__(self, args):
  23. pass
  24. @staticmethod
  25. def abspath(file_path):
  26. return os.path.abspath(file_path) if file_path else file_path
  27. @classmethod
  28. def check_file(cls, file_path, config_name):
  29. if file_path is None:
  30. raise ConfigError(
  31. "Missing config for %s."
  32. " You must specify a path for the config file. You can "
  33. "do this with the -c or --config-path option. "
  34. "Adding --generate-config along with --server-name "
  35. "<server name> will generate a config file at the given path."
  36. % (config_name,)
  37. )
  38. if not os.path.exists(file_path):
  39. raise ConfigError(
  40. "File % config for %s doesn't exist."
  41. " Try running again with --generate-config"
  42. % (config_name,)
  43. )
  44. return cls.abspath(file_path)
  45. @staticmethod
  46. def ensure_directory(dir_path):
  47. if not os.path.exists(dir_path):
  48. os.makedirs(dir_path)
  49. if not os.path.isdir(dir_path):
  50. raise ConfigError(
  51. "%s is not a directory" % (dir_path,)
  52. )
  53. return dir_path
  54. @classmethod
  55. def read_file(cls, file_path, config_name):
  56. cls.check_file(file_path, config_name)
  57. with open(file_path) as file_stream:
  58. return file_stream.read()
  59. @staticmethod
  60. def default_path(name):
  61. return os.path.abspath(os.path.join(os.path.curdir, name))
  62. @staticmethod
  63. def read_config_file(file_path):
  64. with open(file_path) as file_stream:
  65. return yaml.load(file_stream)
  66. @classmethod
  67. def add_arguments(cls, parser):
  68. pass
  69. @classmethod
  70. def generate_config(cls, args, config_dir_path):
  71. pass
  72. @classmethod
  73. def load_config(cls, description, argv, generate_section=None):
  74. config_parser = argparse.ArgumentParser(add_help=False)
  75. config_parser.add_argument(
  76. "-c", "--config-path",
  77. metavar="CONFIG_FILE",
  78. help="Specify config file"
  79. )
  80. config_parser.add_argument(
  81. "--generate-config",
  82. action="store_true",
  83. help="Generate config file"
  84. )
  85. config_args, remaining_args = config_parser.parse_known_args(argv)
  86. if config_args.generate_config:
  87. if not config_args.config_path:
  88. config_parser.error(
  89. "Must specify where to generate the config file"
  90. )
  91. config_dir_path = os.path.dirname(config_args.config_path)
  92. if os.path.exists(config_args.config_path):
  93. defaults = cls.read_config_file(config_args.config_path)
  94. else:
  95. defaults = {}
  96. else:
  97. if config_args.config_path:
  98. defaults = cls.read_config_file(config_args.config_path)
  99. else:
  100. defaults = {}
  101. parser = argparse.ArgumentParser(
  102. parents=[config_parser],
  103. description=description,
  104. formatter_class=argparse.RawDescriptionHelpFormatter,
  105. )
  106. cls.add_arguments(parser)
  107. parser.set_defaults(**defaults)
  108. args = parser.parse_args(remaining_args)
  109. if config_args.generate_config:
  110. config_dir_path = os.path.dirname(config_args.config_path)
  111. config_dir_path = os.path.abspath(config_dir_path)
  112. if not os.path.exists(config_dir_path):
  113. os.makedirs(config_dir_path)
  114. cls.generate_config(args, config_dir_path)
  115. config = {}
  116. for key, value in vars(args).items():
  117. if (key not in set(["config_path", "generate_config"])
  118. and value is not None):
  119. config[key] = value
  120. with open(config_args.config_path, "w") as config_file:
  121. # TODO(paul) it would be lovely if we wrote out vim- and emacs-
  122. # style mode markers into the file, to hint to people that
  123. # this is a YAML file.
  124. yaml.dump(config, config_file, default_flow_style=False)
  125. print (
  126. "A config file has been generated in %s for server name"
  127. " '%s' with corresponding SSL keys and self-signed"
  128. " certificates. Please review this file and customise it to"
  129. " your needs."
  130. ) % (
  131. config_args.config_path, config['server_name']
  132. )
  133. print (
  134. "If this server name is incorrect, you will need to regenerate"
  135. " the SSL certificates"
  136. )
  137. sys.exit(0)
  138. return cls(args)