Skip to content

Commit

Permalink
[343] Add dev describe
Browse files Browse the repository at this point in the history
  • Loading branch information
zipofar committed Oct 19, 2023
1 parent 749f6cb commit cd5c887
Show file tree
Hide file tree
Showing 11 changed files with 334 additions and 75 deletions.
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,10 @@ gem_build_install:
gem_uninstall:
gem uninstall uffizzi-cli

brew_add_tap:
brew tap UffizziCloud/tap

brew_tap_install:
brew install uffizzicloud/tap/uffizzi

.PHONY: test
123 changes: 56 additions & 67 deletions lib/uffizzi/cli/cluster.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,15 @@ def run(command, command_args = {})

case command
when 'list'
handle_list_command(project_slug)
handle_list_command
when 'create'
handle_create_command(project_slug, command_args)
handle_create_command(command_args)
when 'describe'
handle_describe_command(project_slug, command_args)
handle_describe_command(command_args)
when 'delete'
handle_delete_command(project_slug, command_args)
handle_delete_command(command_args)
when 'update-kubeconfig'
handle_update_kubeconfig_command(project_slug, command_args)
handle_update_kubeconfig_command(command_args)
when 'disconnect'
ClusterDisconnectService.handle(options)
when 'sleep'
Expand All @@ -98,13 +98,12 @@ def run(command, command_args = {})
end
end

def handle_list_command(project_slug)
def handle_list_command
is_all = options[:all]
response = if is_all
get_account_clusters(ConfigFile.read_option(:server), ConfigFile.read_option(:account, :id))
get_account_clusters(server, ConfigFile.read_option(:account, :id))
else
oidc_token = ConfigFile.read_option(:oidc_token)
get_project_clusters(ConfigFile.read_option(:server), project_slug, oidc_token: oidc_token)
get_project_clusters(server, project_slug, oidc_token: oidc_token)
end

if ResponseHelper.ok?(response)
Expand All @@ -115,7 +114,7 @@ def handle_list_command(project_slug)
end

# rubocop:disable Metrics/PerceivedComplexity
def handle_create_command(project_slug, command_args)
def handle_create_command(command_args)
Uffizzi.ui.disable_stdout if Uffizzi.ui.output_format

if options[:name]
Expand All @@ -129,19 +128,19 @@ def handle_create_command(project_slug, command_args)
k8s_version = options[:"k8s-version"]
Uffizzi.ui.say_error_and_exit("Cluster name: #{cluster_name} is not valid.") unless ClusterService.valid_name?(cluster_name)

params = cluster_creation_params(
name: cluster_name,
creation_source: creation_source,
manifest_file_path: options[:manifest],
k8s_version: k8s_version,
)
response = create_cluster(ConfigFile.read_option(:server), project_slug, params)
unless ClusterService.valid_name?(cluster_name)
Uffizzi.ui.say_error_and_exit("Cluster name: #{cluster_name} is not valid.")
end

manifest_file_path = options[:manifest]
params = cluster_creation_params(cluster_name, creation_source, manifest_file_path)
response = create_cluster(server, project_slug, params)

return ResponseHelper.handle_failed_response(response) unless ResponseHelper.created?(response)

spinner = TTY::Spinner.new("[:spinner] Creating cluster #{cluster_name}...", format: :dots)
spinner.auto_spin
cluster_data = ClusterService.wait_cluster_deploy(project_slug, cluster_name, ConfigFile.read_option(:oidc_token))
cluster_data = ClusterService.wait_cluster_deploy(project_slug, cluster_name, oidc_token)

if ClusterService.failed?(cluster_data[:state])
spinner.error
Expand All @@ -151,26 +150,31 @@ def handle_create_command(project_slug, command_args)
spinner.success
handle_succeed_create_response(cluster_data)
rescue SystemExit, Interrupt, SocketError
handle_interrupt_creation(cluster_name, ConfigFile.read_option(:server), project_slug)
handle_interrupt_creation(cluster_name)
end
# rubocop:enable Metrics/PerceivedComplexity

def handle_describe_command(project_slug, command_args)
cluster_data = fetch_cluster_data(project_slug, command_args[:cluster_name])
def handle_describe_command(command_args)
cluster_data = ClusterService.fetch_cluster_data(command_args[:cluster_name], **cluster_api_connection_params)
render_data = ClusterService.build_render_data(cluster_data)

handle_succeed_describe(cluster_data)
if Uffizzi.ui.output_format.nil?
Uffizzi.ui.say(ClusterService.stringify_render_data(render_data))
else
Uffizzi.ui.say(render_data)
end
end

def handle_delete_command(project_slug, command_args)
def handle_delete_command(command_args)
cluster_name = command_args[:cluster_name]
is_delete_kubeconfig = options[:'delete-config']

return handle_delete_cluster(project_slug, cluster_name) unless is_delete_kubeconfig
return handle_delete_cluster(cluster_name) unless is_delete_kubeconfig

cluster_data = fetch_cluster_data(project_slug, cluster_name)
cluster_data = ClusterService.fetch_cluster_data(cluster_name, **cluster_api_connection_params)
kubeconfig = parse_kubeconfig(cluster_data[:kubeconfig])

handle_delete_cluster(project_slug, cluster_name)
handle_delete_cluster(cluster_name)
exclude_kubeconfig(cluster_data[:id], kubeconfig) if kubeconfig.present?
end

Expand All @@ -194,12 +198,12 @@ def exclude_kubeconfig(cluster_id, kubeconfig)
end
end

def handle_delete_cluster(project_slug, cluster_name)
def handle_delete_cluster(cluster_name)
params = {
cluster_name: cluster_name,
oidc_token: ConfigFile.read_option(:oidc_token),
oidc_token: oidc_token,
}
response = delete_cluster(ConfigFile.read_option(:server), project_slug, params)
response = delete_cluster(server, project_slug, params)

if ResponseHelper.no_content?(response)
Uffizzi.ui.say("Cluster #{cluster_name} deleted")
Expand All @@ -208,10 +212,9 @@ def handle_delete_cluster(project_slug, cluster_name)
end
end

def handle_update_kubeconfig_command(project_slug, command_args)
def handle_update_kubeconfig_command(command_args)
kubeconfig_path = options[:kubeconfig] || KubeconfigService.default_path
cluster_name = command_args[:cluster_name]
cluster_data = fetch_cluster_data(project_slug, cluster_name)
cluster_data = ClusterService.fetch_cluster_data(command_args[:cluster_name], **cluster_api_connection_params)

unless cluster_data[:kubeconfig].present?
say_error_update_kubeconfig(cluster_data)
Expand Down Expand Up @@ -291,8 +294,6 @@ def say_error_update_kubeconfig(cluster_data)

def cluster_creation_params(name:, creation_source:, manifest_file_path:, k8s_version:)
manifest_content = load_manifest_file(manifest_file_path)
oidc_token = Uffizzi::ConfigFile.read_option(:oidc_token)

{
cluster: {
name: name,
Expand All @@ -312,7 +313,7 @@ def load_manifest_file(file_path)
raise Uffizzi::Error.new(e.message)
end

def handle_interrupt_creation(cluster_name, server, project_slug)
def handle_interrupt_creation(cluster_name)
deletion_response = delete_cluster(server, project_slug, cluster_name: cluster_name)
deletion_message = if ResponseHelper.no_content?(deletion_response)
"The cluster #{cluster_name} has been disabled."
Expand Down Expand Up @@ -348,24 +349,6 @@ def render_plain_cluster_list(clusters)
end.join("\n")
end

def handle_succeed_describe(cluster_data)
prepared_cluster_data = {
name: cluster_data[:name],
status: cluster_data[:state],
created: Time.strptime(cluster_data[:created_at], '%Y-%m-%dT%H:%M:%S.%N').strftime('%a %b %d %H:%M:%S %Y'),
url: cluster_data[:host],
k8s_version: cluster_data[:k8s_version],
}

rendered_cluster_data = if Uffizzi.ui.output_format.nil?
prepared_cluster_data.map { |k, v| "- #{k.to_s.upcase}: #{v}" }.join("\n").strip
else
prepared_cluster_data
end

Uffizzi.ui.say(rendered_cluster_data)
end

def handle_succeed_create_response(cluster_data)
kubeconfig_path = options[:kubeconfig] || KubeconfigService.default_path
is_update_current_context = options[:'update-current-context']
Expand Down Expand Up @@ -432,20 +415,6 @@ def parse_kubeconfig(kubeconfig)
Psych.safe_load(Base64.decode64(kubeconfig))
end

def fetch_cluster_data(project_slug, cluster_name)
params = {
cluster_name: cluster_name,
oidc_token: ConfigFile.read_option(:oidc_token),
}
response = get_cluster(ConfigFile.read_option(:server), project_slug, params)

if ResponseHelper.ok?(response)
response.dig(:body, :cluster)
else
ResponseHelper.handle_failed_response(response)
end
end

def save_previous_current_context(kubeconfig_path, current_context)
return if kubeconfig_path.nil? || ConfigHelper.previous_current_context_by_path(kubeconfig_path).present?

Expand All @@ -458,5 +427,25 @@ def handle_missing_cluster_name_error
Uffizzi.ui.say('Please update the current context or provide a cluster name.')
Uffizzi.ui.say('$uffizzi cluster sleep my-cluster')
end

def cluster_api_connection_params
{
server: server,
project_slug: project_slug,
oidc_token: oidc_token,
}
end

def oidc_token
@oidc_token ||= ConfigFile.read_option(:oidc_token)
end

def project_slug
@project_slug ||= ConfigFile.read_option(:project)
end

def server
@server ||= ConfigFile.read_option(:server)
end
end
end
79 changes: 72 additions & 7 deletions lib/uffizzi/cli/dev.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ def start(config_path = 'skaffold.yaml')
DevService.check_skaffold_config_existence(config_path)
cluster_id, cluster_name = start_create_cluster
kubeconfig = wait_cluster_creation(cluster_name)
save_config_dev_environment(cluster_name, config_path)

if options[:quiet]
launch_demonise_skaffold(config_path)
Expand All @@ -31,6 +32,7 @@ def start(config_path = 'skaffold.yaml')
if defined?(cluster_name).present? && defined?(cluster_id).present?
kubeconfig = defined?(kubeconfig).present? ? kubeconfig : nil
handle_delete_cluster(cluster_id, cluster_name, kubeconfig)
delete_config_dev_environment(cluster_name)
end
end

Expand All @@ -48,6 +50,26 @@ def stop
File.delete(DevService.pid_path)
end

desc 'describe [NAME]', 'Describe dev environment'
def describe(name = nil)
check_login
dev_environment = get_dev_environment(name)

if dev_environment.nil? && name.present?
return Uffizzi.ui.say("No running dev environment by name: #{name}")
elsif dev_environment.nil?
return Uffizzi.ui.say('No running dev environments')
end

cluster_name = dev_environment[:name]
cluster_data = ClusterService.fetch_cluster_data(cluster_name, **cluster_api_connection_params)
cluster_render_data = ClusterService.build_render_data(cluster_data)
dev_environment_render_data = cluster_render_data.merge(config_path: dev_environment[:config_path])
rendered_data = dev_environment_render_data.map { |k, v| "- #{k.to_s.upcase}: #{v}" }.join("\n").strip

Uffizzi.ui.say(rendered_data)
end

private

def start_create_cluster
Expand All @@ -57,7 +79,7 @@ def start_create_cluster
k8s_version: options[:"k8s-version"],
)
Uffizzi.ui.say('Start creating a cluster')
response = create_cluster(ConfigFile.read_option(:server), project_slug, params)
response = create_cluster(server, project_slug, params)
return ResponseHelper.handle_failed_response(response) unless ResponseHelper.created?(response)

cluster_id = response.dig(:body, :cluster, :id)
Expand All @@ -68,7 +90,7 @@ def start_create_cluster

def wait_cluster_creation(cluster_name)
Uffizzi.ui.say('Checking the cluster status...')
cluster_data = ClusterService.wait_cluster_deploy(project_slug, cluster_name, ConfigFile.read_option(:oidc_token))
cluster_data = ClusterService.wait_cluster_deploy(project_slug, cluster_name, oidc_token)

if ClusterService.failed?(cluster_data[:state])
Uffizzi.ui.say_error_and_exit("Cluster with name: #{cluster_name} failed to be created.")
Expand Down Expand Up @@ -109,9 +131,7 @@ def update_clusters_config(id, params)
ConfigFile.write_option(:clusters, clusters_config)
end

def cluster_creation_params(name:, creation_source:, k8s_version:)
oidc_token = Uffizzi::ConfigFile.read_option(:oidc_token)

def cluster_creation_params(name, creation_source)
{
cluster: {
name: name,
Expand All @@ -130,9 +150,9 @@ def handle_delete_cluster(cluster_id, cluster_name, kubeconfig)

params = {
cluster_name: cluster_name,
oidc_token: ConfigFile.read_option(:oidc_token),
oidc_token: oidc_token,
}
response = delete_cluster(ConfigFile.read_option(:server), project_slug, params)
response = delete_cluster(server, project_slug, params)

if ResponseHelper.no_content?(response)
Uffizzi.ui.say("Cluster #{cluster_name} deleted")
Expand Down Expand Up @@ -191,8 +211,53 @@ def launch_demonise_skaffold(config_path)
File.open(DevService.logs_path, 'a') { |f| f.puts(e.message) }
end

def save_config_dev_environment(cluster_name, config_path)
params = options.merge(config_path: File.expand_path(config_path))
dev_environments = Uffizzi::ConfigHelper.set_dev_environment(cluster_name, params)
ConfigFile.write_option(:dev_environments, dev_environments)
end

def delete_config_dev_environment(cluster_name)
dev_environments = Uffizzi::ConfigHelper.dev_environments_without(cluster_name)
ConfigFile.write_option(:dev_environments, dev_environments)
end

def get_dev_environment(name)
dev_environments = ConfigHelper.dev_environments

if name.present?
ConfigHelper.dev_environments_by_name(name)
elsif dev_environments.count == 1
dev_environments.last
elsif dev_environments.count > 1
choices = dev_environments.map do |dev_env|
{ name: dev_env[:config_path], value: dev_env[:name] }
end

question = 'You have several dev environments, select one for describe:'
answer = Uffizzi.prompt.select(question, choices)
ConfigHelper.dev_environments_by_name(answer)
end
end

def cluster_api_connection_params
{
server: server,
project_slug: project_slug,
oidc_token: oidc_token,
}
end

def project_slug
@project_slug ||= ConfigFile.read_option(:project)
end

def oidc_token
@oidc_token ||= ConfigFile.read_option(:oidc_token)
end

def server
@server ||= ConfigFile.read_option(:server)
end
end
end
Loading

0 comments on commit cd5c887

Please sign in to comment.