blob: 223bb84e7c27354a5c152241da3b040652e09575 [file] [log] [blame]
Ales Komarek166cc672016-07-27 14:17:22 +02001# -*- coding: utf-8 -*-
2'''
3Module for handling reclass files.
4
5'''
6
7from __future__ import absolute_import
8
9import logging
10import os
11import sys
12import yaml
13
14LOG = logging.getLogger(__name__)
15
16RECLASS_NODES_DIR = "/srv/salt/reclass/nodes"
17RECLASS_CLASSES_DIR = "/srv/salt/reclass/classes"
18
19def __virtual__():
20 '''
21 Only load this module if reclass
22 is installed on this minion.
23 '''
24 return 'reclass'
25
26
27__opts__ = {}
28
29
30def node_create(name, path=None, cluster="default", environment="prd", classes=None, parameters=None, **kwargs):
31 '''
32 Create a reclass node
33
34 :param name: new node FQDN
35 :param path: custom path in nodes for new node
36 :param classes: classes given to the new node
37 :param parameters: parameters given to the new node
38 :param environment: node's environment
39 :param cluster: node's cluster
40
41 CLI Examples:
42
43 .. code-block:: bash
44
45 salt '*' reclass.node_create server.domain.com classes=[system.neco1, system.neco2]
46 salt '*' reclass.node_create namespace/test enabled=False
47
48 '''
49 ret = {}
50
51 node = node_get(name=name)
52
53 if node and not "Error" in node:
54 LOG.debug("node {0} exists".format(name))
55 ret[name] = node
56 return ret
57
58 host_name = name.split('.')[0]
59 domain_name = '.'.join(name.split('.')[1:])
60
61 if classes == None:
62 meta_classes = []
63 else:
64 meta_classes = classes
65
66 if parameters == None:
67 meta_parameters = {}
68 else:
69 meta_parameters = parameters
70
71 node_meta = {
72 'classes': meta_classes,
73 'parameters': {
74 '_param': meta_parameters,
75 'linux': {
76 'system': {
77 'name': host_name,
78 'domain': domain_name,
79 'cluster': cluster,
80 'environment': environment,
81 }
82 }
83 }
84 }
85 LOG.debug(node_meta)
86
87 if path == None:
88 file_path = os.path.join(RECLASS_NODES_DIR, name + '.yml')
89 else:
90 file_path = os.path.join(RECLASS_NODES_DIR, path, name + '.yml')
91
92 with open(file_path, 'w') as node_file:
93 node_file.write(yaml.dump(node_meta, default_flow_style=False) )
94# ret[new.get('path_with_namespace')] = new
95 return node_get(name)
96
97def node_delete(name, **kwargs):
98 '''
99 Delete a reclass node
100
101 :params node: Node name
102
103 CLI Examples:
104
105 .. code-block:: bash
106
107 salt '*' reclass.node_delete demo01.domain.com
108 salt '*' reclass.node_delete name=demo01.domain.com
109 '''
110
111 node = node_get(name=name)
112
113 if 'Error' in node:
114 return {'Error': 'Unable to retreive node'}
115
116 if node[name]['path'] == '':
117 file_path = os.path.join(RECLASS_NODES_DIR, name + '.yml')
118 else:
119 file_path = os.path.join(RECLASS_NODES_DIR, node[name]['path'], name + '.yml')
120
121 os.remove(file_path)
122
123 ret = 'Node {0} deleted'.format(name)
124
125 return ret
126
127
128def node_get(name, path=None, **kwargs):
129 '''
130 Return a specific node
131
132 CLI Examples:
133
134 .. code-block:: bash
135
136 salt '*' reclass.node_get host01.domain.com
137 salt '*' reclass.node_get name=host02.domain.com
138 '''
139 ret = {}
140 nodes = node_list(**kwargs)
141
142 if not name in nodes:
143 return {'Error': 'Error in retrieving node'}
144 ret[name] = nodes[name]
145 return ret
146
147
148def node_list(**connection_args):
149 '''
150 Return a list of available nodes
151
152 CLI Example:
153
154 .. code-block:: bash
155
156 salt '*' reclass.node_list
157 '''
158 ret = {}
159
160 for root, sub_folders, files in os.walk(RECLASS_NODES_DIR):
161 for file in files:
162 file_path = os.path.join(root, file)
163 file_content = open(file_path, 'r')
164 file_data = yaml.load(file_content.read())
165 file_content.close()
166 if 'classes' in file_data:
167 classes = file_data.get('classes')
168 else:
169 classes = []
170 if 'parameters' in file_data:
171 if '_param' in file_data.get('parameters'):
172 parameters = file_data.get('parameters').get('_param')
173 else:
174 parameters = []
175 else:
176 parameters = []
177 name = file.replace('.yml', '')
178 host_name = name.split('.')[0]
179 domain_name = '.'.join(name.split('.')[1:])
180 path = root.replace(RECLASS_NODES_DIR+'/', '')
181 ret[name] = {
182 'name': host_name,
183 'domain': domain_name,
184 'cluster': 'default',
185 'environment': 'prd',
186 'path': path,
187 'classes': classes,
188 'parameters': parameters
189 }
190
191 return ret
192
193def node_update(name, classes=None, parameters=None, **connection_args):
194 '''
195 Update a node metadata information, classes and parameters.
196
197 CLI Examples:
198
199 .. code-block:: bash
200
201 salt '*' reclass.node_update name=nodename classes="[clas1, class2]"
202 '''
203 node = node_get(name=name)
204 if not node.has_key('Error'):
205 node = node[name.split("/")[1]]