blob: 93c4cf504a39834338e2e7959aedd601beb38bbe [file] [log] [blame]
Vasyl Saienkof9ee1582020-03-02 16:53:41 +02001#!/usr/bin/python3
2#
3# Copyright 2018 Mirantis, Inc.
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may
6# not use this file except in compliance with the License. You may obtain
7# a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations
15# under the License.
16
17
18"""Prepare metadata python module
19
20The module is aimed to prepare system files files (networking configs etc)
21based on lab metadata.
22
23Example:
24 python prepare-metadata --metadata-file '/etc/lab-metadata.yaml'
25
26Example of lab-metadata.yaml
27
28'52:54:00:10:94:78':
29 write_files:
30 - path: '/tmp/123.yaml'
31 content: |
32 foo: bar
33
34Attributes:
35 metadata-file - The file with metadata
36"""
37
38
39__version__ = '1.0'
40
41import argparse
42import os
43import yaml
44import logging
45import netifaces
46import sys
47
48LOG = logging.getLogger(__name__)
49
50
51def main():
52 logging.basicConfig(
53 format='%(asctime)s - %(levelname)s - %(message)s'
54 )
55 LOG.setLevel(logging.INFO)
56
57 parser = argparse.ArgumentParser(
58 description=('Render system files based on metadata')
59 )
60
61 group = parser.add_argument_group()
62 group.add_argument(
63 '--metadata-file',
64 help='The path to metadata file.',
65 required=True
66 )
67 args = parser.parse_args()
68
69 with open(args.metadata_file) as f:
70 metadata = yaml.safe_load(f)
71 node_meta = get_node_metadata(metadata)
72 if node_meta is not None:
73 LOG.info(f"Processing node_metadata: {node_meta}")
74 create_files(node_meta.get('write_files', []))
75 else:
76 LOG.error("No matches to MACs for node_metadata found")
77
78def get_interface_mac(iface_name):
79 mac = None
80 ifaddresses = netifaces.ifaddresses(iface_name)
81 link = ifaddresses.get(netifaces.AF_LINK, [])
82 if link:
83 return link[0]['addr']
84
85def get_node_macs():
86 ifaces = netifaces.interfaces()
87 macs = [get_interface_mac(iface_name) for iface_name in ifaces]
88 return [mac for mac in macs if mac is not None]
89
90def get_node_metadata(metadata):
91 for mac in get_node_macs():
92 if mac in metadata:
93 return metadata[mac]
94
95def create_files(files_meta):
96 for file_meta in files_meta:
97 path = file_meta['path']
98 content = file_meta['content']
99 permissions = int(str(file_meta.get('permissions', '644')), base=8)
100 with open(path, "w") as f:
101 f.write(content)
102 os.chmod(path, permissions)
103
104if __name__ == '__main__':
105 try:
106 main()
107 except Exception as e:
108 LOG.exception(f"Failed to apply image layout: {e}")
109 sys.exit(1)