cloud-mu 3.6.10 → 3.6.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Berksfile +2 -3
- data/Berksfile.lock +11 -14
- data/bin/mu-aws-setup +16 -4
- data/bin/mu-configure +2 -1
- data/cloud-mu.gemspec +2 -2
- data/cookbooks/mu-firewall/Berksfile +1 -1
- data/cookbooks/mu-firewall/attributes/default.rb +2 -2
- data/cookbooks/mu-firewall/metadata.rb +3 -3
- data/cookbooks/mu-firewall/recipes/default.rb +11 -2
- data/cookbooks/mu-master/Berksfile +1 -1
- data/cookbooks/mu-master/attributes/default.rb +14 -1
- data/cookbooks/mu-master/files/default/389ds-perl/ASDialogs.pm +173 -0
- data/cookbooks/mu-master/files/default/389ds-perl/AdminMigration.pm +569 -0
- data/cookbooks/mu-master/files/default/389ds-perl/AdminServer.pm +952 -0
- data/cookbooks/mu-master/files/default/389ds-perl/AdminUtil.pm +983 -0
- data/cookbooks/mu-master/files/default/389ds-perl/ConfigDSDialogs.pm +449 -0
- data/cookbooks/mu-master/files/default/389ds-perl/DSCreate.pm +1551 -0
- data/cookbooks/mu-master/files/default/389ds-perl/DSDialogs.pm +233 -0
- data/cookbooks/mu-master/files/default/389ds-perl/DSMigration.pm +1175 -0
- data/cookbooks/mu-master/files/default/389ds-perl/DSUpdate.pm +534 -0
- data/cookbooks/mu-master/files/default/389ds-perl/DSUpdateDialogs.pm +152 -0
- data/cookbooks/mu-master/files/default/389ds-perl/DSUtil.pm +1710 -0
- data/cookbooks/mu-master/files/default/389ds-perl/Dialog.pm +249 -0
- data/cookbooks/mu-master/files/default/389ds-perl/DialogManager.pm +212 -0
- data/cookbooks/mu-master/files/default/389ds-perl/FileConn.pm +461 -0
- data/cookbooks/mu-master/files/default/389ds-perl/Inf.pm +268 -0
- data/cookbooks/mu-master/files/default/389ds-perl/Migration.pm +327 -0
- data/cookbooks/mu-master/files/default/389ds-perl/RegDSDialogs.pm +94 -0
- data/cookbooks/mu-master/files/default/389ds-perl/Resource.pm +137 -0
- data/cookbooks/mu-master/files/default/389ds-perl/Setup.pm +240 -0
- data/cookbooks/mu-master/files/default/389ds-perl/SetupDialogs.pm +243 -0
- data/cookbooks/mu-master/files/default/389ds-perl/SetupLog.pm +82 -0
- data/cookbooks/mu-master/files/default/setCertName.ldif +4 -0
- data/cookbooks/mu-master/libraries/mu.rb +2 -2
- data/cookbooks/mu-master/metadata.rb +1 -1
- data/cookbooks/mu-master/recipes/389ds.rb +71 -32
- data/cookbooks/mu-master/recipes/basepackages.rb +5 -0
- data/cookbooks/mu-master/recipes/default.rb +16 -5
- data/cookbooks/mu-master/recipes/init.rb +36 -3
- data/cookbooks/mu-master/recipes/ssl-certs.rb +6 -0
- data/cookbooks/mu-master/recipes/sssd.rb +85 -62
- data/cookbooks/mu-master/recipes/update_nagios_only.rb +7 -1
- data/cookbooks/mu-master/templates/default/389-directory-setup.inf.erb +11 -26
- data/cookbooks/mu-master/templates/default/sssd.conf.erb +18 -8
- data/cookbooks/mu-tools/files/default/Mu_CA.pem +33 -0
- data/cookbooks/mu-tools/metadata.rb +0 -1
- data/cookbooks/mu-tools/recipes/set_local_fw.rb +7 -1
- data/cookbooks/mu-tools/templates/amazon/sshd_config.erb +5 -1
- data/cookbooks/nagios/CHANGELOG.md +679 -0
- data/cookbooks/nagios/LICENSE +201 -0
- data/cookbooks/nagios/README.md +340 -0
- data/cookbooks/nagios/attributes/config.rb +163 -0
- data/cookbooks/nagios/attributes/default.rb +204 -0
- data/cookbooks/nagios/libraries/base.rb +311 -0
- data/cookbooks/nagios/libraries/command.rb +68 -0
- data/cookbooks/nagios/libraries/contact.rb +229 -0
- data/cookbooks/nagios/libraries/contactgroup.rb +111 -0
- data/cookbooks/{firewall/recipes/disable_firewall.rb → nagios/libraries/custom_option.rb} +20 -7
- data/cookbooks/nagios/libraries/data_bag_helper.rb +23 -0
- data/cookbooks/nagios/libraries/default.rb +90 -0
- data/cookbooks/nagios/libraries/helpers.rb +229 -0
- data/cookbooks/nagios/libraries/host.rb +410 -0
- data/cookbooks/nagios/libraries/hostdependency.rb +178 -0
- data/cookbooks/nagios/libraries/hostescalation.rb +170 -0
- data/cookbooks/nagios/libraries/hostgroup.rb +117 -0
- data/cookbooks/nagios/libraries/nagios.rb +277 -0
- data/cookbooks/nagios/libraries/resource.rb +59 -0
- data/cookbooks/nagios/libraries/service.rb +449 -0
- data/cookbooks/nagios/libraries/servicedependency.rb +213 -0
- data/cookbooks/nagios/libraries/serviceescalation.rb +193 -0
- data/cookbooks/nagios/libraries/servicegroup.rb +142 -0
- data/cookbooks/nagios/libraries/timeperiod.rb +159 -0
- data/cookbooks/nagios/libraries/users_helper.rb +54 -0
- data/cookbooks/nagios/metadata.json +44 -0
- data/cookbooks/nagios/metadata.rb +22 -0
- data/cookbooks/nagios/recipes/_load_databag_config.rb +153 -0
- data/cookbooks/nagios/recipes/_load_default_config.rb +241 -0
- data/cookbooks/nagios/recipes/apache.rb +114 -0
- data/cookbooks/nagios/recipes/default.rb +41 -0
- data/cookbooks/nagios/recipes/nginx.rb +114 -0
- data/cookbooks/nagios/recipes/pagerduty.rb +95 -0
- data/cookbooks/nagios/recipes/server.rb +182 -0
- data/cookbooks/nagios/recipes/server_package.rb +85 -0
- data/cookbooks/nagios/recipes/server_source.rb +137 -0
- data/cookbooks/nagios/resources/command.rb +34 -0
- data/cookbooks/nagios/resources/conf.rb +52 -0
- data/cookbooks/nagios/resources/contact.rb +34 -0
- data/cookbooks/nagios/resources/contactgroup.rb +35 -0
- data/cookbooks/nagios/resources/host.rb +35 -0
- data/cookbooks/nagios/resources/hostdependency.rb +35 -0
- data/cookbooks/nagios/resources/hostescalation.rb +36 -0
- data/cookbooks/nagios/resources/hostgroup.rb +35 -0
- data/cookbooks/nagios/resources/resource.rb +34 -0
- data/cookbooks/nagios/resources/service.rb +35 -0
- data/cookbooks/nagios/resources/servicedependency.rb +35 -0
- data/cookbooks/nagios/resources/serviceescalation.rb +35 -0
- data/cookbooks/nagios/resources/servicegroup.rb +35 -0
- data/cookbooks/nagios/resources/timeperiod.rb +35 -0
- data/cookbooks/nagios/templates/apache2.conf.erb +102 -0
- data/cookbooks/nagios/templates/cgi.cfg.erb +266 -0
- data/cookbooks/nagios/templates/commands.cfg.erb +13 -0
- data/cookbooks/nagios/templates/contacts.cfg.erb +37 -0
- data/cookbooks/nagios/templates/hostgroups.cfg.erb +25 -0
- data/cookbooks/nagios/templates/hosts.cfg.erb +15 -0
- data/cookbooks/nagios/templates/htpasswd.users.erb +6 -0
- data/cookbooks/nagios/templates/nagios.cfg.erb +22 -0
- data/cookbooks/nagios/templates/nginx.conf.erb +80 -0
- data/cookbooks/nagios/templates/pagerduty.cgi.erb +185 -0
- data/cookbooks/nagios/templates/resource.cfg.erb +27 -0
- data/cookbooks/nagios/templates/servicedependencies.cfg.erb +15 -0
- data/cookbooks/nagios/templates/servicegroups.cfg.erb +14 -0
- data/cookbooks/nagios/templates/services.cfg.erb +14 -0
- data/cookbooks/nagios/templates/spawn-fcgi.erb +10 -0
- data/cookbooks/nagios/templates/templates.cfg.erb +31 -0
- data/cookbooks/nagios/templates/timeperiods.cfg.erb +13 -0
- data/extras/platform_berksfile_base +3 -3
- data/extras/python_rpm/build.sh +4 -4
- data/extras/python_rpm/muthon.spec +2 -4
- data/extras/vault_tools/export_vaults.sh +11 -1
- data/install/installer +1 -1
- data/modules/mu/kittens.rb +27523 -0
- data/modules/mu/master/ldap.rb +48 -31
- data/modules/mu/master.rb +69 -0
- data/modules/mu/mu.yaml.rb +351 -0
- data/modules/mu/providers/aws/firewall_rule.rb +3 -1
- data/modules/mu/providers/aws.rb +11 -5
- data/modules/mu.rb +5 -4
- metadata +99 -48
- data/cookbooks/firewall/CHANGELOG.md +0 -488
- data/cookbooks/firewall/LICENSE +0 -202
- data/cookbooks/firewall/README.md +0 -366
- data/cookbooks/firewall/TODO.md +0 -6
- data/cookbooks/firewall/attributes/default.rb +0 -5
- data/cookbooks/firewall/attributes/firewalld.rb +0 -8
- data/cookbooks/firewall/attributes/iptables.rb +0 -17
- data/cookbooks/firewall/attributes/ufw.rb +0 -12
- data/cookbooks/firewall/attributes/windows.rb +0 -8
- data/cookbooks/firewall/libraries/helpers.rb +0 -105
- data/cookbooks/firewall/libraries/helpers_firewalld.rb +0 -116
- data/cookbooks/firewall/libraries/helpers_firewalld_dbus.rb +0 -72
- data/cookbooks/firewall/libraries/helpers_iptables.rb +0 -112
- data/cookbooks/firewall/libraries/helpers_nftables.rb +0 -170
- data/cookbooks/firewall/libraries/helpers_ufw.rb +0 -142
- data/cookbooks/firewall/libraries/helpers_windows.rb +0 -129
- data/cookbooks/firewall/libraries/provider_firewall_firewalld.rb +0 -179
- data/cookbooks/firewall/libraries/provider_firewall_iptables.rb +0 -171
- data/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu.rb +0 -200
- data/cookbooks/firewall/libraries/provider_firewall_iptables_ubuntu1404.rb +0 -200
- data/cookbooks/firewall/libraries/provider_firewall_rule.rb +0 -34
- data/cookbooks/firewall/libraries/provider_firewall_ufw.rb +0 -138
- data/cookbooks/firewall/libraries/provider_firewall_windows.rb +0 -126
- data/cookbooks/firewall/libraries/resource_firewall.rb +0 -26
- data/cookbooks/firewall/libraries/resource_firewall_rule.rb +0 -52
- data/cookbooks/firewall/metadata.json +0 -40
- data/cookbooks/firewall/metadata.rb +0 -15
- data/cookbooks/firewall/recipes/default.rb +0 -76
- data/cookbooks/firewall/recipes/firewalld.rb +0 -87
- data/cookbooks/firewall/resources/firewalld.rb +0 -28
- data/cookbooks/firewall/resources/firewalld_config.rb +0 -39
- data/cookbooks/firewall/resources/firewalld_helpers.rb +0 -106
- data/cookbooks/firewall/resources/firewalld_icmptype.rb +0 -88
- data/cookbooks/firewall/resources/firewalld_ipset.rb +0 -104
- data/cookbooks/firewall/resources/firewalld_policy.rb +0 -115
- data/cookbooks/firewall/resources/firewalld_service.rb +0 -98
- data/cookbooks/firewall/resources/firewalld_zone.rb +0 -118
- data/cookbooks/firewall/resources/nftables.rb +0 -71
- data/cookbooks/firewall/resources/nftables_rule.rb +0 -113
- data/cookbooks/firewall/templates/default/ufw/default.erb +0 -13
- /data/cookbooks/{firewall → nagios}/chefignore +0 -0
- /data/cookbooks/{firewall → nagios}/renovate.json +0 -0
data/modules/mu/master/ldap.rb
CHANGED
@@ -100,7 +100,7 @@ module MU
|
|
100
100
|
raise MuLDAPError, "When supply credentials to getLDAPConnection, both username and password must be specified"
|
101
101
|
end
|
102
102
|
if !username and !password
|
103
|
-
bind_creds = MU::Groomer::Chef.getSecret(vault: $MU_CFG["ldap"]["bind_creds"]["vault"], item:
|
103
|
+
bind_creds = MU::Groomer::Chef.getSecret(vault: $MU_CFG["ldap"]["bind_creds"]["vault"], item: "cfg_directory_adm")#$MU_CFG["ldap"]["bind_creds"]["item"])
|
104
104
|
username = bind_creds[$MU_CFG["ldap"]["bind_creds"]["username_field"]]
|
105
105
|
password = bind_creds[$MU_CFG["ldap"]["bind_creds"]["password_field"]]
|
106
106
|
end
|
@@ -210,6 +210,7 @@ module MU
|
|
210
210
|
:gidNumber => gid,
|
211
211
|
:objectclass => ["top", "posixGroup"]
|
212
212
|
}
|
213
|
+
|
213
214
|
if !@ldap_conn.add(
|
214
215
|
:dn => dn,
|
215
216
|
:attributes => attr
|
@@ -217,7 +218,7 @@ module MU
|
|
217
218
|
MU.log "Error creating #{dn}: "+getLDAPErr, MU::ERR, details: attr
|
218
219
|
return false
|
219
220
|
elsif @ldap_conn.get_operation_result.code != 68
|
220
|
-
MU.log "Created group #{dn} with gid #{gid}", MU::NOTICE
|
221
|
+
MU.log "Created group #{dn} with gid #{gid} (#{@ldap_conn.get_operation_result.message})", MU::NOTICE
|
221
222
|
end
|
222
223
|
return gid
|
223
224
|
end
|
@@ -235,7 +236,7 @@ module MU
|
|
235
236
|
MU.log "Custom directory service configured, not initializing bundled schema", MU::NOTICE
|
236
237
|
return
|
237
238
|
end
|
238
|
-
root_creds = MU::Groomer::Chef.getSecret(vault: "mu_ldap", item: "
|
239
|
+
root_creds = MU::Groomer::Chef.getSecret(vault: "mu_ldap", item: "cfg_directory_adm")
|
239
240
|
@ldap_conn = Net::LDAP.new(
|
240
241
|
:host => "127.0.0.1",
|
241
242
|
:encryption => {
|
@@ -252,7 +253,7 @@ module MU
|
|
252
253
|
)
|
253
254
|
|
254
255
|
# Manufacture our OU tree and groups
|
255
|
-
[$MU_CFG["ldap"]["base_dn"],
|
256
|
+
[ $MU_CFG["ldap"]["base_dn"],
|
256
257
|
"OU=Mu-System,#{$MU_CFG["ldap"]["base_dn"]}",
|
257
258
|
$MU_CFG["ldap"]["user_ou"],
|
258
259
|
$MU_CFG["ldap"]["group_ou"],
|
@@ -397,14 +398,14 @@ module MU
|
|
397
398
|
|
398
399
|
@can_write = true
|
399
400
|
if !conn.add(:dn => dn, :attributes => attr)
|
400
|
-
MU.log "Couldn't create write-test user #{dn},
|
401
|
+
MU.log "Couldn't create write-test user #{dn}, wll operate in read-only LDAP mode (#{getLDAPErr})", MU::NOTICE, details: attr
|
401
402
|
return false
|
402
403
|
end
|
403
404
|
|
404
405
|
# Make sure we can write various fields that we might need to touch
|
405
406
|
[:displayName, :mail, :givenName, :sn].each { |field|
|
406
407
|
if !conn.replace_attribute(dn, field, "foo@bar.com")
|
407
|
-
MU.log "Couldn't modify write-test user #{dn} field #{field.to_s},
|
408
|
+
MU.log "Couldn't modify write-test user #{dn} field #{field.to_s}, will operate in read-only LDAP mode (#{getLDAPErr})", MU::NOTICE
|
408
409
|
@can_write = false
|
409
410
|
|
410
411
|
end
|
@@ -431,11 +432,12 @@ module MU
|
|
431
432
|
# @param search [Array<String>]: Strings to search for.
|
432
433
|
# @param exact [Boolean]: Return only exact matches for whole fields.
|
433
434
|
# @param searchbase [String]: The DN under which to search.
|
435
|
+
# @param whole_desc [Boolean]: Return whole descriptors instead of just the DNs
|
434
436
|
# @return [Array<String>]
|
435
|
-
def self.findGroups(search = [], exact: false, searchbase:
|
436
|
-
if search.nil? or search.size == 0
|
437
|
-
raise MuLDAPError, "Need something to search for in MU::Master::LDAP.findGroups"
|
438
|
-
end
|
437
|
+
def self.findGroups(search = [], exact: false, searchbase: "OU=Groups,"+$MU_CFG['ldap']['base_dn'], whole_desc: false)
|
438
|
+
# if search.nil? or search.size == 0
|
439
|
+
# raise MuLDAPError, "Need something to search for in MU::Master::LDAP.findGroups"
|
440
|
+
# end
|
439
441
|
conn = getLDAPConnection
|
440
442
|
filter = nil
|
441
443
|
search.each { |term|
|
@@ -450,14 +452,19 @@ module MU
|
|
450
452
|
filter = filter | curfilter
|
451
453
|
end
|
452
454
|
}
|
453
|
-
filter =
|
455
|
+
filter = if filter
|
456
|
+
Net::LDAP::Filter.ne("objectclass", "computer") & (filter)
|
457
|
+
else
|
458
|
+
Net::LDAP::Filter.ne("objectclass", "computer")
|
459
|
+
end
|
454
460
|
groups = []
|
455
461
|
conn.search(
|
456
462
|
:filter => filter,
|
457
463
|
:base => searchbase,
|
458
|
-
:attributes => ["objectclass"]
|
464
|
+
:attributes => ["objectclass"] + (whole_desc ? ["description", @gidnum_attr, @member_attr] : [])
|
459
465
|
) do |group|
|
460
|
-
|
466
|
+
next if group.dn == searchbase
|
467
|
+
groups << (whole_desc ? group : group.dn)
|
461
468
|
end
|
462
469
|
groups
|
463
470
|
end
|
@@ -671,7 +678,7 @@ module MU
|
|
671
678
|
username_filter = Net::LDAP::Filter.eq("cn", cn)
|
672
679
|
end
|
673
680
|
user_filter = Net::LDAP::Filter.ne("objectclass", "computer") & Net::LDAP::Filter.ne("objectclass", "group")
|
674
|
-
fetchattrs = ["cn", @uid_attr, "displayName", "mail"]
|
681
|
+
fetchattrs = ["cn", @uid_attr, "displayName", "mail", "departmentNumber"]
|
675
682
|
fetchattrs << "employeeNumber" if $MU_CFG["ldap"]["type"] == "389 Directory Services"
|
676
683
|
conn.search(
|
677
684
|
:filter => username_filter & user_filter,
|
@@ -695,6 +702,9 @@ module MU
|
|
695
702
|
begin
|
696
703
|
users[acct[@uid_attr].first]['uid'] = acct.employeenumber.first
|
697
704
|
end rescue NoMethodError
|
705
|
+
begin
|
706
|
+
users[acct[@uid_attr].first]['gid'] = acct.departmentNumber.first
|
707
|
+
end rescue NoMethodError
|
698
708
|
end
|
699
709
|
}
|
700
710
|
}
|
@@ -898,22 +908,25 @@ module MU
|
|
898
908
|
manageGroup(group, add_users: [user])
|
899
909
|
}
|
900
910
|
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
|
905
|
-
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
|
913
|
-
|
914
|
-
|
911
|
+
# XXX SSSD is completely broken on Amazon 2023 for now. None of the below works.
|
912
|
+
# We're currently relying on MU::Master.manageUser to set up a unix-side
|
913
|
+
# user, old-school /etc/passwd style, in parallel to these LDAP entries.
|
914
|
+
# wait = 10
|
915
|
+
# begin
|
916
|
+
# %x{/usr/bin/getent passwd ; /usr/bin/getent group} # winbind is slow sometimes
|
917
|
+
# Etc.getpwnam(user)
|
918
|
+
# rescue ArgumentError
|
919
|
+
# if wait >= 30
|
920
|
+
# MU.log "User #{user} has been created in LDAP, but local system can't see it. Are PAM/LDAP configured correctly?", MU::ERR
|
921
|
+
# return false
|
922
|
+
# end
|
923
|
+
# MU.log "User #{user} has been created in LDAP, but not yet visible to local system, waiting #{wait}s and checking again.", MU::WARN
|
924
|
+
# sleep wait
|
925
|
+
# wait = wait + 5
|
926
|
+
# retry
|
927
|
+
# end if user != "mu"
|
915
928
|
%x{/sbin/restorecon -r /home} # SELinux stupidity that oddjob misses
|
916
|
-
MU::Master.setLocalDataPerms(user) if Etc.getpwuid(Process.uid).name == "root" and mu_acct
|
929
|
+
# MU::Master.setLocalDataPerms(user) if Etc.getpwuid(Process.uid).name == "root" and mu_acct
|
917
930
|
else
|
918
931
|
MU.log "We are in read-only LDAP mode. You must first create #{user} in your directory and add it to #{$MU_CFG["ldap"]["user_group_dn"]}. If the user is intended to be an admin, also add it to #{$MU_CFG["ldap"]["admin_group_dn"]}.", MU::WARN
|
919
932
|
return true
|
@@ -985,9 +998,13 @@ module MU
|
|
985
998
|
|
986
999
|
cur_users = listUsers
|
987
1000
|
if cur_users.has_key?(user)
|
1001
|
+
stubdir = File.join($MU_CFG['datadir'], "users", user)
|
1002
|
+
if !Dir.exist?(stubdir)
|
1003
|
+
Dir.mkdir(stubdir)
|
1004
|
+
end
|
988
1005
|
["realname", "email", "monitoring_email"].each { |field|
|
989
1006
|
next if !cur_users[user].has_key?(field)
|
990
|
-
File.open(
|
1007
|
+
File.open("#{stubdir}/#{field}", File::CREAT|File::RDWR, 0640) { |f|
|
991
1008
|
f.puts cur_users[user][field]
|
992
1009
|
}
|
993
1010
|
}
|
@@ -995,7 +1012,7 @@ module MU
|
|
995
1012
|
MU.log "Load of current user list didn't include #{user}, even though we just created them!", MU::WARN
|
996
1013
|
end
|
997
1014
|
|
998
|
-
MU::Master.setLocalDataPerms(user) if Etc.getpwuid(Process.uid).name == "root" and mu_acct
|
1015
|
+
# MU::Master.setLocalDataPerms(user) if Etc.getpwuid(Process.uid).name == "root" and mu_acct
|
999
1016
|
ok
|
1000
1017
|
end
|
1001
1018
|
|
data/modules/mu/master.rb
CHANGED
@@ -72,6 +72,46 @@ module MU
|
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
75
|
+
# Ensure that the existing list of LDAP groups has counterparts in
|
76
|
+
# /etc/group, and that all LDAP members also exist there.
|
77
|
+
# @return [Hash<String>]: A mapping of group names to gids
|
78
|
+
def self.syncGroups
|
79
|
+
groups = MU::Master::LDAP.findGroups(whole_desc: true)
|
80
|
+
ldapusers = MU::Master::LDAP.listUsers
|
81
|
+
groups.each { |g|
|
82
|
+
group_name = g.dn.split(/,/)[0].sub(/^cn=/i, '')
|
83
|
+
attempts = 0
|
84
|
+
group = begin
|
85
|
+
Etc.getgrnam(group_name)
|
86
|
+
rescue ArgumentError => e
|
87
|
+
MU.log "Creating unix group #{group_name} with gid #{g.gidnumber.first}", MU::NOTICE
|
88
|
+
attempts += 1
|
89
|
+
puts %x{/usr/sbin/groupadd --gid #{g.gidnumber.first} #{group_name}}
|
90
|
+
if attempts < 3
|
91
|
+
retry
|
92
|
+
else
|
93
|
+
raise MuError, "Failed to create group #{group_name}"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
if group.gid != g.gidnumber.first.to_i
|
97
|
+
raise MuError, "GID #{group.gid.to_s} for group #{group_name} doesn't agree with LDAP, which says #{g.gidnumber.first}"
|
98
|
+
end
|
99
|
+
|
100
|
+
g.memberuid.each { |user|
|
101
|
+
begin
|
102
|
+
Etc.getpwnam(user)
|
103
|
+
rescue ArgumentError
|
104
|
+
next
|
105
|
+
end
|
106
|
+
|
107
|
+
if ldapusers[user] and !group.mem.include?(user)
|
108
|
+
MU.log "Adding #{user} to group #{group_name}", MU::NOTICE
|
109
|
+
puts %x{/usr/sbin/groupmod --append #{group_name} --users #{user}}
|
110
|
+
end
|
111
|
+
}
|
112
|
+
}
|
113
|
+
end
|
114
|
+
|
75
115
|
# Create and/or update a user as appropriate (Chef, LDAP, et al).
|
76
116
|
# @param username [String]: The canonical username to modify.
|
77
117
|
# @param chef_username [String]: The Chef username, if different
|
@@ -99,12 +139,39 @@ module MU
|
|
99
139
|
deleteUser(username) if create
|
100
140
|
return false
|
101
141
|
end
|
142
|
+
ldapusers = MU::Master::LDAP.listUsers
|
143
|
+
if !ldapusers[username]
|
144
|
+
MU.log "#{username} wasn't in LDAP after I added it, I don't know what to do", MU::ERR
|
145
|
+
deleteUser(username) if create
|
146
|
+
return false
|
147
|
+
end
|
148
|
+
|
149
|
+
# XXX the following insecure jank is a workaround for the fact that SSSD
|
150
|
+
# is flat broken on Amazon Linux 2023. We're managing unix passwd and
|
151
|
+
# group entries like cavemen.
|
152
|
+
ldap_desc = ldapusers[username]
|
153
|
+
begin
|
154
|
+
Etc.getpwnam(username)
|
155
|
+
rescue
|
156
|
+
syncGroups
|
157
|
+
MU.log "Creating unix user #{username}", MU::NOTICE, ldap_desc
|
158
|
+
# XXX plain-text password visible in ps! horrible!
|
159
|
+
puts %x{/usr/sbin/adduser "#{username}" --uid #{ldap_desc['uid']} --gid #{ldap_desc['gid']} --no-user-group --comment '#{ldap_desc['realname']},#{ldap_desc['email']},,,' --password '#{password}'}
|
160
|
+
end
|
161
|
+
syncGroups
|
102
162
|
%x{sh -x /etc/init.d/oddjobd start 2>&1 > /dev/null} # oddjobd dies, like a lot
|
103
163
|
begin
|
104
164
|
Etc.getpwnam(username)
|
165
|
+
if password # setting a new password for an existing user
|
166
|
+
MU.log "Updating unix password for #{username}", MU::NOTICE
|
167
|
+
# XXX plain-text password visible in ps! horrible!
|
168
|
+
%x{echo '#{username}:#{password}' | /usr/sbin/chpasswd}
|
169
|
+
end
|
105
170
|
rescue ArgumentError
|
106
171
|
return false
|
107
172
|
end
|
173
|
+
|
174
|
+
|
108
175
|
chef_username ||= username.dup
|
109
176
|
%x{/bin/su - #{username} -c "ls > /dev/null"}
|
110
177
|
if !MU::Master::Chef.manageUser(chef_username, ldap_user: username, name: name, email: email, admin: admin, orgs: orgs, remove_orgs: remove_orgs) and create
|
@@ -157,6 +224,8 @@ module MU
|
|
157
224
|
end
|
158
225
|
MU::Master::Chef.deleteUser(user)
|
159
226
|
MU::Master::LDAP.deleteUser(user)
|
227
|
+
puts %x{/usr/sbin/userdel "#{user}"}
|
228
|
+
puts %x{/usr/sbin/groupdel "#{user}.mu-user"}
|
160
229
|
FileUtils.rm_rf(deletia)
|
161
230
|
end
|
162
231
|
|
@@ -0,0 +1,351 @@
|
|
1
|
+
# Configuration schema for mu.yaml. See also {https://github.com/cloudamatic/mu/wiki/Configuration the Mu wiki}.
|
2
|
+
#
|
3
|
+
# Example:
|
4
|
+
#
|
5
|
+
# <pre>
|
6
|
+
# ---
|
7
|
+
# public_address: 1.2.3.4
|
8
|
+
# mu_admin_email: egtlabs@eglobaltech.com
|
9
|
+
# mu_admin_name: Joe Schmoe
|
10
|
+
# mommacat_port: 2260
|
11
|
+
# banner: My Example Mu Master
|
12
|
+
# mu_repository: git://github.com/cloudamatic/mu.git
|
13
|
+
# repos:
|
14
|
+
# - https://github.com/cloudamatic/mu_demo_platform
|
15
|
+
# allow_invade_foreign_vpcs: true
|
16
|
+
# ansible_dir:
|
17
|
+
# aws:
|
18
|
+
# egtdev:
|
19
|
+
# region: us-east-1
|
20
|
+
# log_bucket_name: egt-mu-log-bucket
|
21
|
+
# default: true
|
22
|
+
# name: egtdev
|
23
|
+
# personal:
|
24
|
+
# region: us-east-2
|
25
|
+
# log_bucket_name: my-mu-log-bucket
|
26
|
+
# name: personal
|
27
|
+
# google:
|
28
|
+
# egtlabs:
|
29
|
+
# project: egt-labs-admin
|
30
|
+
# credentials_file: /opt/mu/etc/google.json
|
31
|
+
# region: us-east4
|
32
|
+
# log_bucket_name: hexabucket-761234
|
33
|
+
# default: true
|
34
|
+
# </pre>
|
35
|
+
module MuYAML
|
36
|
+
# The configuration file format for Mu's main config file.
|
37
|
+
# Adoption Change Notifications
|
38
|
+
class adopt_change_notify
|
39
|
+
# @!group Optional parameters
|
40
|
+
|
41
|
+
# Report modifications to adopted resources, detected by mu-adopt --diff, to the Slack webhook and channel configured under Slack Configuration.
|
42
|
+
#
|
43
|
+
# @return [Boolean]
|
44
|
+
attr_accessor :slack
|
45
|
+
|
46
|
+
# If a list of details about a modified resources is longer than this number of lines (in JSON), it will be sent as an "attachment," which in Slack means a blockquote that displays a few lines with a "Show more" button. The internal default is 5 lines.
|
47
|
+
#
|
48
|
+
# @return [String]
|
49
|
+
attr_accessor :slack_snippet_threshold
|
50
|
+
# @!endgroup
|
51
|
+
end
|
52
|
+
# Amazon Web Services
|
53
|
+
class aws
|
54
|
+
# @!group Required parameters
|
55
|
+
|
56
|
+
# **REQUIRED** -
|
57
|
+
# S3 bucket into which we'll synchronize deploy secrets, and if we're hosted in AWS, collected system logs
|
58
|
+
#
|
59
|
+
# @return [String]
|
60
|
+
attr_accessor :log_bucket_name
|
61
|
+
# @!endgroup
|
62
|
+
# @!group Optional parameters
|
63
|
+
|
64
|
+
# **Must match pattern `(?i-mx:^[a-z0-9]+$)`** -
|
65
|
+
# Credentials used for accessing the AWS API (looks like: AKIAINWLOOAA24PBRBZA)
|
66
|
+
#
|
67
|
+
# @return [String]
|
68
|
+
attr_accessor :access_key
|
69
|
+
|
70
|
+
# Credentials used for accessing the AWS API (looks like: +Z16iRP9QAq7EcjHINyEMs3oR7A76QpfaSgCBogp).
|
71
|
+
#
|
72
|
+
# @return [String]
|
73
|
+
attr_accessor :access_secret
|
74
|
+
|
75
|
+
# **Must match pattern `(?-mix:^\d+$)`** -
|
76
|
+
# Default target account for resources managed using these credentials. This is an AWS account number, e.g. 918972669773. If not specified, we will use the account number which owns these API keys.
|
77
|
+
#
|
78
|
+
# @return [String]
|
79
|
+
attr_accessor :account_number
|
80
|
+
|
81
|
+
# A secure Chef vault and item from which to retrieve an AWS access key and secret. The vault item should have 'access_key' and 'access_secret' elements.
|
82
|
+
#
|
83
|
+
# @return [String]
|
84
|
+
attr_accessor :credentials
|
85
|
+
|
86
|
+
# An INI-formatted AWS credentials file, of the type used by the AWS command-line tools. This is less secure than using 'credentials' to store these in a Chef vault. See: https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html
|
87
|
+
#
|
88
|
+
# @return [String]
|
89
|
+
attr_accessor :credentials_file
|
90
|
+
|
91
|
+
# **Default: `false`** -
|
92
|
+
# If set to true, Mu will default to these AWS credentials when targeting AWS resources
|
93
|
+
#
|
94
|
+
# @return [Boolean]
|
95
|
+
attr_accessor :default
|
96
|
+
|
97
|
+
# Default Amazon Web Services region in which these credentials should operate
|
98
|
+
#
|
99
|
+
# @return [String]
|
100
|
+
attr_accessor :region
|
101
|
+
# @!endgroup
|
102
|
+
end
|
103
|
+
# Microsoft Azure Cloud Computing Platform & Services
|
104
|
+
class azure
|
105
|
+
# @!group Optional parameters
|
106
|
+
|
107
|
+
# App client id used to authenticate to our subscription. From https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredAppsPreview
|
108
|
+
#
|
109
|
+
# @return [String]
|
110
|
+
attr_accessor :client_id
|
111
|
+
|
112
|
+
# App client secret used to authenticate to our subscription. From https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredAppsPreview under the 'Certificates & secrets' tab, 'Client secrets.' This can only be retrieved upon initial secret creation.
|
113
|
+
#
|
114
|
+
# @return [String]
|
115
|
+
attr_accessor :client_secret
|
116
|
+
|
117
|
+
# JSON file which contains a hash of directory_id, client_id, client_secret, and subscription values. If found, these will be override values entered directly in mu-configure.
|
118
|
+
#
|
119
|
+
# @return [String]
|
120
|
+
attr_accessor :credentials_file
|
121
|
+
|
122
|
+
# **Default: `false`** -
|
123
|
+
# If set to true, Mu will use this set of Azure credentials when targeting Azure without a specific account having been requested
|
124
|
+
#
|
125
|
+
# @return [Boolean]
|
126
|
+
attr_accessor :default
|
127
|
+
|
128
|
+
# AKA Tenant ID; the default Microsoft Azure Directory project in which we operate and deploy, from https://portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredAppsPreview
|
129
|
+
#
|
130
|
+
# @return [String]
|
131
|
+
attr_accessor :directory_id
|
132
|
+
|
133
|
+
# **Default: `eastus`** -
|
134
|
+
# Default Microsoft Azure region in which we operate and deploy
|
135
|
+
#
|
136
|
+
# @return [String]
|
137
|
+
attr_accessor :region
|
138
|
+
|
139
|
+
# Default Microsoft Azure Subscription we will use to deploy, from https://portal.azure.com/#blade/Microsoft_Azure_Billing/SubscriptionsBlade
|
140
|
+
#
|
141
|
+
# @return [String]
|
142
|
+
attr_accessor :subscription
|
143
|
+
# @!endgroup
|
144
|
+
end
|
145
|
+
# Google Cloud Platform
|
146
|
+
class google
|
147
|
+
# @!group Required parameters
|
148
|
+
|
149
|
+
# **REQUIRED** -
|
150
|
+
# Cloud Storage bucket into which we'll synchronize deploy secrets, and if we're hosted in GCP, collected system logs
|
151
|
+
#
|
152
|
+
# @return [String]
|
153
|
+
attr_accessor :log_bucket_name
|
154
|
+
|
155
|
+
# **REQUIRED** -
|
156
|
+
# Default Google Cloud Platform project in which we operate and deploy. Generate a service account at: https://console.cloud.google.com/iam-admin/serviceaccounts/project, making sure the account has sufficient privileges to manage cloud resources. Download the private key as JSON, and import that key to the vault specified here. Import example: knife vault create secrets google -J my-google-service-account.json
|
157
|
+
#
|
158
|
+
# @return [String]
|
159
|
+
attr_accessor :project
|
160
|
+
# @!endgroup
|
161
|
+
# @!group Optional parameters
|
162
|
+
|
163
|
+
# A secure Chef vault and item from which to retrieve the JSON-formatted Service Account credentials for our GCP account, in the format vault:itemname (e.g. 'secrets:google'). Generate a service account at: https://console.cloud.google.com/iam-admin/serviceaccounts/project, making sure the account has sufficient privileges to manage cloud resources. Download the private key as JSON, and import that key to the vault specified here. Import example: knife vault create secrets google -J my-google-service-account.json
|
164
|
+
#
|
165
|
+
# @return [String]
|
166
|
+
attr_accessor :credentials
|
167
|
+
|
168
|
+
# JSON-formatted Service Account credentials for our GCP account, b64-encoded and dropped directly into mu.yaml. Generate a service account at: https://console.cloud.google.com/iam-admin/serviceaccounts/project, making sure the account has sufficient privileges to manage cloud resources. Download the private key as JSON and point this argument to the file. This is less secure than using 'credentials' to store in a vault.
|
169
|
+
#
|
170
|
+
# @return [String]
|
171
|
+
attr_accessor :credentials_encoded
|
172
|
+
|
173
|
+
# JSON-formatted Service Account credentials for our GCP account, stored in plain text in a file. Generate a service account at: https://console.cloud.google.com/iam-admin/serviceaccounts/project, making sure the account has sufficient privileges to manage cloud resources. Download the private key as JSON and point this argument to the file. This is less secure than using 'credentials' to store in a vault.
|
174
|
+
#
|
175
|
+
# @return [String]
|
176
|
+
attr_accessor :credentials_file
|
177
|
+
|
178
|
+
# For Google Cloud projects which are attached to a GSuite domain. Some API calls (groups, users, etc) require this identifier. From admin.google.com, choose Security, the Single Sign On, and look for the Entity ID field. The value after idpid= in the URL there should be the customer ID.
|
179
|
+
#
|
180
|
+
# @return [String]
|
181
|
+
attr_accessor :customer_id
|
182
|
+
|
183
|
+
# **Default: `false`** -
|
184
|
+
# If set to true, Mu will use this set of GCP credentials when targeting the Google Cloud without a specific account having been requested
|
185
|
+
#
|
186
|
+
# @return [Boolean]
|
187
|
+
attr_accessor :default
|
188
|
+
|
189
|
+
# Optional list of projects to ignore, for credentials which have visibility into multiple projects
|
190
|
+
#
|
191
|
+
# @return [Array<String>]
|
192
|
+
attr_accessor :ignore_habitats
|
193
|
+
|
194
|
+
# For Google Cloud projects which are attached to a GSuite domain. GCP service accounts cannot view or manage GSuite resources (groups, users, etc) directly, but must instead masquerade as a GSuite user which has delegated authority to the service account. See also: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority
|
195
|
+
#
|
196
|
+
# @return [String]
|
197
|
+
attr_accessor :masequerade_as
|
198
|
+
|
199
|
+
# For credential sets which have access to multiple GSuite or Cloud Identity orgs, you must specify a default organization (e.g. my.domain.com).
|
200
|
+
#
|
201
|
+
# @return [String]
|
202
|
+
attr_accessor :org
|
203
|
+
|
204
|
+
# **Default: `us-east4`** -
|
205
|
+
# Default Google Cloud Platform region in which we operate and deploy
|
206
|
+
#
|
207
|
+
# @return [String]
|
208
|
+
attr_accessor :region
|
209
|
+
|
210
|
+
# Optional list of projects to which we'll restrict all of our activities.
|
211
|
+
#
|
212
|
+
# @return [Array<String>]
|
213
|
+
attr_accessor :restrict_to_habitats
|
214
|
+
# @!endgroup
|
215
|
+
end
|
216
|
+
# Slack Configuration
|
217
|
+
class slack
|
218
|
+
# @!group Optional parameters
|
219
|
+
|
220
|
+
# The channel name (without leading #) to which alerts should be sent.
|
221
|
+
#
|
222
|
+
# @return [String]
|
223
|
+
attr_accessor :channel
|
224
|
+
|
225
|
+
# The hooks.slack.com URL for the webook to which we'll send deploy notifications
|
226
|
+
#
|
227
|
+
# @return [String]
|
228
|
+
attr_accessor :webhook
|
229
|
+
# @!endgroup
|
230
|
+
end
|
231
|
+
# @!group Required parameters
|
232
|
+
|
233
|
+
# **REQUIRED**,
|
234
|
+
# **Must match pattern `(?i-mx:^[a-z0-9\-_]+$)`** -
|
235
|
+
# The local system's value for HOSTNAME
|
236
|
+
#
|
237
|
+
# @return [String]
|
238
|
+
attr_accessor :hostname
|
239
|
+
|
240
|
+
# **REQUIRED**,
|
241
|
+
# **Must match pattern `(?i-mx:\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z)`** -
|
242
|
+
# Administative contact email
|
243
|
+
#
|
244
|
+
# @return [String]
|
245
|
+
attr_accessor :mu_admin_email
|
246
|
+
|
247
|
+
# **REQUIRED**,
|
248
|
+
# **Must match pattern `(?-mix:^(127\.0\.0\.1|localhost)$)`** -
|
249
|
+
# IP address or hostname
|
250
|
+
#
|
251
|
+
# @return [String]
|
252
|
+
attr_accessor :public_address
|
253
|
+
# @!endgroup
|
254
|
+
# @!group Optional parameters
|
255
|
+
|
256
|
+
# Adoption Change Notifications
|
257
|
+
#
|
258
|
+
# @return [adopt_change_notify]
|
259
|
+
# @see adopt_change_notify
|
260
|
+
attr_accessor :adopt_change_notify
|
261
|
+
|
262
|
+
# **Default: `false`** -
|
263
|
+
# Ordinarily, Mu will automatically name, tag and generate auxiliary resources in a standard Mu-ish fashion that allows for deployment of multiple clones of a given stack. Toggling this flag will change the default behavior of mu-adopt, when it creates stack descriptors from found resources, to enable or disable this behavior (see also mu-adopt's --scrub option).
|
264
|
+
#
|
265
|
+
# @return [Boolean]
|
266
|
+
attr_accessor :adopt_scrub_mu_isms
|
267
|
+
|
268
|
+
# If set to true, Mu will be allowed to modify routing and peering behavior of VPCs which it did not create, but for which it has permissions.
|
269
|
+
#
|
270
|
+
# @return [Boolean]
|
271
|
+
attr_accessor :allow_invade_foreign_vpcs
|
272
|
+
|
273
|
+
# Intended for use with minimal installs which use Ansible as a groomer and which do not store Ansible artifacts in a dedicated git repository. This allows simply pointing to a local directory.
|
274
|
+
#
|
275
|
+
# @return [String]
|
276
|
+
attr_accessor :ansible_dir
|
277
|
+
|
278
|
+
# Amazon Web Services
|
279
|
+
#
|
280
|
+
# @return [aws]
|
281
|
+
# @see aws
|
282
|
+
attr_accessor :aws
|
283
|
+
|
284
|
+
# Microsoft Azure Cloud Computing Platform & Services
|
285
|
+
#
|
286
|
+
# @return [azure]
|
287
|
+
# @see azure
|
288
|
+
attr_accessor :azure
|
289
|
+
|
290
|
+
# Login banner, displayed in various locations
|
291
|
+
#
|
292
|
+
# @return [String]
|
293
|
+
attr_accessor :banner
|
294
|
+
|
295
|
+
# **Default: `false`** -
|
296
|
+
# Disable the Momma Cat grooming daemon. Nodes which require asynchronous Ansible/Chef bootstraps will not function. This option is only honored in gem-based installations.
|
297
|
+
#
|
298
|
+
# @return [Boolean]
|
299
|
+
attr_accessor :disable_mommacat
|
300
|
+
|
301
|
+
# **Default: `false`** -
|
302
|
+
# Disable Nagios monitoring
|
303
|
+
#
|
304
|
+
# @return [Boolean]
|
305
|
+
attr_accessor :disable_nagios
|
306
|
+
|
307
|
+
# Google Cloud Platform
|
308
|
+
#
|
309
|
+
# @return [google]
|
310
|
+
# @see google
|
311
|
+
attr_accessor :google
|
312
|
+
|
313
|
+
# Optional extra Chef roles or recipes to invoke when running chef-client on this Master (ex: recipe[mycookbook::mumaster])
|
314
|
+
#
|
315
|
+
# @return [Array<String>]
|
316
|
+
attr_accessor :master_runlist_extras
|
317
|
+
|
318
|
+
# **Default: `2260`**,
|
319
|
+
# **Must match pattern `(?i-mx:^[0-9]+$)`** -
|
320
|
+
# Listen port for the Momma Cat grooming daemon
|
321
|
+
#
|
322
|
+
# @return [String]
|
323
|
+
attr_accessor :mommacat_port
|
324
|
+
|
325
|
+
# **Default: `Mu Administrator`** -
|
326
|
+
# Administative contact's full name
|
327
|
+
#
|
328
|
+
# @return [String]
|
329
|
+
attr_accessor :mu_admin_name
|
330
|
+
|
331
|
+
# **Default: `git://github.com/cloudamatic/mu.git`**,
|
332
|
+
# **Must match pattern `(?-mix:(((git|ssh|http(s)?)|(git@[\w\.]+))(:(\/\/)?))?([\w\.@\:\/\-~]+)(\.git)?(\/)?)`** -
|
333
|
+
# Source repository for Mu tools
|
334
|
+
#
|
335
|
+
# @return [String]
|
336
|
+
attr_accessor :mu_repository
|
337
|
+
|
338
|
+
# **Default: `["https://github.com/cloudamatic/mu_demo_platform"]`**,
|
339
|
+
# **Must match pattern `(?-mix:(((git|ssh|http(s)?)|(git@[\w\.]+))(:(\/\/)?))?([\w\.@\:\/\-~]+)(\.git)?(\/)?)`** -
|
340
|
+
# Optional platform repositories, as a Git URL or Github repo name (ex: eGT-Labs/fema_platform.git)
|
341
|
+
#
|
342
|
+
# @return [Array<String>]
|
343
|
+
attr_accessor :repos
|
344
|
+
|
345
|
+
# Slack Configuration
|
346
|
+
#
|
347
|
+
# @return [slack]
|
348
|
+
# @see slack
|
349
|
+
attr_accessor :slack
|
350
|
+
# @!endgroup
|
351
|
+
end
|
@@ -757,6 +757,8 @@ MU.log ".update_security_group_rule_descriptions_ingress", MU::NOTICE, details:
|
|
757
757
|
end
|
758
758
|
|
759
759
|
def rules_match(rule_a, rule_b)
|
760
|
+
a_ranges = rule_a[:ip_ranges].to_a.map { |r| MU.structToHash(r) }.sort
|
761
|
+
b_ranges = rule_b[:ip_ranges].to_a.map { |r| MU.structToHash(r) }.sort
|
760
762
|
(
|
761
763
|
rule_a[:from_port] == rule_b[:from_port] and
|
762
764
|
rule_a[:to_port] == rule_b[:to_port] and
|
@@ -768,7 +770,7 @@ MU.log ".update_security_group_rule_descriptions_ingress", MU::NOTICE, details:
|
|
768
770
|
) or
|
769
771
|
(
|
770
772
|
!rule_a[:ip_ranges].nil? and !rule_b[:ip_ranges].nil? and
|
771
|
-
|
773
|
+
a_ranges == b_ranges
|
772
774
|
)
|
773
775
|
) and
|
774
776
|
(
|