Skip to content

Instantly share code, notes, and snippets.

@ironcladlou
Created March 19, 2020 11:31
Show Gist options
  • Save ironcladlou/e9e6ebc9c309edba854f3e0ef34fc9da to your computer and use it in GitHub Desktop.
Save ironcladlou/e9e6ebc9c309edba854f3e0ef34fc9da to your computer and use it in GitHub Desktop.
clusterctl.rb
#!/usr/bin/env ruby
require 'json'
require 'yaml'
require 'securerandom'
require 'etc'
require 'optparse'
require 'fileutils'
require 'tmpdir'
$ip_families = {
:azure => :v4,
:azureipv6 => :v6,
:aws => :v4,
}
$templates = {}
$templates[:azureipv6] = <<EOF
apiVersion: v1
baseDomain: networkedge.azure.devcluster.openshift.com
clusterID: %{cluster_id}
metadata:
name: %{cluster_name}
compute:
- hyperthreading: Enabled
name: worker
replicas: 3
controlPlane:
hyperthreading: Enabled
name: master
replicas: 3
networking:
clusterNetwork:
- cidr: fd01::/48
hostPrefix: 64
machineNetwork:
- cidr: 10.0.0.0/16
- cidr: fd00::/48
networkType: OVNKubernetes
serviceNetwork:
- fd02::/112
platform:
azure:
baseDomainResourceGroupName: os4-common
region: centralus
pullSecret: '%{pull_secret}'
sshKey: '%{ssh_key_contents}'
EOF
$templates[:aws] = <<EOF
apiVersion: v1
baseDomain: devcluster.openshift.com
clusterID: %{cluster_id}
machines:
- name: master
replicas: 3
- name: worker
replicas: 3
metadata:
name: %{cluster_name}
networking:
clusterNetworks:
- cidr: 10.128.0.0/14
hostSubnetLength: 9
machineCIDR: 10.0.0.0/16
serviceCIDR: 172.30.0.0/16
type: OpenshiftSDN
platform:
aws:
region: us-east-2
pullSecret: '%{pull_secret}'
sshKey: '%{ssh_key_contents}'
EOF
def create(opts)
uuid = SecureRandom.uuid
meta = {
:cluster_id => uuid,
:cluster_name => "#{ENV['USER']}-#{uuid[0..3]}",
:platform => opts.fetch(:platform),
:installer => opts.fetch(:installer, `which openshift-install`.chomp),
:image_override => opts.fetch(:image_override, ""),
:docker_config => opts.fetch(:docker_config, "#{ENV['HOME']}/.docker/config.json"),
:ssh_key => opts.fetch(:ssh_key, "#{ENV['HOME']}/.ssh/id_rsa.pub"),
}
cluster_dir = File.expand_path(meta[:cluster_name])
if Dir.exist?(cluster_dir)
puts "cluster already exists at #{cluster_dir}"
return
end
Dir.mkdir(cluster_dir)
meta_file = File.join(cluster_dir, "metadata.yaml")
File.write(meta_file, YAML.dump(meta))
data = {
:pull_secret => File.read(meta[:docker_config]).gsub("\n", '').squeeze(' '),
:ssh_key_contents => File.read(meta[:ssh_key]).gsub("\n", '').squeeze(' ')
}
template = $templates[meta[:platform]]
install_config = template % meta.merge(data)
install_config_file = File.join(cluster_dir, "install-config.yaml")
File.write(install_config_file, install_config)
puts "created cluster directory #{cluster_dir}"
case $ip_families[meta[:platform]]
when :v4
command = "OPENSHIFT_INSTALL_RELEASE_IMAGE_OVERRIDE=#{meta[:image_override]} #{meta[:installer]} create cluster --dir=#{cluster_dir} --log-level debug 2>&1 | tee #{cluster_dir}/install.log"
puts "executing: #{command}"
system(command, out: STDOUT)
when :v6
command = "OPENSHIFT_INSTALL_AZURE_EMULATE_SINGLESTACK_IPV6=true OPENSHIFT_INSTALL_RELEASE_IMAGE_OVERRIDE=#{meta[:image_override]} #{meta[:installer]} create cluster --dir=#{cluster_dir} --log-level debug 2>&1 | tee #{cluster_dir}/install.log"
puts "executing: #{command}"
system(command, out: STDOUT)
else
puts "no IP family defined for platform #{meta[:platform]}"
end
end
def delete(opts)
cluster_dir = File.expand_path(opts[:cluster_name])
unless Dir.exist?(cluster_dir)
puts "no cluster found at #{cluster_dir}"
return
end
meta_file = File.join(cluster_dir, "metadata.yaml")
meta = YAML.load(File.read(meta_file))
case $ip_families[meta[:platform]]
when :v4
command = "OPENSHIFT_INSTALL_RELEASE_IMAGE_OVERRIDE=#{meta[:image_override]} #{meta[:installer]} destroy cluster --dir=#{cluster_dir} --log-level debug 2>&1 | tee #{cluster_dir}/destroy.log"
puts "executing: #{command}"
system(command, out: STDOUT)
when :v6
command = "OPENSHIFT_INSTALL_AZURE_EMULATE_SINGLESTACK_IPV6=true OPENSHIFT_INSTALL_RELEASE_IMAGE_OVERRIDE=#{meta[:image_override]} #{meta[:installer]} destroy cluster --dir=#{cluster_dir} --log-level debug 2>&1 | tee #{cluster_dir}/destroy.log"
puts "executing: #{command}"
system(command, out: STDOUT)
else
puts "no IP family defined for platform #{meta[:platform]}"
end
# do delete
trash_dir = File.join(Dir.tmpdir(), File.basename(cluster_dir))
FileUtils.mv(cluster_dir, trash_dir)
puts "moved cluster #{meta[:cluster_name]} to trash: #{trash_dir}"
end
opts = {}
OptionParser.new do |parser|
# options for create
parser.on('-p', '--platform=NAME') do |platform|
opts[:platform] = platform.to_sym
end
parser.on('-i', '--installer=PATH') do |installer|
opts[:installer] = installer
end
parser.on('-s', '--ssh-key=PATH') do |ssh_key|
opts[:ssh_key] = ssh_key
end
parser.on('-o', '--override=IMAGE') do |image|
opts[:image_override] = image
end
# options for delete
parser.on('-c', '--cluster=NAME') do |name|
opts[:cluster_name] = name
end
end.parse!
command = ARGV.pop.to_sym
case command
when :create
create(opts)
when :delete
delete(opts)
else
puts "unrecognized command"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment