Skip to content

Commit 6ae6c5b

Browse files
committed
salt: import salt-minion configuration from vyos-salt-minion
1 parent 7af1a76 commit 6ae6c5b

File tree

2 files changed

+288
-0
lines changed

2 files changed

+288
-0
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?xml version="1.0"?>
2+
<!--Salt-minion configuration -->
3+
<interfaceDefinition>
4+
<node name="service">
5+
<children>
6+
<node name="salt-minion" owner="${vyos_conf_scripts_dir}/salt-minion.py">
7+
<properties>
8+
<help>Salt Minion</help>
9+
<priority>500</priority>
10+
</properties>
11+
<children>
12+
<leafNode name="hash_type">
13+
<properties>
14+
<help>The hash_type is the hash to use when discovering the hash of a file on the master server.</help>
15+
</properties>
16+
</leafNode>
17+
<leafNode name="log_file">
18+
<properties>
19+
<help>The location of the minion log file.</help>
20+
</properties>
21+
</leafNode>
22+
<leafNode name="log_level">
23+
<properties>
24+
<help>Log level</help>
25+
<valueHelp>
26+
<format>garbage</format>
27+
<description>log garbage info</description>
28+
</valueHelp>
29+
<valueHelp>
30+
<format>trace</format>
31+
<description>log trace info</description>
32+
</valueHelp>
33+
<valueHelp>
34+
<format>debug</format>
35+
<description>log debug info</description>
36+
</valueHelp>
37+
<valueHelp>
38+
<format>info</format>
39+
<description>log info</description>
40+
</valueHelp>
41+
<valueHelp>
42+
<format>warning</format>
43+
<description>log warning info</description>
44+
</valueHelp>
45+
<valueHelp>
46+
<format>error</format>
47+
<description>log error info</description>
48+
</valueHelp>
49+
<valueHelp>
50+
<format>critical</format>
51+
<description>log critical info</description>
52+
</valueHelp>
53+
</properties>
54+
</leafNode>
55+
<leafNode name="master">
56+
<properties>
57+
<help>The hostname or IP address of the master.</help>
58+
<multi/>
59+
</properties>
60+
</leafNode>
61+
<leafNode name="id">
62+
<properties>
63+
<help>Explicitly declare the id for this minion to use.</help>
64+
</properties>
65+
</leafNode>
66+
<leafNode name="user">
67+
<properties>
68+
<help>The user to run the Salt processes.</help>
69+
</properties>
70+
</leafNode>
71+
<leafNode name="mine_interval">
72+
<properties>
73+
<help>The number of minutes between mine updates.</help>
74+
</properties>
75+
</leafNode>
76+
<leafNode name="master-key">
77+
<properties>
78+
<help>Enables verification of the master-public-signature returned by the master in auth-replies.</help>
79+
</properties>
80+
</leafNode>
81+
</children>
82+
</node>
83+
</children>
84+
</node>
85+
</interfaceDefinition>

src/conf_mode/salt-minion.py

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
#!/usr/bin/env python3
2+
#
3+
# Copyright (C) 2018 VyOS maintainers and contributors
4+
#
5+
# This program is free software; you can redistribute it and/or modify
6+
# it under the terms of the GNU General Public License version 2 or later as
7+
# published by the Free Software Foundation.
8+
#
9+
# This program is distributed in the hope that it will be useful,
10+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
# GNU General Public License for more details.
13+
#
14+
# You should have received a copy of the GNU General Public License
15+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
#
17+
#
18+
19+
import sys
20+
import os
21+
import pwd
22+
import socket
23+
import urllib3
24+
25+
import jinja2
26+
27+
from vyos.config import Config
28+
from vyos import ConfigError
29+
30+
config_file = r'/etc/salt/minion'
31+
32+
# Please be careful if you edit the template.
33+
config_tmpl = """
34+
### Autogenerated by salt-minion.py ###
35+
36+
##### Primary configuration settings #####
37+
##########################################
38+
39+
# The hash_type is the hash to use when discovering the hash of a file on
40+
# the master server. The default is sha256, but md5, sha1, sha224, sha384 and
41+
# sha512 are also supported.
42+
#
43+
# WARNING: While md5 and sha1 are also supported, do not use them due to the
44+
# high chance of possible collisions and thus security breach.
45+
#
46+
# Prior to changing this value, the master should be stopped and all Salt
47+
# caches should be cleared.
48+
hash_type: {{ hash_type }}
49+
50+
##### Logging settings #####
51+
##########################################
52+
# The location of the minion log file
53+
# The minion log can be sent to a regular file, local path name, or network
54+
# location. Remote logging works best when configured to use rsyslogd(8) (e.g.:
55+
# ``file:///dev/log``), with rsyslogd(8) configured for network logging. The URI
56+
# format is: <file|udp|tcp>://<host|socketpath>:<port-if-required>/<log-facility>
57+
#log_file: /var/log/salt/minion
58+
#log_file: file:///dev/log
59+
#log_file: udp://loghost:10514
60+
#
61+
log_file: {{ log_file }}
62+
63+
# The level of messages to send to the console.
64+
# One of 'garbage', 'trace', 'debug', info', 'warning', 'error', 'critical'.
65+
#
66+
# The following log levels are considered INSECURE and may log sensitive data:
67+
# ['garbage', 'trace', 'debug']
68+
#
69+
# Default: 'warning'
70+
log_level: {{ log_level }}
71+
72+
# Set the location of the salt master server, if the master server cannot be
73+
# resolved, then the minion will fail to start.
74+
master:
75+
{% for host in master -%}
76+
- {{ host }}
77+
{% endfor %}
78+
79+
# The user to run salt
80+
user: {{ user }}
81+
82+
# The directory to store the pki information in
83+
pki_dir: /config/salt/pki/minion
84+
85+
# Explicitly declare the id for this minion to use, if left commented the id
86+
# will be the hostname as returned by the python call: socket.getfqdn()
87+
# Since salt uses detached ids it is possible to run multiple minions on the
88+
# same machine but with different ids, this can be useful for salt compute
89+
# clusters.
90+
id: {{ salt_id }}
91+
92+
93+
# The number of minutes between mine updates.
94+
mine_interval: {{ mine_interval }}
95+
96+
verify_master_pubkey_sign: {{ verify_master_pubkey_sign }}
97+
"""
98+
99+
default_config_data = {
100+
'hash_type': 'sha256',
101+
'log_file': '/var/log/salt/minion',
102+
'log_level': 'warning',
103+
'master' : 'salt',
104+
'user': 'minion',
105+
'salt_id': socket.gethostname(),
106+
'mine_interval': '60',
107+
'verify_master_pubkey_sign': 'false'
108+
}
109+
110+
def get_config():
111+
salt = default_config_data
112+
conf = Config()
113+
if not conf.exists('service salt-minion'):
114+
return None
115+
else:
116+
conf.set_level('service salt-minion')
117+
118+
if conf.exists('hash_type'):
119+
salt['hash_type'] = conf.return_value('hash_type')
120+
121+
if conf.exists('log_file'):
122+
salt['log_file'] = conf.return_value('log_file')
123+
124+
if conf.exists('log_level'):
125+
salt['log_level'] = conf.return_value('log_level')
126+
127+
if conf.exists('master'):
128+
master = conf.return_values('master')
129+
salt['master'] = master
130+
131+
if conf.exists('id'):
132+
salt['salt_id'] = conf.return_value('id')
133+
134+
if conf.exists('user'):
135+
salt['user'] = conf.return_value('user')
136+
137+
if conf.exists('mine_interval'):
138+
salt['mine_interval'] = conf.return_value('mine_interval')
139+
140+
salt['master-key'] = None
141+
if conf.exists('master-key'):
142+
salt['master-key'] = conf.return_value('master-key')
143+
salt['verify_master_pubkey_sign'] = 'true'
144+
145+
return salt
146+
147+
def generate(salt):
148+
paths = ['/etc/salt/','/var/run/salt','/opt/vyatta/etc/config/salt/']
149+
directory = '/opt/vyatta/etc/config/salt/pki/minion'
150+
uid = pwd.getpwnam(salt['user']).pw_uid
151+
http = urllib3.PoolManager()
152+
153+
if salt is None:
154+
return None
155+
156+
if not os.path.exists(directory):
157+
os.makedirs(directory)
158+
159+
tmpl = jinja2.Template(config_tmpl)
160+
config_text = tmpl.render(salt)
161+
with open(config_file, 'w') as f:
162+
f.write(config_text)
163+
path = "/etc/salt/"
164+
for path in paths:
165+
for root, dirs, files in os.walk(path):
166+
for usgr in dirs:
167+
os.chown(os.path.join(root, usgr), uid, 100)
168+
for usgr in files:
169+
os.chown(os.path.join(root, usgr), uid, 100)
170+
171+
if not os.path.exists('/opt/vyatta/etc/config/salt/pki/minion/master_sign.pub'):
172+
if not salt['master-key'] is None:
173+
r = http.request('GET', salt['master-key'], preload_content=False)
174+
175+
with open('/opt/vyatta/etc/config/salt/pki/minion/master_sign.pub', 'wb') as out:
176+
while True:
177+
data = r.read(1024)
178+
if not data:
179+
break
180+
out.write(data)
181+
182+
r.release_conn()
183+
184+
return None
185+
186+
def apply(salt):
187+
if salt is not None:
188+
os.system("sudo systemctl restart salt-minion")
189+
else:
190+
# Salt access is removed in the commit
191+
os.system("sudo systemctl stop salt-minion")
192+
os.unlink(config_file)
193+
194+
return None
195+
196+
if __name__ == '__main__':
197+
try:
198+
c = get_config()
199+
generate(c)
200+
apply(c)
201+
except ConfigError as e:
202+
print(e)
203+
sys.exit(1)

0 commit comments

Comments
 (0)