Skip to content

Commit

Permalink
Merge pull request #192 from cloudamatic/development
Browse files Browse the repository at this point in the history
I Spy With My Ruby Eye
  • Loading branch information
jstange authored Jun 17, 2020
2 parents 6b5de9a + c815ff5 commit a559262
Show file tree
Hide file tree
Showing 154 changed files with 6,405 additions and 5,366 deletions.
4 changes: 2 additions & 2 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ Docker Build:
variables:
- $IMAGE_BUILD
tags:
- docker-build
- docker
retry: 2

Parser Test With Gem:
Expand Down Expand Up @@ -349,7 +349,7 @@ Base Images Linux:
Base Images Windows:
stage: Deploy
script:
- /opt/mu/lib/extras/generate-stock-images --clouds AWS --aws-creds egtprod --platforms win2k12 win2k16
- /opt/mu/lib/extras/generate-stock-images --clouds AWS --aws-creds egtprod --platforms win2k12 win2k16 win2k19
tags:
- mu-gitlab-runner
only:
Expand Down
16 changes: 4 additions & 12 deletions bin/mu-adopt
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,6 @@ require 'bundler/setup'
require 'optimist'
require 'mu'

available_clouds = MU::Cloud.supportedClouds
available_clouds.reject! { |cloud|
cloudclass = Object.const_get("MU").const_get("Cloud").const_get(cloud)
cloudclass.listCredentials.nil? or cloudclass.listCredentials.size == 0
}

available_types = MU::Cloud.resource_types.keys.map { |t| t.to_s }
grouping_options = {
"logical" => "Group resources in logical layers (folders and habitats together, users/roles/groups together, network resources together, etc)",
Expand All @@ -39,15 +33,17 @@ $opt = Optimist::options do
EOS
opt :appname, "The overarching name of the application stack we will generate", :required => false, :default => "mu", :type => :string
opt :types, "The resource types to scan and import. Valid types: #{available_types.join(", ")}", :required => false, :type => :strings, :default => available_types
opt :clouds, "The cloud providers to scan and import.", :required => false, :type => :strings, :default => available_clouds
opt :clouds, "The cloud providers to scan and import.", :required => false, :type => :strings, :default => MU::Cloud.availableClouds
opt :parent, "Where applicable, resources which reside in the root folder or organization are configured with the specified parent in our target BoK", :required => false, :type => :string
opt :billing, "Force-set this billing entity on created resources, instead of copying from the live resources", :required => false, :type => :string
opt :sources, "One or more sets of credentials to use when importing resources. By default we will search and import from all sets of available credentials for each cloud provider specified with --clouds", :required => false, :type => :strings
opt :credentials, "Override the 'credentials' value in our generated Baskets of Kittens to target a single, specific account. Our default behavior is to set each resource to deploy into the account from which it was sourced.", :required => false, :type => :string
opt :savedeploys, "Generate actual deployment metadata in #{MU.dataDir}/deployments, as though the resources we found were created with mu-deploy. If we are generating more than one configuration, and a resource needs to reference another resource (e.g. to declare a VPC in which to reside), this will allow us to reference them as virtual resource, rather than by raw cloud identifier.", :required => false, :type => :boolean, :default => false
opt :diff, "List the differences between what we find and an existing, saved deploy from a previous run, if one exists.", :required => false, :type => :boolean
opt :merge_changes, "When using --diff, merge detected changes into the baseline deploy after reporting on them.", :required => false, :type => :boolean, :default => false
opt :grouping, "Methods for grouping found resources into separate Baskets.\n\n"+MU::Adoption::GROUPMODES.keys.map { |g| "* "+g.to_s+": "+MU::Adoption::GROUPMODES[g] }.join("\n")+"\n\n", :required => false, :type => :string, :default => "logical"
opt :habitats, "Limit scope of searches to the named accounts/projects/subscriptions, instead of search all habitats visible to our credentials.", :required => false, :type => :strings
opt :regions, "Restrict to operating on a subset of available regions, instead of all that we know about.", :require => false, :type => :strings
opt :scrub, "Whether to set scrub_mu_isms in the BoKs we generate", :default => $MU_CFG.has_key?('adopt_scrub_mu_isms') ? $MU_CFG['adopt_scrub_mu_isms'] : false
end

Expand Down Expand Up @@ -102,8 +98,7 @@ if !ok
exit 1
end


adoption = MU::Adoption.new(clouds: clouds, types: types, parent: $opt[:parent], billing: $opt[:billing], sources: $opt[:sources], credentials: $opt[:credentials], group_by: $opt[:grouping].to_sym, savedeploys: $opt[:savedeploys], diff: $opt[:diff], habitats: $opt[:habitats], scrub_mu_isms: $opt[:scrub])
adoption = MU::Adoption.new(clouds: clouds, types: types, parent: $opt[:parent], billing: $opt[:billing], sources: $opt[:sources], credentials: $opt[:credentials], group_by: $opt[:grouping].to_sym, savedeploys: $opt[:savedeploys], diff: $opt[:diff], habitats: $opt[:habitats], scrub_mu_isms: $opt[:scrub], regions: $opt[:regions], merge: $opt[:merge_changes])
found = adoption.scrapeClouds
if found.nil? or found.empty?
MU.log "No resources found to adopt", MU::WARN, details: {"clouds" => clouds, "types" => types }
Expand All @@ -117,10 +112,7 @@ boks.each_pair { |appname, bok|
File.open("#{appname}.yaml", "w") { |f|
f.write JSON.parse(JSON.generate(bok)).to_yaml
}
conf_engine = MU::Config.new("#{appname}.yaml")
stack_conf = conf_engine.config
# puts stack_conf.to_yaml
MU.log "#{appname}.yaml validated successfully", MU::NOTICE
MU::Cloud.resource_types.each_pair { |type, cfg|
if bok[cfg[:cfg_plural]]
MU.log "#{bok[cfg[:cfg_plural]].size.to_s} #{cfg[:cfg_plural]}", MU::NOTICE
Expand Down
57 changes: 57 additions & 0 deletions bin/mu-azure-tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/local/ruby-current/bin/ruby
# Copyright:: Copyright (c) 2014 eGlobalTech, Inc., all rights reserved
#
# Licensed under the BSD-3 license (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License in the root of the project or at
#
# http://egt-labs.com/mu/LICENSE.html
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require 'rubygems'
require 'bundler/setup'
require 'json'
require 'erb'
require 'optimist'
require 'json-schema'
require File.realpath(File.expand_path(File.dirname(__FILE__)+"/mu-load-config.rb"))
require 'mu'

(0..100000).to_a.each { |n|
retries = 0
seed = nil
# begin
# raise MuError, "Failed to allocate an unused MU-ID after #{retries} tries!" if retries > 70
# seedsize = 1 + (retries/10).abs
# seed = (0...seedsize+1).map { ('a'..'z').to_a[rand(26)] }.join
# end while seed == "mu" or seed[0] == seed[1]
seed = "nn"
handle = MU::MommaCat.generateHandle(seed)
puts handle
}
exit

#pp MU::Cloud::Azure.listRegions
#pp MU::Cloud::Azure::Habitat.testcalls
#pp MU::Cloud::Azure::VPC.find(cloud_id: MU::Cloud::Azure::Id.new(resource_group: "mu", name: "mu-vnet"))
#pp MU::Cloud::Azure.authorization.role_assignments.list_for_resource_group("AKS-DEV-2019062015-KA-EASTUS")
#pp MU::Cloud::Azure::Role.find(role_name: "Azure Kubernetes Service Cluster Admin Role")
#puts MU::Cloud::Azure.default_subscription
#pp MU::Cloud::Azure.fetchPublicIP("MYVPC-DEV-2019061911-XI-EASTUS", "ip-addr-thingy")
#pp MU::Cloud::Azure.ensureProvider("egtazure", "Microsoft.ContainerService", force: true)
pp MU::Cloud::Azure::Server.find(cloud_id: "mu")
exit
pp MU::Cloud::Azure::Server.fetchImage("OpenLogic/CentOS/6")
pp MU::Cloud::Azure::Server.fetchImage("OpenLogic/CentOS/7")
pp MU::Cloud::Azure::Server.fetchImage("RedHat/RHEL/8")
pp MU::Cloud::Azure::Server.fetchImage("RedHat/RHEL/7")
pp MU::Cloud::Azure::Server.fetchImage("RedHat/RHEL/6")
pp MU::Cloud::Azure::Server.fetchImage("Debian/debian-10/10")
pp MU::Cloud::Azure::Server.fetchImage("MicrosoftWindowsServer/WindowsServer/2012-R2-Datacenter")
pp MU::Cloud::Azure::Server.fetchImage("MicrosoftWindowsServer/WindowsServer/2016-Datacenter")
pp MU::Cloud::Azure::Server.fetchImage("MicrosoftWindowsServer/WindowsServer/2019-Datacenter")
6 changes: 2 additions & 4 deletions bin/mu-cleanup
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@ require 'mu'
Dir.chdir(MU.installDir)

credentials = []
MU::Cloud.supportedClouds.each { |cloud|
cloudclass = Object.const_get("MU").const_get("Cloud").const_get(cloud)
next if cloudclass.listCredentials.nil? or cloudclass.listCredentials.size == 0
credentials.concat(cloudclass.listCredentials)
MU::Cloud.availableClouds.each { |cloud|
credentials.concat(MU::Cloud.cloudClass(cloud).listCredentials)
}
credentials.uniq!

Expand Down
38 changes: 37 additions & 1 deletion bin/mu-configure
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,44 @@ $CONFIGURABLES = {
"desc" => "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.",
"boolean" => true
},
"adopt_change_notify" => {
"title" => "Adoption Change Notifications",
"subtree" => {
"slack" => {
"title" => "Send to Slack",
"desc" => "Report modifications to adopted resources, detected by mu-adopt --diff, to the Slack webhook and channel configured under Slack Configuration.",
"boolean" => true
},
"slack_snippet_threshold" => {
"title" => "Attachment Threshold",
"desc" => "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."
},
# "email" => {
# "title" => "Send Email",
# "desc" => "",
# "boolean" => true
# }
}
},
"adopt_scrub_mu_isms" => {
"title" => "Disable Momma Cat",
"title" => "Scrub Mu-isms from Baskets of Kittens",
"default" => false,
"desc" => "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).",
"boolean" => true
},
"slack" => {
"title" => "Slack Configuration",
"subtree" => {
"webhook" => {
"title" => "Webhook",
"desc" => "The hooks.slack.com URL for the webook to which we'll send deploy notifications"
},
"channel" => {
"title" => "Channel",
"desc" => "The channel name (without leading #) to which alerts should be sent."
}
}
},
"mommacat_port" => {
"title" => "Momma Cat Listen Port",
"pattern" => /^[0-9]+$/i,
Expand Down Expand Up @@ -247,6 +279,10 @@ $CONFIGURABLES = {
"required" => false,
"desc" => "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"
},
"org" => {
"title" => "Default Org/Domain",
"desc" => "For credential sets which have access to multiple GSuite or Cloud Identity orgs, you must specify a default organization (e.g. my.domain.com)."
},
"customer_id" => {
"title" => "GSuite Customer ID",
"required" => false,
Expand Down
6 changes: 3 additions & 3 deletions bin/mu-deploy
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ if $opts[:dryrun]
Thread.handle_interrupt(MU::Cloud::MuCloudResourceNotImplemented => :never) {
begin
Thread.handle_interrupt(MU::Cloud::MuCloudResourceNotImplemented => :immediate) {
MU.log "Cost calculator not available for this stack, as it uses a resource not implemented in Mu's CloudFormation layer.", MU::WARN, verbosity: MU::Logger::NORMAL
MU.log "Cost calculator not available for this stack, as it uses a resource not implemented in Mu's CloudFormation layer.", MU::NOTICE, verbosity: MU::Logger::NORMAL
Thread.current.exit
}
ensure
Expand All @@ -124,7 +124,7 @@ if $opts[:dryrun]
)
cost_dummy_deploy.run
rescue MU::Cloud::MuCloudResourceNotImplemented, MU::Cloud::MuCloudFlagNotImplemented
MU.log "Cost calculator not available for this stack, as it uses a resource not implemented in Mu's CloudFormation layer.", MU::WARN, verbosity: MU::Logger::NORMAL
MU.log "Cost calculator not available for this stack, as it uses a resource not implemented in Mu's CloudFormation layer.", MU::NOTICE, verbosity: MU::Logger::NORMAL
end
end
exit
Expand All @@ -135,7 +135,7 @@ if $opts[:update]
# TODO consider whether this is useful/valid
# old_conf = JSON.parse(File.read(deploy.deploy_dir+"/basket_of_kittens.json"))
# stack_conf = old_conf.merge(stack_conf)
deploy.updateBasketofKittens(stack_conf)
deploy.updateBasketofKittens(stack_conf, skip_validation: true)
deployer = MU::Deploy.new(
deploy.environment,
verbosity: verbosity,
Expand Down
25 changes: 25 additions & 0 deletions bin/mu-findstray-tests
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/usr/local/ruby-current/bin/ruby
# Copyright:: Copyright (c) 2014 eGlobalTech, Inc., all rights reserved
#
# Licensed under the BSD-3 license (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License in the root of the project or at
#
# http://egt-labs.com/mu/LICENSE.html
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require 'rubygems'
require 'bundler/setup'
require 'json'
require 'erb'
require 'optimist'
require 'json-schema'
require File.realpath(File.expand_path(File.dirname(__FILE__)+"/mu-load-config.rb"))
require 'mu'

MU::MommaCat.findStray("AWS", "firewall_rule", region: MU.myRegion, dummy_ok: true, debug: true)
6 changes: 2 additions & 4 deletions bin/mu-gen-docs
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,7 @@ EOF
impl_counts[type] ||= 0
[a, b].each { |cloud|
begin
myclass = Object.const_get("MU").const_get("Cloud").const_get(cloud).const_get(type)
case myclass.quality
case MU::Cloud.resourceClass(cloud, type).quality
when MU::Cloud::RELEASE
cloud_is_useful[cloud] = true
counts[cloud] += 4
Expand Down Expand Up @@ -114,8 +113,7 @@ EOF
cloudlist.each { |cloud|
readme += "<td><center>"
begin
myclass = Object.const_get("MU").const_get("Cloud").const_get(cloud).const_get(type)
case myclass.quality
case MU::Cloud.resourceClass(cloud, type).quality
when MU::Cloud::RELEASE
readme += "<img src='release.png' style='#{icon_style}' title='Release Quality' alt='[Release Quality]'>"
when MU::Cloud::BETA
Expand Down
33 changes: 23 additions & 10 deletions bin/mu-run-tests
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ only = ARGV

files = Dir.glob("*.yaml", base: dir)
files.concat(Dir.glob("*.yml", base: dir))
baseclouds = MU::Cloud.supportedClouds.reject { |c| c == "CloudFormation" }
baseclouds = MU::Cloud.availableClouds.reject { |c| c == "CloudFormation" }

commands = {}
failures = []
Expand All @@ -56,20 +56,33 @@ end

files.each { |f|
clouds = baseclouds.dup
groomer_match = true
File.open(dir+"/"+f).readlines.each { |l|
l.chomp!
next if !l.match(/^\s*#\s*clouds: (.*)/)
clouds = []
cloudstr = Regexp.last_match[1]
cloudstr.split(/\s*,\s*/).each { |c|
baseclouds.each { |cloud|
if cloud.match(/^#{Regexp.quote(c)}$/i)
clouds << cloud
if l.match(/^\s*#\s*clouds: (.*)/)
clouds = []
cloudstr = Regexp.last_match[1]
cloudstr.split(/\s*,\s*/).each { |c|
baseclouds.each { |cloud|
if cloud.match(/^#{Regexp.quote(c)}$/i)
clouds << cloud
end
}
}
elsif l.match(/^\s*#\s*groomers: (.*)/)
groomerstr = Regexp.last_match[1]
groomerstr.split(/\s*,\s*/).each { |g|
if !MU::Groomer.availableGroomers.include?(g)
MU.log "#{f} requires groomer #{g}, which is not available. This test will be skipped.", MU::NOTICE
groomer_match = false
end
}
}
break
end
}
if !groomer_match
next
end

clouds.each { |cloud|
cmd = "mu-deploy #{f} --cloud #{cloud} #{$opts[:full] ? "" : "--dryrun"}"
commands[cmd] = {
Expand Down
4 changes: 2 additions & 2 deletions cloud-mu.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ end

Gem::Specification.new do |s|
s.name = 'cloud-mu'
s.version = '3.1.6'
s.date = '2020-03-20'
s.version = '3.2.0'
s.date = '2020-06-16'
s.require_paths = ['modules']
s.required_ruby_version = '>= 2.4'
s.summary = "The eGTLabs Mu toolkit for unified cloud deployments"
Expand Down
2 changes: 1 addition & 1 deletion cookbooks/mu-tools/libraries/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ def mommacat_request(action, arg)
response = nil
begin
secret = get_deploy_secret
if secret.nil?
if secret.nil? or secret.empty?
raise "Failed to fetch deploy secret, and I can't communicate with Momma Cat without it"
end

Expand Down
28 changes: 14 additions & 14 deletions cookbooks/mu-tools/recipes/apply_security.rb
Original file line number Diff line number Diff line change
Expand Up @@ -252,21 +252,21 @@
# end
# 6.3 Configure PAM
# 6.3.2 Set Password Creation Requirement Parameters Using pam_cracklib
template "/etc/pam.d/password-auth-local" do
source "etc_pamd_password-auth.erb"
mode 0644
end
link "/etc/pam.d/password-auth" do
to "/etc/pam.d/password-auth-local"
end
# template "/etc/pam.d/password-auth-local" do
# source "etc_pamd_password-auth.erb"
# mode 0644
# end
# link "/etc/pam.d/password-auth" do
# to "/etc/pam.d/password-auth-local"
# end
#6.3.3 Set Lockout for Failed Password Attempts
template "/etc/pam.d/system-auth-local" do
source "etc_pamd_system-auth.erb"
mode 0644
end
link "/etc/pam.d/system-auth" do
to "/etc/pam.d/system-auth-local"
end
# template "/etc/pam.d/system-auth-local" do
# source "etc_pamd_system-auth.erb"
# mode 0644
# end
# link "/etc/pam.d/system-auth" do
# to "/etc/pam.d/system-auth-local"
# end

#SV-50303r1_rule/SV-50304r1_rule
execute "chown root:root /etc/shadow"
Expand Down
9 changes: 9 additions & 0 deletions cookbooks/mu-tools/recipes/aws_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,12 @@
version "2.11.24"
action :install
end

if platform_family?("rhel") or platform_family?("amazon")
if node['platform_version'].to_i == 6
package "python34-pip"
execute "/usr/bin/pip3 install awscli" do
not_if "test -x /usr/bin/aws"
end
end
end
Loading

0 comments on commit a559262

Please sign in to comment.