Class: Deploio::NctlClient

Inherits:
Object
  • Object
show all
Defined in:
lib/deploio/nctl_client.rb

Constant Summary collapse

REQUIRED_VERSION =
"1.10.0"

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(dry_run: false) ⇒ NctlClient

Returns a new instance of NctlClient.



12
13
14
# File 'lib/deploio/nctl_client.rb', line 12

def initialize(dry_run: false)
  @dry_run = dry_run
end

Instance Attribute Details

#dry_runObject (readonly)

Returns the value of attribute dry_run.



10
11
12
# File 'lib/deploio/nctl_client.rb', line 10

def dry_run
  @dry_run
end

Instance Method Details

#auth_loginObject



288
289
290
# File 'lib/deploio/nctl_client.rb', line 288

def 
  exec_passthrough("auth", "login")
end

#auth_logoutObject



292
293
294
# File 'lib/deploio/nctl_client.rb', line 292

def auth_logout
  run("auth", "logout")
end

#auth_whoamiObject



296
297
298
# File 'lib/deploio/nctl_client.rb', line 296

def auth_whoami
  exec_passthrough("auth", "whoami")
end

#build_logs(build_name, app_ref: nil, tail: false, lines: 5000) ⇒ Object



29
30
31
32
33
34
35
36
# File 'lib/deploio/nctl_client.rb', line 29

def build_logs(build_name, app_ref: nil, tail: false, lines: 5000)
  args = ["--lines=#{lines}"]
  args << "-f" if tail
  if app_ref
    args += ["--project", app_ref.project_name, "-a", app_ref.app_name]
  end
  exec_passthrough("logs", "build", *[build_name].compact, *args)
end

#check_requirementsObject



16
17
18
19
# File 'lib/deploio/nctl_client.rb', line 16

def check_requirements
  check_nctl_installed
  check_nctl_version
end

#current_orgObject



256
257
258
# File 'lib/deploio/nctl_client.rb', line 256

def current_org
  get_orgs.find { |o| o["current"] }&.fetch("name", nil)
end

#exec_command(app_ref, command) ⇒ Object



38
39
40
41
42
# File 'lib/deploio/nctl_client.rb', line 38

def exec_command(app_ref, command)
  exec_passthrough("exec", "app", app_ref.app_name,
    "--project", app_ref.project_name,
    "--", *command)
end

#get_all_appsObject



44
45
46
47
48
49
50
51
52
53
54
# File 'lib/deploio/nctl_client.rb', line 44

def get_all_apps
  @all_apps ||= begin
    output = capture("get", "apps", "-A", "-o", "json")
    return [] if output.nil? || output.empty?

    data = JSON.parse(output)
    data.is_a?(Array) ? data : (data["items"] || [])
  rescue JSON::ParserError
    []
  end
end

#get_all_buildsObject



113
114
115
116
117
118
119
120
121
122
123
# File 'lib/deploio/nctl_client.rb', line 113

def get_all_builds
  output = capture("get", "builds", "-A", "-o", "json")
  return [] if output.nil? || output.empty?

  data = JSON.parse(output)
  builds = data.is_a?(Array) ? data : (data["items"] || [])
  # Sort by creation timestamp descending (newest first)
  builds.sort_by { |b| b.dig("metadata", "creationTimestamp") || "" }.reverse
rescue JSON::ParserError
  []
end

#get_all_pg_databasesObject



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/deploio/nctl_client.rb', line 67

def get_all_pg_databases
  output_dedicated_dbs = capture("get", "postgres", "-A", "-o", "json")
  output_shared_dbs = capture("get", "postgresdatabase", "-A", "-o", "json")
  if (output_dedicated_dbs.nil? || output_dedicated_dbs.empty?) &&
      (output_shared_dbs.nil? || output_shared_dbs.empty?)
    return []
  end

  [
    *JSON.parse(output_dedicated_dbs),
    *JSON.parse(output_shared_dbs)
  ]
rescue JSON::ParserError
  []
end

#get_all_services(project: nil) ⇒ Object



141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/deploio/nctl_client.rb', line 141

def get_all_services(project: nil)
  service_types = %w[keyvaluestore postgres postgresdatabases mysql mysqldatabases opensearch bucket]
  all_services = []

  service_types.each do |type|
    services = get_services_by_type(type, project: project)
    services.each { |s| s["_type"] = type }
    all_services.concat(services)
  end

  all_services
end

#get_app(app_ref) ⇒ Object



56
57
58
59
60
61
62
63
64
65
# File 'lib/deploio/nctl_client.rb', line 56

def get_app(app_ref)
  output = capture("get", "app", app_ref.app_name,
    "--project", app_ref.project_name,
    "-o", "json")
  return {} if output.nil? || output.empty?

  JSON.parse(output)
rescue JSON::ParserError
  {}
end

#get_apps_by_project(project) ⇒ Object



103
104
105
106
107
108
109
110
111
# File 'lib/deploio/nctl_client.rb', line 103

def get_apps_by_project(project)
  output = capture("get", "apps", "--project", project, "-o", "json")
  return [] if output.nil? || output.empty?

  data = JSON.parse(output)
  data.is_a?(Array) ? data : (data["items"] || [])
rescue JSON::ParserError
  []
end

#get_bucket_user_access_key(name, project:) ⇒ Object



200
201
202
# File 'lib/deploio/nctl_client.rb', line 200

def get_bucket_user_access_key(name, project:)
  capture("get", "bucketuser", name, "--project", project, "--print-access-key").strip
end

#get_bucket_user_secret_key(name, project:) ⇒ Object



204
205
206
# File 'lib/deploio/nctl_client.rb', line 204

def get_bucket_user_secret_key(name, project:)
  capture("get", "bucketuser", name, "--project", project, "--print-secret-key").strip
end

#get_builds(app_ref) ⇒ Object

Parameters:



126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/deploio/nctl_client.rb', line 126

def get_builds(app_ref)
  output = capture("get", "builds",
    "--project", app_ref.project_name,
    "-a", app_ref.app_name,
    "-o", "json")
  return [] if output.nil? || output.empty?

  data = JSON.parse(output)
  builds = data.is_a?(Array) ? data : (data["items"] || [])
  # Sort by creation timestamp descending (newest first)
  builds.sort_by { |b| b.dig("metadata", "creationTimestamp") || "" }.reverse
rescue JSON::ParserError
  []
end

#get_orgsObject



249
250
251
252
253
254
# File 'lib/deploio/nctl_client.rb', line 249

def get_orgs
  output = capture("auth", "whoami")
  return [] if output.nil? || output.empty?

  parse_orgs_from_whoami(output)
end

#get_pg_database(db_ref) ⇒ Object



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/deploio/nctl_client.rb', line 83

def get_pg_database(db_ref)
  output = begin
    capture("get", "postgres", db_ref.database_name,
      "--project", db_ref.project_name, "-o", "json")
  rescue Deploio::NctlError
    nil
  end

  if output.nil? || output.empty?
    output = capture("get", "postgresdatabase", db_ref.database_name,
      "--project", db_ref.project_name, "-o", "json")
  end

  return nil if output.nil? || output.empty?

  JSON.parse(output)
rescue JSON::ParserError
  nil
end

#get_project_display_namesObject

Enrich with display names from table output (since JSON excludes spec.displayName) TODO: https://github.com/ninech/nctl/pull/339



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/deploio/nctl_client.rb', line 231

def get_project_display_names
  output = capture("get", "projects")
  return {} if output.nil? || output.empty?

  display_names = {}
  output.each_line.drop(1).each do |line| # Skip header
    parts = line.strip.split(" ").map(&:strip)
    next if parts.length < 2

    project_name = parts[0]
    display_name = parts[1]
    display_names[project_name] = display_name unless display_name == "<none>"
  end
  display_names
rescue Deploio::NctlError
  {}
end

#get_projectsObject



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/deploio/nctl_client.rb', line 208

def get_projects
  output = capture("get", "projects", "-o", "json")
  return [] if output.nil? || output.empty?

  data = JSON.parse(output)
  projects = data.is_a?(Array) ? data : (data["items"] || [])

  display_names = get_project_display_names
  projects.each do |project|
    name = project.dig("metadata", "name")
    if display_names[name]
      project["spec"] ||= {}
      project["spec"]["displayName"] = display_names[name]
    end
  end

  projects
rescue JSON::ParserError
  []
end

#get_service(type, name, project:) ⇒ Object



174
175
176
177
178
179
180
181
182
183
# File 'lib/deploio/nctl_client.rb', line 174

def get_service(type, name, project:)
  output = capture("get", type, name, "--project", project, "-o", "json")
  return nil if output.nil? || output.empty?

  JSON.parse(output)
rescue JSON::ParserError
  nil
rescue Deploio::NctlError
  nil
end

#get_service_connection_string(type, name, project:) ⇒ Object



185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/deploio/nctl_client.rb', line 185

def get_service_connection_string(type, name, project:)
  case type
  when "postgres", "mysql", "postgresdatabases", "mysqldatabases"
    capture("get", type, name, "--project", project, "--print-connection-string").strip
  when "keyvaluestore"
    build_keyvaluestore_connection_string(name, project)
  when "opensearch"
    build_opensearch_connection_string(name, project)
  when "bucket"
    build_bucket_url(name, project)
  end
rescue Deploio::NctlError
  nil
end

#get_services_by_type(type, project: nil) ⇒ Object



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/deploio/nctl_client.rb', line 154

def get_services_by_type(type, project: nil)
  args = ["get", type]
  if project
    args += ["--project", project]
  else
    args << "-A"
  end
  args += ["-o", "json"]

  output = capture(*args)
  return [] if output.nil? || output.empty?

  data = JSON.parse(output)
  data.is_a?(Array) ? data : (data["items"] || [])
rescue JSON::ParserError
  []
rescue Deploio::NctlError
  []
end

#logs(app_ref, tail: false, lines: 100) ⇒ Object



21
22
23
24
25
26
27
# File 'lib/deploio/nctl_client.rb', line 21

def logs(app_ref, tail: false, lines: 100)
  args = ["--lines=#{lines}"]
  args << "-f" if tail
  exec_passthrough("logs", "app", app_ref.app_name,
    "--project", app_ref.project_name,
    *args)
end

#parse_orgs_from_whoami(output) ⇒ Object



260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
# File 'lib/deploio/nctl_client.rb', line 260

def parse_orgs_from_whoami(output)
  orgs = []
  in_orgs_section = false

  output.each_line do |line|
    if line.include?("Available Organizations:")
      in_orgs_section = true
      next
    end

    next unless in_orgs_section
    break if line.strip.empty? || line.start_with?("To switch")

    # Lines are either "*\torg_name" (current) or "\torg_name"
    current = line.start_with?("*")
    org_name = line.sub(/^\*?\t/, "").strip
    next if org_name.empty?

    orgs << {"name" => org_name, "current" => current}
  end

  orgs
end

#set_org(org_name) ⇒ Object



284
285
286
# File 'lib/deploio/nctl_client.rb', line 284

def set_org(org_name)
  run("auth", "set-org", org_name)
end