uffizzi-cli 2.0.37 → 2.1.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f2764a609f5446a2b7f1a11ac9ec37619b14f441278dd220142edbab2b106876
4
- data.tar.gz: 5f7196a3c7ef61b8d67685d14ce806b7651c9141de0795cb09248455602fed48
3
+ metadata.gz: 8fc9021c07ec1fbbbd32baab4e37dcdf3eb9b7368843701e9c0a086da8eefefe
4
+ data.tar.gz: ccf95b0bd9ae6fffa906a15012825a9c9d4b209263e0735ce200d5ba5ca953b8
5
5
  SHA512:
6
- metadata.gz: 741e72b2f9c8c20c6a1bd7631af35f55b321b785b5defb052ea98cd273df80edc31223527bf30bffd59f5f0f3c0269f771ca6473be61292e8b8e985414bd0a44
7
- data.tar.gz: f3f0f3ab58fcda3b73d8ab178a79d79591f8a86e63ae7e5d78b70eb3e6188732fb7e65a3e664bb0ada2cb7d04a0cb4c51281857b2165a833d2baf193fcbf5ca2
6
+ metadata.gz: aeb135bb03097b24c39b408e10bc31fa995d3cd4da3284eacc07be126b04a5aaf18a02e5cf432e5e9f46a24bb842c79209d3100ec8d0b94efde7f8c9a5b43ae4
7
+ data.tar.gz: 29d2160ec30fd61f9f5bf96ef24dea226b6388e9ab1bcf47b3c6a66a2b518df17bc9013d5d036dc5f3c6b517e30f2de0015a46d2ce933f8332113943e84a9b54
@@ -0,0 +1,177 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'uffizzi/services/command_service'
4
+ require 'uffizzi/services/cluster_service'
5
+ require 'uffizzi/services/kubeconfig_service'
6
+
7
+ module Uffizzi
8
+ class Cli::Dev < Thor
9
+ include ApiClient
10
+
11
+ desc 'start [CONFIG]', 'Start dev environment'
12
+ def start(config_path = 'skaffold.yaml')
13
+ check_skaffold_existence
14
+ check_login
15
+ cluster_id, cluster_name = start_create_cluster
16
+ kubeconfig = wait_cluster_creation(cluster_name)
17
+ launch_scaffold(config_path)
18
+ ensure
19
+ if defined?(cluster_name).present? && defined?(cluster_id).present?
20
+ kubeconfig = defined?(kubeconfig).present? ? kubeconfig : nil
21
+ handle_delete_cluster(cluster_id, cluster_name, kubeconfig)
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def check_login
28
+ raise Uffizzi::Error.new('You are not logged in.') unless Uffizzi::AuthHelper.signed_in?
29
+ raise Uffizzi::Error.new('This command needs project to be set in config file') unless CommandService.project_set?(options)
30
+ end
31
+
32
+ def start_create_cluster
33
+ cluster_name = ClusterService.generate_name
34
+ creation_source = MANUAL
35
+ params = cluster_creation_params(cluster_name, creation_source)
36
+ Uffizzi.ui.say('Start creating a cluster')
37
+ response = create_cluster(ConfigFile.read_option(:server), project_slug, params)
38
+ return ResponseHelper.handle_failed_response(response) unless ResponseHelper.created?(response)
39
+
40
+ cluster_id = response.dig(:body, :cluster, :id)
41
+ cluster_name = response.dig(:body, :cluster, :name)
42
+
43
+ [cluster_id, cluster_name]
44
+ end
45
+
46
+ def wait_cluster_creation(cluster_name)
47
+ Uffizzi.ui.say('Checking the cluster status...')
48
+ cluster_data = ClusterService.wait_cluster_deploy(project_slug, cluster_name, ConfigFile.read_option(:oidc_token))
49
+
50
+ if ClusterService.failed?(cluster_data[:state])
51
+ Uffizzi.ui.say_error_and_exit("Cluster with name: #{cluster_name} failed to be created.")
52
+ end
53
+
54
+ handle_succeed_cluster_creation(cluster_data)
55
+ parse_kubeconfig(cluster_data[:kubeconfig])
56
+ end
57
+
58
+ def handle_succeed_cluster_creation(cluster_data)
59
+ kubeconfig_path = KubeconfigService.default_path
60
+ parsed_kubeconfig = parse_kubeconfig(cluster_data[:kubeconfig])
61
+
62
+ Uffizzi.ui.say("Cluster with name: #{cluster_data[:name]} was created.")
63
+
64
+ save_kubeconfig(parsed_kubeconfig, kubeconfig_path)
65
+ update_clusters_config(cluster_data[:id], kubeconfig_path: kubeconfig_path)
66
+ end
67
+
68
+ def save_kubeconfig(kubeconfig, kubeconfig_path)
69
+ KubeconfigService.save_to_filepath(kubeconfig_path, kubeconfig) do |kubeconfig_by_path|
70
+ merged_kubeconfig = KubeconfigService.merge(kubeconfig_by_path, kubeconfig)
71
+
72
+ new_current_context = KubeconfigService.get_current_context(kubeconfig)
73
+ new_kubeconfig = KubeconfigService.update_current_context(merged_kubeconfig, new_current_context)
74
+
75
+ next new_kubeconfig if kubeconfig_by_path.nil?
76
+
77
+ previous_current_context = KubeconfigService.get_current_context(kubeconfig_by_path)
78
+ save_previous_current_context(kubeconfig_path, previous_current_context)
79
+ new_kubeconfig
80
+ end
81
+ end
82
+
83
+ def update_clusters_config(id, params)
84
+ clusters_config = Uffizzi::ConfigHelper.update_clusters_config_by_id(id, params)
85
+ ConfigFile.write_option(:clusters, clusters_config)
86
+ end
87
+
88
+ def cluster_creation_params(name, creation_source)
89
+ oidc_token = Uffizzi::ConfigFile.read_option(:oidc_token)
90
+
91
+ {
92
+ cluster: {
93
+ name: name,
94
+ manifest: nil,
95
+ creation_source: creation_source,
96
+ },
97
+ token: oidc_token,
98
+ }
99
+ end
100
+
101
+ def handle_delete_cluster(cluster_id, cluster_name, kubeconfig)
102
+ exclude_kubeconfig(cluster_id, kubeconfig) if kubeconfig.present?
103
+
104
+ params = {
105
+ cluster_name: cluster_name,
106
+ oidc_token: ConfigFile.read_option(:oidc_token),
107
+ }
108
+ response = delete_cluster(ConfigFile.read_option(:server), project_slug, params)
109
+
110
+ if ResponseHelper.no_content?(response)
111
+ Uffizzi.ui.say("Cluster #{cluster_name} deleted")
112
+ else
113
+ ResponseHelper.handle_failed_response(response)
114
+ end
115
+ end
116
+
117
+ def exclude_kubeconfig(cluster_id, kubeconfig)
118
+ cluster_config = Uffizzi::ConfigHelper.cluster_config_by_id(cluster_id)
119
+ return if cluster_config.nil?
120
+
121
+ kubeconfig_path = cluster_config[:kubeconfig_path]
122
+ ConfigFile.write_option(:clusters, Uffizzi::ConfigHelper.clusters_config_without(cluster_id))
123
+
124
+ KubeconfigService.save_to_filepath(kubeconfig_path, kubeconfig) do |kubeconfig_by_path|
125
+ return if kubeconfig_by_path.nil?
126
+
127
+ new_kubeconfig = KubeconfigService.exclude(kubeconfig_by_path, kubeconfig)
128
+ new_current_context = find_previous_current_context(new_kubeconfig, kubeconfig_path)
129
+ KubeconfigService.update_current_context(new_kubeconfig, new_current_context)
130
+ end
131
+ end
132
+
133
+ def find_previous_current_context(kubeconfig, kubeconfig_path)
134
+ prev_current_context = Uffizzi::ConfigHelper.previous_current_context_by_path(kubeconfig_path)&.fetch(:current_context, nil)
135
+
136
+ if KubeconfigService.find_cluster_contexts_by_name(kubeconfig, prev_current_context).present?
137
+ prev_current_context
138
+ end
139
+ end
140
+
141
+ def save_previous_current_context(kubeconfig_path, current_context)
142
+ previous_current_contexts = Uffizzi::ConfigHelper.set_previous_current_context_by_path(kubeconfig_path, current_context)
143
+ ConfigFile.write_option(:previous_current_contexts, previous_current_contexts)
144
+ end
145
+
146
+ def parse_kubeconfig(kubeconfig)
147
+ return if kubeconfig.nil?
148
+
149
+ Psych.safe_load(Base64.decode64(kubeconfig))
150
+ end
151
+
152
+ def launch_scaffold(config_path)
153
+ Uffizzi.ui.say('Start skaffold')
154
+ cmd = "skaffold dev --filename='#{config_path}'"
155
+
156
+ Uffizzi.ui.popen2e(cmd) do |_stdin, stdout_and_stderr, wait_thr|
157
+ stdout_and_stderr.each { |l| puts l }
158
+ wait_thr.value
159
+ end
160
+ end
161
+
162
+ def check_skaffold_existence
163
+ cmd = 'skaffold version'
164
+ stdout_str, stderr_str = Uffizzi.ui.capture3(cmd)
165
+
166
+ return if stdout_str.present? && stderr_str.blank?
167
+
168
+ Uffizzi.ui.say_error_and_exit(stderr_str)
169
+ rescue StandardError => e
170
+ Uffizzi.ui.say_error_and_exit(e.message)
171
+ end
172
+
173
+ def project_slug
174
+ @project_slug ||= ConfigFile.read_option(:project)
175
+ end
176
+ end
177
+ end
data/lib/uffizzi/cli.rb CHANGED
@@ -71,6 +71,10 @@ module Uffizzi
71
71
  Disconnect.new.run(credential_type)
72
72
  end
73
73
 
74
+ desc 'dev', 'dev'
75
+ require_relative 'cli/dev'
76
+ subcommand 'dev', Cli::Dev
77
+
74
78
  map preview: :compose
75
79
 
76
80
  class << self
@@ -9,8 +9,6 @@ class ClusterDisconnectService
9
9
  def handle(options)
10
10
  kubeconfig_path = options[:kubeconfig] || KubeconfigService.default_path
11
11
  is_ask_origin_current_context = options[:ask]
12
-
13
- prev_current_context = Uffizzi::ConfigHelper.previous_current_context_by_path(kubeconfig_path)&.fetch(:current_context, nil)
14
12
  kubeconfig = KubeconfigService.read_kubeconfig(kubeconfig_path)
15
13
 
16
14
  if kubeconfig.nil?
@@ -18,12 +16,14 @@ class ClusterDisconnectService
18
16
  end
19
17
 
20
18
  contexts = KubeconfigService.get_cluster_contexts(kubeconfig)
21
- current_context = KubeconfigService.get_current_context(kubeconfig)
22
19
 
23
20
  if contexts.empty?
24
21
  return Uffizzi.ui.say("No contexts by kubeconfig path #{kubeconfig_path}")
25
22
  end
26
23
 
24
+ prev_current_context = Uffizzi::ConfigHelper.previous_current_context_by_path(kubeconfig_path)&.fetch(:current_context, nil)
25
+ current_context = KubeconfigService.get_current_context(kubeconfig)
26
+
27
27
  if KubeconfigService.find_cluster_contexts_by_name(kubeconfig, prev_current_context).present? &&
28
28
  prev_current_context != current_context &&
29
29
  !is_ask_origin_current_context
data/lib/uffizzi/shell.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'awesome_print'
4
+ require 'open3'
4
5
 
5
6
  module Uffizzi
6
7
  module UI
@@ -54,6 +55,14 @@ module Uffizzi
54
55
  $stdout.stat.pipe?
55
56
  end
56
57
 
58
+ def popen2e(command, &block)
59
+ Open3.popen2e(command, &block)
60
+ end
61
+
62
+ def capture3(command)
63
+ Open3.capture3(command)
64
+ end
65
+
57
66
  private
58
67
 
59
68
  def format_to_json(data)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Uffizzi
4
- VERSION = '2.0.37'
4
+ VERSION = '2.1.0'
5
5
  end
@@ -17,7 +17,7 @@ https://docs\.uffizzi\.com/references/cli/
17
17
  .fi
18
18
  .SH "FLAGS"
19
19
  .nf
20
- \-\- name
20
+ \-\-name
21
21
  Option is deprecated and will be removed in the newer versions\.
22
22
  Please use a positional argument instead: uffizzi cluster create my\-awesome\-name\.
23
23
 
@@ -0,0 +1,29 @@
1
+ .\" generated with Ronn-NG/v0.9.1
2
+ .\" http://github.com/apjanke/ronn-ng/tree/0.9.1
3
+ .TH "UFFIZZI\-DEV\-START" "" "September 2023" ""
4
+ .SH "NAME"
5
+ \fBuffizzi\-dev\-start\fR \- start development environment
6
+ .SH "SYNOPSIS"
7
+ .nf
8
+ uffizzi dev start [SKAFFOLD_CONFIG_FILE_PATH]
9
+ .fi
10
+ .SH "DESCRIPTION"
11
+ .nf
12
+ Creates a new cluster and start skaffold\. If no SKAFFOLD_CONFIG_FILE_PATH is specified,
13
+ the default path will be used\.
14
+ Default SKAFFOLD_CONFIG_FILE_PATH is \'skaffold\.yaml\'
15
+
16
+ For more information on Uffizzi clusters, see:
17
+ https://docs\.uffizzi\.com/references/cli/
18
+ .fi
19
+ .SH "EXAMPLES"
20
+ .nf
21
+ To start development environment, run:
22
+
23
+ $ uffizzi dev start
24
+
25
+ To start development environment with custom skaffold\.yaml file, run:
26
+
27
+ $ uffizzi cluster create /path/to/skaffold\.yaml
28
+ .fi
29
+
@@ -0,0 +1,22 @@
1
+ uffizzi-dev-start - start development environment
2
+ ================================================================
3
+
4
+ ## SYNOPSIS
5
+ uffizzi dev start [SKAFFOLD_CONFIG_FILE_PATH]
6
+
7
+ ## DESCRIPTION
8
+ Creates a new cluster and start skaffold. If no SKAFFOLD_CONFIG_FILE_PATH is specified,
9
+ the default path will be used.
10
+ Default SKAFFOLD_CONFIG_FILE_PATH is 'skaffold.yaml'
11
+
12
+ For more information on Uffizzi clusters, see:
13
+ https://docs.uffizzi.com/references/cli/
14
+
15
+ ## EXAMPLES
16
+ To start development environment, run:
17
+
18
+ $ uffizzi dev start
19
+
20
+ To start development environment with custom skaffold.yaml file, run:
21
+
22
+ $ uffizzi cluster create /path/to/skaffold.yaml
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: uffizzi-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.37
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Josh Thurman
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2023-09-19 00:00:00.000000000 Z
12
+ date: 2023-09-29 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
@@ -423,6 +423,7 @@ files:
423
423
  - lib/uffizzi/cli/common.rb
424
424
  - lib/uffizzi/cli/config.rb
425
425
  - lib/uffizzi/cli/connect.rb
426
+ - lib/uffizzi/cli/dev.rb
426
427
  - lib/uffizzi/cli/disconnect.rb
427
428
  - lib/uffizzi/cli/login.rb
428
429
  - lib/uffizzi/cli/login_by_identity_token.rb
@@ -518,6 +519,8 @@ files:
518
519
  - man/uffizzi-connect-ghcr
519
520
  - man/uffizzi-connect-ghcr.ronn
520
521
  - man/uffizzi-connect.ronn
522
+ - man/uffizzi-dev-start
523
+ - man/uffizzi-dev-start.ronn
521
524
  - man/uffizzi-disconnect
522
525
  - man/uffizzi-disconnect.ronn
523
526
  - man/uffizzi-login