/pentagon/migration/migrations/migration_2_7_1.py

https://github.com/reactiveops/pentagon
Python | 119 lines | 79 code | 32 blank | 8 comment | 17 complexity | 9347707caf79c5f5de336e66f39fbfc6 MD5 | raw file
  1. from copy import deepcopy
  2. from pentagon import migration
  3. import yaml
  4. import os
  5. import logging
  6. readme = """
  7. # Migration 2.7.1 -> 2.7.2
  8. ## This migration:
  9. - adds kubelet flags that were missing in the last migration to take advantage of the audit policy
  10. - made `anonymousAuth: false` default for Kops clusters. This currently conflicts with metricserver version > 3.0.0
  11. ## Risks:
  12. - this requires you to roll the cluster
  13. - metrics-server version compatibility
  14. ## Follow up tasks:
  15. - roll the cluster
  16. """
  17. # Magic to make block formatting in yaml.dump work as expected
  18. class folded_unicode(unicode):
  19. pass
  20. class literal_unicode(unicode):
  21. pass
  22. def folded_unicode_representer(dumper, data):
  23. return dumper.represent_scalar(u'tag:yaml.org,2002:str', data, style='>')
  24. def literal_unicode_representer(dumper, data):
  25. return dumper.represent_scalar(u'tag:yaml.org,2002:str', data, style='|')
  26. yaml.add_representer(folded_unicode, folded_unicode_representer)
  27. yaml.add_representer(literal_unicode, literal_unicode_representer)
  28. # https://stackoverflow.com/questions/6432605/any-yaml-libraries-in-python-that-support-dumping-of-long-strings-as-block-liter
  29. audit_settings = {
  30. 'auditLogPath': '/var/log/kube-apiserver-audit.log',
  31. 'auditLogMaxAge': 10,
  32. 'auditLogMaxBackups': 1,
  33. 'auditLogMaxSize': 100,
  34. 'auditPolicyFile': '/srv/kubernetes/audit.yaml'
  35. }
  36. class Migration(migration.Migration):
  37. _starting_version = '2.7.1'
  38. _ending_version = '2.7.2'
  39. _readme_string = readme
  40. def run(self):
  41. for item in self.inventory:
  42. inventory_path = "inventory/{}".format(item)
  43. # If there are no clusters, move on.
  44. if not os.path.isdir('{}/clusters/'.format(inventory_path)):
  45. continue
  46. for cluster_item in os.listdir('{}/clusters/'.format(inventory_path)):
  47. item_path = '{}/clusters/{}'.format(inventory_path, cluster_item)
  48. # Is this a kops cluster?
  49. # There is a small amount of variation here where some cluster config
  50. # directories are `cluster` and some are `cluster-config`
  51. # Align these
  52. if os.path.isdir("{}/cluster".format(item_path)):
  53. logging.info("Moving {item_path}/cluster to {item_path}/cluster-config".format(item_path))
  54. self.move("{}/cluster".format(item_path), "{}/cluster-config".format(item_path))
  55. if os.path.isdir(item_path) and os.path.exists("{}/cluster-config/cluster.yml".format(item_path)):
  56. logging.info("Migrating {} {}.".format(item, cluster_item))
  57. # Setup cluster spec with aws-iam auth and audit logging
  58. if True:
  59. cluster_spec_file = "{}/cluster-config/cluster.yml".format(item_path)
  60. with open(cluster_spec_file) as yaml_file:
  61. cluster_config = yaml.load(yaml_file.read())
  62. cluster_spec = cluster_config['spec']
  63. if cluster_spec.get('kubelet') is None:
  64. cluster_spec['kubelet'] = {}
  65. cluster_spec['kubelet']['anonymousAuth'] = False
  66. hooks = cluster_spec.get("hooks")
  67. if hooks:
  68. logging.debug(hooks)
  69. for hook in hooks:
  70. hook['manifest'] = literal_unicode(hook['manifest'])
  71. for policy_type in cluster_spec.get('additionalPolicies', {}):
  72. cluster_spec['additionalPolicies'][policy_type] = literal_unicode(cluster_spec['additionalPolicies'][policy_type])
  73. for fa in cluster_spec.get('fileAssets'):
  74. if fa.get('content'):
  75. fa['content'] = literal_unicode(fa['content'])
  76. kube_api_server = cluster_spec['kubeAPIServer']
  77. for setting, value in audit_settings.items():
  78. if kube_api_server.get(setting) != value:
  79. kube_api_server[setting] = value
  80. with open(cluster_spec_file, 'w') as yaml_file:
  81. yaml_file.write(yaml.dump(cluster_config, default_flow_style=False))