Skip to content

Commit

Permalink
ONEOCPDEPL-43: refactoring
Browse files Browse the repository at this point in the history
Signed-off-by: Andrej Podhradsky <[email protected]>
  • Loading branch information
apodhrad committed Jan 22, 2021
1 parent b36e6e3 commit 5b22f63
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 74 deletions.
4 changes: 1 addition & 3 deletions lib/launchers/amz.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ def initialize(access_key: nil, secret_key: nil, service_name: nil, region: nil)
)
}) )
Aws.config.update( config[:config_opts].merge({region: region})) if region

@account_id = awscred["aws_account_id"]
end

private def client_ec2
Expand Down Expand Up @@ -619,7 +617,7 @@ def secret_key

# @return [String]
def account_id
return @account_id
client_sts.get_caller_identity.to_h[:account]
end

# @return [Object] undefined
Expand Down
168 changes: 112 additions & 56 deletions lib/launchers/ocm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@
require 'yaml'
require 'tmpdir'
require 'git'
require 'os'
require 'http'

module BushSlicer
class OCM
include Common::Helper

attr_reader :config
attr_reader :config, :ocm_cli
attr_reader :token, :token_file, :url, :region, :version, :num_nodes, :lifespan, :cloud, :cloud_opts, :multi_az, :aws_account_id, :aws_access_key, :aws_secret_key

def initialize(**options)
Expand Down Expand Up @@ -66,6 +68,8 @@ def initialize(**options)
# you can refer to already defined cloud in config.yaml
# currently, only AWS is supported
if ENV['AWS_ACCOUNT_ID'] && ENV['AWS_ACCESS_KEY'] && (ENV['AWS_SECRET_ACCESS_KEY'] || ENV['AWS_SECRET_KEY'])
# account_id will not be required once the following issue is fixed
# https://github.com/openshift-online/ocm-cli/issues/216
@aws_account_id = ENV['AWS_ACCOUNT_ID']
@aws_access_key = ENV['AWS_ACCESS_KEY']
@aws_secret_key = ENV['AWS_SECRET_ACCESS_KEY'] || ENV['AWS_SECRET_KEY']
Expand Down Expand Up @@ -114,9 +118,8 @@ def to_seconds(string)
end
end

# create a json which specifies OSD cluster
# in the future we plan to move the logic into the script 'osd-provision.sh'
def generate_json(name)
# Generate a cluster data used for creating OSD cluster
def generate_cluster_data(name)
json_data = {
"name" => name,
"managed" => true,
Expand Down Expand Up @@ -150,25 +153,30 @@ def generate_json(name)
json_data.merge!({"byoc" => true})
end

return json_data.to_json
return json_data
end

# download the script 'osd-provision.sh' which takes care of the OSD installation/uninstallation
def download_osd_script
if ENV['GIT_OSD_URI']
osd_repo_uri = ENV['GIT_OSD_URI']
else
raise "You need to define env variable 'GIT_OSD_URI'"
end
osd_repo_dir = File.join(Dir.tmpdir, 'osd_repo')
FileUtils.rm_rf(osd_repo_dir)
git = BushSlicer::Git.new(uri: osd_repo_uri, dir: osd_repo_dir)
git.clone
osd_script = File.join(osd_repo_dir, 'scripts', 'osd-provision.sh')
if !File.exists?(osd_script)
raise "Cannot find #{osd_script}"
def download_ocm_cli
url = ENV['OCM_CLI_URL']
unless url
url_prefix = ENV['OCM_CLI_URL_PREFIX'] || 'https://github.com/openshift-online/ocm-cli/releases/download/v0.1.46'
if OS.mac?
url = "#{url_prefix}/ocm-darwin-amd64"
elsif OS.linux?
url = "#{url_prefix}/ocm-linux-amd64"
else
raise "Unsupported OS"
end
end
return osd_script
#doesn't work
#File.open('/tmp/ocm', 'wb') do |file|
# @result = Http.get(url: url) do |chunk|
# file.write chunk
# end
#end
shell("curl -L #{url} -o /tmp/ocm")
File.chmod(0775, '/tmp/ocm')
return '/tmp/ocm'
end

def shell(cmd, output = nil)
Expand All @@ -184,55 +192,103 @@ def shell(cmd, output = nil)
end
end

def exec(cmd)
unless @ocm_cli
@ocm_cli = download_ocm_cli
end
return shell("#{@ocm_cli} #{cmd}").strip
end

def login
ocm_token_file = Tempfile.new("ocm-token", Host.localhost.workdir)
File.write(ocm_token_file, @token)
exec("login --url=#{@url} --token=$(cat #{ocm_token_file.path})")
end

def get_value(osd_name, attribute)
result = exec("list clusters --parameter search=\"name='#{osd_name}'\" --columns #{attribute}")
return result.lines.last
end

def get_credentials(osd_name)
osd_id = get_value(osd_name, "id")
return JSON.parse(exec("get /api/clusters_mgmt/v1/clusters/#{osd_id}/credentials"))
end

# generate OCP information
def generate_ocp_info(api_url, json_creds)
api_regex = /https?:\/\/api\.([\S]+):[\d]*/
if api_url.match(api_regex)
domain = api_url.scan(api_regex).first.first
def generate_ocpinfo_data(api_url, user, password)
host = URI.parse(api_url).host
if host
host = host.gsub(/^api\./, '')
else
raise "Given api_url '#{api_url}' doesn't match '#{api_regex}'"
raise "Given API url '#{api_url}' cannot be parsed"
end
credentials = JSON.parse(json_creds)
ocp_info = {
"ocp_domain" => domain,
"ocp_api_url" => "https://api.#{domain}:6443",
"ocp_console_url" => "https://console-openshift-console.apps.#{domain}",
"user" => credentials["user"],
"password" => credentials["password"]
"ocp_domain" => host,
"ocp_api_url" => "https://api.#{host}:6443",
"ocp_console_url" => "https://console-openshift-console.apps.#{host}",
"user" => user,
"password" => password
}
return ocp_info
end

# create OSD cluster
def create_osd(name)
# cerate a temp file with ocm-token
ocm_token_file = Tempfile.new("ocm-token-file", Host.localhost.workdir)
File.write(ocm_token_file, @token)
# create cluster.json in a workdir/install-dir
# create workdir/install-dir
def create_install_dir
install_dir = File.join(Host.localhost.workdir, 'install-dir')
FileUtils.mkdir_p(install_dir)
ocm_json_file = File.join(install_dir, 'cluster.json')
File.write(ocm_json_file, generate_json(name))
# now, download the script which will take care of the OSD cluster installation
osd_script = download_osd_script
shell("#{osd_script} --create --cloud-token-file #{ocm_token_file.path} -f #{ocm_json_file} --wait", STDOUT)
output = shell("#{osd_script} --get api_url -f #{ocm_json_file}")
ocp_api_url = output.lines.last
output = shell("#{osd_script} --get credentials -f #{ocm_json_file}")
ocp_credentials = output.lines.last
# generate yaml file with OCP information
ocp_info_file = File.join(install_dir, 'OCPINFO.yml')
File.write(ocp_info_file, generate_ocp_info(ocp_api_url, ocp_credentials).to_yaml)
return install_dir
end

def create_cluster_file(osd_name, dir, filename = 'cluster.json')
cluster_file = File.join(dir, filename)
cluster_data = generate_cluster_data(osd_name)
File.write(cluster_file, cluster_data.to_json)
return cluster_file
end

def create_ocpinfo_file(osd_name, dir, filename = 'OCPINFO.yml')
api_url = get_value(osd_name, "api.url")
osd_id = get_value(osd_name, "id")
ocp_creds = get_credentials(osd_name)
user = ocp_creds["admin"]["user"]
password = ocp_creds["admin"]["password"]
ocpinfo_file = File.join(dir, filename)
ocpinfo_data = generate_ocpinfo_data(api_url, user, password)
File.write(ocpinfo_file, ocpinfo_data.to_yaml)
return ocpinfo_file
end

# Wait until OSD cluster is ready and OCP version is available
# NOTE: we need to wait for registering all metrics - OCP version indicates this state
def wait_for_osd(osd_name)
loop do
osd_status = get_value(osd_name, "state")
ocp_version = get_value(osd_name, "openshift_version")
logger.info("Status of cluster #{osd_name} is #{osd_status} and OCP version is #{ocp_version}")
if osd_status == "ready" && ocp_version != "NONE"
break
end
logger.info("Check again after 2 minutes")
sleep(120)
end
end

# Create OSD cluster
def create_osd(osd_name)
login
install_dir = create_install_dir
cluster_file = create_cluster_file(osd_name, install_dir)
exec("post /api/clusters_mgmt/v1/clusters --body='#{cluster_file}'")
wait_for_osd(osd_name)
create_ocpinfo_file(osd_name, install_dir)
end

# delete OSD cluster
def delete_osd(name)
# create a temp file with ocm-token
ocm_token_file = Tempfile.new("ocm-token-file", Host.localhost.workdir)
File.write(ocm_token_file, @token)
# now, download the script which will take care of the OSD cluster installation
osd_script = download_osd_script
shell("#{osd_script} --delete --cloud-token-file #{ocm_token_file.path} -n #{name}")
def delete_osd(osd_name)
login
osd_id = get_value(osd_name, "id")
exec("delete post /api/clusters_mgmt/v1/clusters/#{osd_id}")
end

end
Expand Down
80 changes: 65 additions & 15 deletions lib/launchers/ocm_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,62 +40,62 @@ def test_default_url_envvars
assert_equal('https://api.stage.openshift.com', ocm.url)
end

def test_generating_json
def test_generating_cluster_data
options = { :token => "abc" }
ocm = BushSlicer::OCM.new(options)
json = ocm.generate_json('myosd4')
json = ocm.generate_cluster_data('myosd4').to_json
assert_equal('{"name":"myosd4","managed":true,"multi_az":false,"byoc":false}', json)
end

def test_generating_json_with_region
def test_generating_cluster_data_with_region
options = { :token => "abc", :region => "us-east-1" }
ocm = BushSlicer::OCM.new(options)
json = ocm.generate_json('myosd4')
json = ocm.generate_cluster_data('myosd4').to_json
assert_equal('{"name":"myosd4","managed":true,"multi_az":false,"byoc":false,"region":{"id":"us-east-1"}}', json)
end

def test_generating_json_with_region_envvars
def test_generating_cluster_data_with_region_envvars
ENV['OCM_TOKEN'] = "abc"
ENV['OCM_REGION'] = "us-east-2"
ocm = BushSlicer::OCM.new()
json = ocm.generate_json('myosd4')
json = ocm.generate_cluster_data('myosd4').to_json
assert_equal('{"name":"myosd4","managed":true,"multi_az":false,"byoc":false,"region":{"id":"us-east-2"}}', json)
end

def test_generating_json_with_aws_envvars
def test_generating_cluster_data_with_aws_envvars
ENV['OCM_TOKEN'] = "abc"
ENV['AWS_REGION'] = "eu-central-1"
ENV['AWS_ACCOUNT_ID'] = '123456789'
ENV['AWS_ACCESS_KEY'] = 'AKIAZZ007'
ENV['AWS_SECRET_ACCESS_KEY'] = 'asdfghjkl/123456'

ocm = BushSlicer::OCM.new()
json = ocm.generate_json('myosd4')
json = ocm.generate_cluster_data('myosd4').to_json
assert_equal('{"name":"myosd4","managed":true,"multi_az":false,"byoc":true,"region":{"id":"eu-central-1"},"aws":{"account_id":"123456789","access_key_id":"AKIAZZ007","secret_access_key":"asdfghjkl/123456"}}', json)
end

def test_generating_json_with_version
options = { :token => "abc", :version => "4.6.1" }
ocm = BushSlicer::OCM.new(options)
json = ocm.generate_json('myosd4')
json = ocm.generate_cluster_data('myosd4').to_json
assert_equal('{"name":"myosd4","managed":true,"multi_az":false,"byoc":false,"version":{"id":"openshift-v4.6.1"}}', json)
end

def test_generating_json_with_lifespan
def test_generating_cluster_data_with_lifespan
options = { :token => "abc", :lifespan => "25h" }
ocm = BushSlicer::OCM.new(options)
json = ocm.generate_json('myosd4')
json = ocm.generate_cluster_data('myosd4').to_json
time = Time.now + 60 * 60 * 25
year = time.strftime("%Y")
month = time.strftime("%m")
day = time.strftime("%d")
assert_match(/.*"expiration_timestamp":"#{year}-#{month}-#{day}T[0-9][0-9]:[0-9][0-9]:[0-9][0-9]Z".*/, json)
end

def test_generating_json_with_nodes
def test_generating_cluster_data_with_nodes
options = { :token => "abc", :num_nodes => "8" }
ocm = BushSlicer::OCM.new(options)
json = ocm.generate_json('myosd4')
json = ocm.generate_cluster_data('myosd4').to_json
assert_equal('{"name":"myosd4","managed":true,"multi_az":false,"byoc":false,"nodes":{"compute":8}}', json)
end

Expand All @@ -115,15 +115,65 @@ def test_executing_shell
assert_equal("Error when executing '#{hello_script} '. Response: ", error.message)
end

def test_generating_ocp_info
def test_downloading_ocm_cli
options = { :token => "abc" }
ocm = BushSlicer::OCM.new(options)
result = ocm.generate_ocp_info('https://api.osd4-123.w95o.s1.foo.com:6443/', '{ "user": "guest", "password": "some-password" }')
ocm_cli = ocm.download_ocm_cli
assert(File.exists?(ocm_cli), "File '#{ocm_cli}' was not downloaded")
output = ocm.shell('/tmp/ocm version').strip
assert_equal("0.1.46", output)
end

def test_executing_ocm
options = { :token => "abc" }
ocm = BushSlicer::OCM.new(options)
output = ocm.exec("version")
assert_equal("0.1.46", output)
# if we provide some fake ocm-cli
if ENV['OCM_CLI_URL']
output = ocm.get_value("osd4-001", "id")
assert_equal("1ia3pju6itu3oqd8ba6p522858ua49hq", output)
output = ocm.get_value("osd4-001", "state")
assert_equal("ready", output)
output = ocm.get_value("osd4-001", "api.url")
assert_equal("https://api.osd4-001.w95o.s1.foo.com", output)
creds = ocm.get_credentials("osd4-001")
assert_equal("guest", creds["admin"]["user"])
assert_equal("some-password", creds["admin"]["password"])
end
end

def test_generating_ocpinfo_data
options = { :token => "abc" }
ocm = BushSlicer::OCM.new(options)
result = ocm.generate_ocpinfo_data('https://api.osd4-123.w95o.s1.foo.com:6443/', 'guest', 'some-password')
assert_equal('osd4-123.w95o.s1.foo.com', result["ocp_domain"])
assert_equal('https://api.osd4-123.w95o.s1.foo.com:6443', result["ocp_api_url"])
assert_equal('https://console-openshift-console.apps.osd4-123.w95o.s1.foo.com', result["ocp_console_url"])
assert_equal('guest', result["user"])
assert_equal('some-password', result["password"])
result = ocm.generate_ocpinfo_data('https://api.osd4-123.w95o.s1.foo.com', 'guest', 'some-password')
assert_equal('osd4-123.w95o.s1.foo.com', result["ocp_domain"])
assert_equal('https://api.osd4-123.w95o.s1.foo.com:6443', result["ocp_api_url"])
assert_equal('https://console-openshift-console.apps.osd4-123.w95o.s1.foo.com', result["ocp_console_url"])
assert_equal('guest', result["user"])
assert_equal('some-password', result["password"])
end

def test_creating_osd
# only if we provide some fake ocm-cli
if ENV['OCM_CLI_URL']
options = { :token => "abc" }
ocm = BushSlicer::OCM.new(options)
ocm.create_osd("osd4-001")
ocpinfo_file = File.join(BushSlicer::Host.localhost.workdir, 'install-dir', 'OCPINFO.yml')
ocpinfo = YAML.load_file(ocpinfo_file)
assert_equal('osd4-001.w95o.s1.foo.com', ocpinfo['ocp_domain'])
assert_equal('https://console-openshift-console.apps.osd4-001.w95o.s1.foo.com', ocpinfo['ocp_console_url'])
assert_equal('https://api.osd4-001.w95o.s1.foo.com:6443', ocpinfo['ocp_api_url'])
assert_equal('guest', ocpinfo['user'])
assert_equal('some-password', ocpinfo['password'])
end
end

end

0 comments on commit 5b22f63

Please sign in to comment.