Class: Controlplane
- Inherits:
-
Object
- Object
- Controlplane
- Defined in:
- lib/core/controlplane.rb
Overview
rubocop:disable Metrics/ClassLength
Instance Attribute Summary collapse
-
#api ⇒ Object
readonly
Returns the value of attribute api.
-
#config ⇒ Object
readonly
Returns the value of attribute config.
-
#gvc ⇒ Object
readonly
Returns the value of attribute gvc.
-
#org ⇒ Object
readonly
Returns the value of attribute org.
Instance Method Summary collapse
- #apply_hash(data) ⇒ Object
-
#apply_template(data) ⇒ Object
apply.
- #bind_identity_to_policy(identity_link, policy) ⇒ Object
- #delete_volumeset(volumeset, a_gvc = gvc) ⇒ Object
- #delete_workload(workload, a_gvc = gvc) ⇒ Object
- #domain_workload_matches?(data, workload) ⇒ Boolean
- #fetch_domain(domain) ⇒ Object
- #fetch_gvc(a_gvc = gvc, a_org = org) ⇒ Object
- #fetch_gvc!(a_gvc = gvc) ⇒ Object
-
#fetch_gvcs ⇒ Object
gvc.
-
#fetch_identity(identity, a_gvc = gvc) ⇒ Object
identities.
-
#fetch_policy(policy) ⇒ Object
policies.
-
#fetch_volumesets(a_gvc = gvc) ⇒ Object
volumeset.
- #fetch_workload(workload) ⇒ Object
- #fetch_workload!(workload) ⇒ Object
- #fetch_workload_deployments(workload) ⇒ Object
-
#fetch_workloads(a_gvc = gvc) ⇒ Object
workload.
- #fetch_workloads_by_org(a_org = org) ⇒ Object
- #find_domain_for(workloads) ⇒ Object
-
#find_domain_route(data) ⇒ Object
domain.
- #gvc_delete(a_gvc = gvc) ⇒ Object
- #gvc_query(app_name = config.app) ⇒ Object
- #image_build(image, dockerfile:, docker_args: [], build_args: [], push: true) ⇒ Object
- #image_delete(image) ⇒ Object
- #image_login(org_name = config.org) ⇒ Object
- #image_pull(image) ⇒ Object
- #image_push(image) ⇒ Object
- #image_tag(old_tag, new_tag) ⇒ Object
-
#initialize(config) ⇒ Controlplane
constructor
A new instance of Controlplane.
- #log_get(workload:, from:, to:) ⇒ Object
-
#logs(workload:) ⇒ Object
logs.
-
#parse_apply_result(result) ⇒ Object
rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity.
- #profile_create(profile, token) ⇒ Object
- #profile_delete(profile) ⇒ Object
- #profile_exists?(profile) ⇒ Boolean
-
#profile_switch(profile) ⇒ Object
profile.
-
#query_images(a_gvc = gvc, a_org = org, partial_gvc_match: nil) ⇒ Object
image.
- #query_workloads(workload, a_gvc = gvc, a_org = org, partial_workload_match: false, partial_gvc_match: nil) ⇒ Object
- #set_domain_workload(data, workload) ⇒ Object
- #set_workload_env_var(workload, container:, name:, value:) ⇒ Object
- #set_workload_suspend(workload, value) ⇒ Object
- #workload_connect(workload, location:, container: nil, shell: nil) ⇒ Object
- #workload_deployment_version_ready?(version, next_version, expected_status:) ⇒ Boolean
- #workload_deployments_ready?(workload, expected_status:) ⇒ Boolean
- #workload_exec(workload, location:, container: nil, command: nil) ⇒ Object
- #workload_force_redeployment(workload) ⇒ Object
- #workload_get_replicas(workload, location:) ⇒ Object
- #workload_get_replicas_safely(workload, location:) ⇒ Object
- #workload_set_image_ref(workload, container:, image:) ⇒ Object
Constructor Details
#initialize(config) ⇒ Controlplane
Returns a new instance of Controlplane.
6 7 8 9 10 11 |
# File 'lib/core/controlplane.rb', line 6 def initialize(config) @config = config @api = ControlplaneApi.new @gvc = config.app @org = config.org end |
Instance Attribute Details
#api ⇒ Object (readonly)
Returns the value of attribute api.
4 5 6 |
# File 'lib/core/controlplane.rb', line 4 def api @api end |
#config ⇒ Object (readonly)
Returns the value of attribute config.
4 5 6 |
# File 'lib/core/controlplane.rb', line 4 def config @config end |
#gvc ⇒ Object (readonly)
Returns the value of attribute gvc.
4 5 6 |
# File 'lib/core/controlplane.rb', line 4 def gvc @gvc end |
#org ⇒ Object (readonly)
Returns the value of attribute org.
4 5 6 |
# File 'lib/core/controlplane.rb', line 4 def org @org end |
Instance Method Details
#apply_hash(data) ⇒ Object
343 344 345 |
# File 'lib/core/controlplane.rb', line 343 def apply_hash(data) apply_template(data.to_yaml) end |
#apply_template(data) ⇒ Object
apply
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 |
# File 'lib/core/controlplane.rb', line 322 def apply_template(data) # rubocop:disable Metrics/MethodLength Tempfile.create do |f| f.write(data) f.rewind cmd = "cpln apply #{gvc_org} --file #{f.path}" if Shell.tmp_stderr cmd += " 2> #{Shell.tmp_stderr.path}" if Shell.should_hide_output? Shell.debug("CMD", cmd) result = `#{cmd}` $CHILD_STATUS.success? ? parse_apply_result(result) : false else Shell.debug("CMD", cmd) result = `#{cmd}` $CHILD_STATUS.success? ? parse_apply_result(result) : exit(1) end end end |
#bind_identity_to_policy(identity_link, policy) ⇒ Object
315 316 317 318 319 |
# File 'lib/core/controlplane.rb', line 315 def bind_identity_to_policy(identity_link, policy) cmd = "cpln policy add-binding #{policy} --org #{org} --identity #{identity_link} --permission reveal" cmd += " > /dev/null" if Shell.should_hide_output? perform!(cmd) end |
#delete_volumeset(volumeset, a_gvc = gvc) ⇒ Object
246 247 248 |
# File 'lib/core/controlplane.rb', line 246 def delete_volumeset(volumeset, a_gvc = gvc) api.delete_volumeset(org: org, gvc: a_gvc, volumeset: volumeset) end |
#delete_workload(workload, a_gvc = gvc) ⇒ Object
222 223 224 |
# File 'lib/core/controlplane.rb', line 222 def delete_workload(workload, a_gvc = gvc) api.delete_workload(org: org, gvc: a_gvc, workload: workload) end |
#domain_workload_matches?(data, workload) ⇒ Boolean
280 281 282 283 |
# File 'lib/core/controlplane.rb', line 280 def domain_workload_matches?(data, workload) route = find_domain_route(data) route["workloadLink"].match?(%r{/org/#{org}/gvc/#{gvc}/workload/#{workload}}) end |
#fetch_domain(domain) ⇒ Object
272 273 274 275 276 277 278 |
# File 'lib/core/controlplane.rb', line 272 def fetch_domain(domain) domain_data = api.fetch_domain(org: org, domain: domain) route = find_domain_route(domain_data) return nil if route.nil? domain_data end |
#fetch_gvc(a_gvc = gvc, a_org = org) ⇒ Object
104 105 106 |
# File 'lib/core/controlplane.rb', line 104 def fetch_gvc(a_gvc = gvc, a_org = org) api.gvc_get(gvc: a_gvc, org: a_org) end |
#fetch_gvc!(a_gvc = gvc) ⇒ Object
108 109 110 111 112 113 |
# File 'lib/core/controlplane.rb', line 108 def fetch_gvc!(a_gvc = gvc) gvc_data = fetch_gvc(a_gvc) return gvc_data if gvc_data raise "Can't find app '#{gvc}', please create it with 'cpl setup-app -a #{config.app}'." end |
#fetch_gvcs ⇒ Object
gvc
91 92 93 |
# File 'lib/core/controlplane.rb', line 91 def fetch_gvcs api.gvc_list(org: org) end |
#fetch_identity(identity, a_gvc = gvc) ⇒ Object
identities
305 306 307 |
# File 'lib/core/controlplane.rb', line 305 def fetch_identity(identity, a_gvc = gvc) api.fetch_identity(org: org, gvc: a_gvc, identity: identity) end |
#fetch_policy(policy) ⇒ Object
policies
311 312 313 |
# File 'lib/core/controlplane.rb', line 311 def fetch_policy(policy) api.fetch_policy(org: org, policy: policy) end |
#fetch_volumesets(a_gvc = gvc) ⇒ Object
volumeset
242 243 244 |
# File 'lib/core/controlplane.rb', line 242 def fetch_volumesets(a_gvc = gvc) api.list_volumesets(org: org, gvc: a_gvc) end |
#fetch_workload(workload) ⇒ Object
129 130 131 |
# File 'lib/core/controlplane.rb', line 129 def fetch_workload(workload) api.workload_get(workload: workload, gvc: gvc, org: org) end |
#fetch_workload!(workload) ⇒ Object
133 134 135 136 137 138 |
# File 'lib/core/controlplane.rb', line 133 def fetch_workload!(workload) workload_data = fetch_workload(workload) return workload_data if workload_data raise "Can't find workload '#{workload}', please create it with 'cpl apply-template #{workload} -a #{config.app}'." end |
#fetch_workload_deployments(workload) ⇒ Object
163 164 165 |
# File 'lib/core/controlplane.rb', line 163 def fetch_workload_deployments(workload) api.workload_deployments(workload: workload, gvc: gvc, org: org) end |
#fetch_workloads(a_gvc = gvc) ⇒ Object
workload
121 122 123 |
# File 'lib/core/controlplane.rb', line 121 def fetch_workloads(a_gvc = gvc) api.workload_list(gvc: a_gvc, org: org) end |
#fetch_workloads_by_org(a_org = org) ⇒ Object
125 126 127 |
# File 'lib/core/controlplane.rb', line 125 def fetch_workloads_by_org(a_org = org) api.workload_list_by_org(org: a_org) end |
#find_domain_for(workloads) ⇒ Object
262 263 264 265 266 267 268 269 270 |
# File 'lib/core/controlplane.rb', line 262 def find_domain_for(workloads) domains = api.list_domains(org: org)["items"] domains.find do |domain_data| route = find_domain_route(domain_data) next false if route.nil? workloads.any? { |workload| route["workloadLink"].match?(%r{/org/#{org}/gvc/#{gvc}/workload/#{workload}}) } end end |
#find_domain_route(data) ⇒ Object
domain
252 253 254 255 256 257 258 259 260 |
# File 'lib/core/controlplane.rb', line 252 def find_domain_route(data) port = data["spec"]["ports"].find { |current_port| current_port["number"] == 80 || current_port["number"] == 443 } return nil if port.nil? || port["routes"].nil? route = port["routes"].find { |current_route| current_route["prefix"] == "/" } return nil if route.nil? route end |
#gvc_delete(a_gvc = gvc) ⇒ Object
115 116 117 |
# File 'lib/core/controlplane.rb', line 115 def gvc_delete(a_gvc = gvc) api.gvc_delete(gvc: a_gvc, org: org) end |
#gvc_query(app_name = config.app) ⇒ Object
95 96 97 98 99 100 101 102 |
# File 'lib/core/controlplane.rb', line 95 def gvc_query(app_name = config.app) # When `match_if_app_name_starts_with` is `true`, we query for any gvc containing the name, # otherwise we query for a gvc with the exact name. op = config.should_app_start_with?(app_name) ? "~" : "=" cmd = "cpln gvc query --org #{org} -o yaml --prop name#{op}#{app_name}" perform_yaml(cmd) end |
#image_build(image, dockerfile:, docker_args: [], build_args: [], push: true) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/core/controlplane.rb', line 47 def image_build(image, dockerfile:, docker_args: [], build_args: [], push: true) # https://docs.controlplane.com/guides/push-image#step-2 # Might need to use `docker buildx build` if compatiblitity issues arise cmd = "docker build --platform=linux/amd64 -t #{image} -f #{dockerfile}" cmd += " --progress=plain" if ControlplaneApiDirect.trace cmd += " #{docker_args.join(' ')}" if docker_args.any? build_args.each { |build_arg| cmd += " --build-arg #{build_arg}" } cmd += " #{config.app_dir}" perform!(cmd) image_push(image) if push end |
#image_delete(image) ⇒ Object
61 62 63 |
# File 'lib/core/controlplane.rb', line 61 def image_delete(image) api.image_delete(org: org, image: image) end |
#image_login(org_name = config.org) ⇒ Object
65 66 67 68 69 |
# File 'lib/core/controlplane.rb', line 65 def image_login(org_name = config.org) cmd = "cpln image docker-login --org #{org_name}" cmd += " > /dev/null 2>&1" if Shell.should_hide_output? perform!(cmd) end |
#image_pull(image) ⇒ Object
71 72 73 74 75 |
# File 'lib/core/controlplane.rb', line 71 def image_pull(image) cmd = "docker pull #{image}" cmd += " > /dev/null" if Shell.should_hide_output? perform!(cmd) end |
#image_push(image) ⇒ Object
83 84 85 86 87 |
# File 'lib/core/controlplane.rb', line 83 def image_push(image) cmd = "docker push #{image}" cmd += " > /dev/null" if Shell.should_hide_output? perform!(cmd) end |
#image_tag(old_tag, new_tag) ⇒ Object
77 78 79 80 81 |
# File 'lib/core/controlplane.rb', line 77 def image_tag(old_tag, new_tag) cmd = "docker tag #{old_tag} #{new_tag}" cmd += " > /dev/null" if Shell.should_hide_output? perform!(cmd) end |
#log_get(workload:, from:, to:) ⇒ Object
299 300 301 |
# File 'lib/core/controlplane.rb', line 299 def log_get(workload:, from:, to:) api.log_get(org: org, gvc: gvc, workload: workload, from: from, to: to) end |
#logs(workload:) ⇒ Object
logs
294 295 296 297 |
# File 'lib/core/controlplane.rb', line 294 def logs(workload:) cmd = "cpln logs '{workload=\"#{workload}\"}' --org #{org} -t -o raw --limit 200" perform!(cmd) end |
#parse_apply_result(result) ⇒ Object
rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 |
# File 'lib/core/controlplane.rb', line 347 def parse_apply_result(result) # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/PerceivedComplexity items = [] lines = result.split("\n") lines.each do |line| # The line can be in one of these formats: # - "Created /org/shakacode-open-source-examples/gvc/my-app-staging" # - "Created /org/shakacode-open-source-examples/gvc/my-app-staging/workload/redis" # - "Updated gvc 'tutorial-app-test-1'" # - "Updated workload 'redis'" if line.start_with?("Created") matches = line.match(%r{Created\s/org/[^/]+/gvc/([^/]+)($|(/([^/]+)/([^/]+)$))})&.captures next unless matches app, _, __, kind, name = matches if kind items.push({ kind: kind, name: name }) else items.push({ kind: "app", name: app }) end else matches = line.match(/Updated\s([^\s]+)\s'([^\s]+)'$/)&.captures next unless matches kind, name = matches kind = "app" if kind == "gvc" items.push({ kind: kind, name: name }) end end items end |
#profile_create(profile, token) ⇒ Object
25 26 27 28 29 30 |
# File 'lib/core/controlplane.rb', line 25 def profile_create(profile, token) sensitive_data_pattern = /(?<=--token )(\S+)/ cmd = "cpln profile create #{profile} --token #{token}" cmd += " > /dev/null" if Shell.should_hide_output? perform!(cmd, sensitive_data_pattern: sensitive_data_pattern) end |
#profile_delete(profile) ⇒ Object
32 33 34 35 36 |
# File 'lib/core/controlplane.rb', line 32 def profile_delete(profile) cmd = "cpln profile delete #{profile}" cmd += " > /dev/null" if Shell.should_hide_output? perform!(cmd) end |
#profile_exists?(profile) ⇒ Boolean
20 21 22 23 |
# File 'lib/core/controlplane.rb', line 20 def profile_exists?(profile) cmd = "cpln profile get #{profile} -o yaml" perform_yaml(cmd).length.positive? end |
#profile_switch(profile) ⇒ Object
profile
15 16 17 18 |
# File 'lib/core/controlplane.rb', line 15 def profile_switch(profile) ENV["CPLN_PROFILE"] = profile ControlplaneApiDirect.reset_api_token end |
#query_images(a_gvc = gvc, a_org = org, partial_gvc_match: nil) ⇒ Object
image
40 41 42 43 44 45 |
# File 'lib/core/controlplane.rb', line 40 def query_images(a_gvc = gvc, a_org = org, partial_gvc_match: nil) partial_gvc_match = config.should_app_start_with?(a_gvc) if partial_gvc_match.nil? gvc_op = partial_gvc_match ? "~" : "=" api.query_images(org: a_org, gvc: a_gvc, gvc_op_type: gvc_op) end |
#query_workloads(workload, a_gvc = gvc, a_org = org, partial_workload_match: false, partial_gvc_match: nil) ⇒ Object
140 141 142 143 144 145 146 |
# File 'lib/core/controlplane.rb', line 140 def query_workloads(workload, a_gvc = gvc, a_org = org, partial_workload_match: false, partial_gvc_match: nil) partial_gvc_match = config.should_app_start_with?(a_gvc) if partial_gvc_match.nil? gvc_op = partial_gvc_match ? "~" : "=" workload_op = partial_workload_match ? "~" : "=" api.query_workloads(org: a_org, gvc: a_gvc, workload: workload, gvc_op_type: gvc_op, workload_op_type: workload_op) end |
#set_domain_workload(data, workload) ⇒ Object
285 286 287 288 289 290 |
# File 'lib/core/controlplane.rb', line 285 def set_domain_workload(data, workload) route = find_domain_route(data) route["workloadLink"] = "/org/#{org}/gvc/#{gvc}/workload/#{workload}" api.update_domain(org: org, domain: data["name"], data: data) end |
#set_workload_env_var(workload, container:, name:, value:) ⇒ Object
194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/core/controlplane.rb', line 194 def set_workload_env_var(workload, container:, name:, value:) data = fetch_workload!(workload) data["spec"]["containers"].each do |container_data| next unless container_data["name"] == container container_data["env"].each do |env_data| next unless env_data["name"] == name env_data["value"] = value end end api.update_workload(org: org, gvc: gvc, workload: workload, data: data) end |
#set_workload_suspend(workload, value) ⇒ Object
209 210 211 212 213 214 |
# File 'lib/core/controlplane.rb', line 209 def set_workload_suspend(workload, value) data = fetch_workload!(workload) data["spec"]["defaultOptions"]["suspend"] = value api.update_workload(org: org, gvc: gvc, workload: workload, data: data) end |
#workload_connect(workload, location:, container: nil, shell: nil) ⇒ Object
226 227 228 229 230 231 |
# File 'lib/core/controlplane.rb', line 226 def workload_connect(workload, location:, container: nil, shell: nil) cmd = "cpln workload connect #{workload} #{gvc_org} --location #{location}" cmd += " --container #{container}" if container cmd += " --shell #{shell}" if shell perform!(cmd) end |
#workload_deployment_version_ready?(version, next_version, expected_status:) ⇒ Boolean
167 168 169 170 171 172 173 174 |
# File 'lib/core/controlplane.rb', line 167 def workload_deployment_version_ready?(version, next_version, expected_status:) return false unless version["workload"] == next_version version["containers"]&.all? do |_, container| ready = container.dig("resources", "replicas") == container.dig("resources", "replicasReady") expected_status == true ? ready : !ready end end |
#workload_deployments_ready?(workload, expected_status:) ⇒ Boolean
176 177 178 179 180 181 182 183 184 185 |
# File 'lib/core/controlplane.rb', line 176 def workload_deployments_ready?(workload, expected_status:) deployments = fetch_workload_deployments(workload)["items"] deployments.all? do |deployment| next_version = deployment.dig("status", "expectedDeploymentVersion") deployment.dig("status", "versions")&.all? do |version| workload_deployment_version_ready?(version, next_version, expected_status: expected_status) end end end |
#workload_exec(workload, location:, container: nil, command: nil) ⇒ Object
233 234 235 236 237 238 |
# File 'lib/core/controlplane.rb', line 233 def workload_exec(workload, location:, container: nil, command: nil) cmd = "cpln workload exec #{workload} #{gvc_org} --location #{location}" cmd += " --container #{container}" if container cmd += " -- #{command}" perform!(cmd) end |
#workload_force_redeployment(workload) ⇒ Object
216 217 218 219 220 |
# File 'lib/core/controlplane.rb', line 216 def workload_force_redeployment(workload) cmd = "cpln workload force-redeployment #{workload} #{gvc_org}" cmd += " > /dev/null" if Shell.should_hide_output? perform!(cmd) end |
#workload_get_replicas(workload, location:) ⇒ Object
148 149 150 151 |
# File 'lib/core/controlplane.rb', line 148 def workload_get_replicas(workload, location:) cmd = "cpln workload get-replicas #{workload} #{gvc_org} --location #{location} -o yaml" perform_yaml(cmd) end |
#workload_get_replicas_safely(workload, location:) ⇒ Object
153 154 155 156 157 158 159 160 161 |
# File 'lib/core/controlplane.rb', line 153 def workload_get_replicas_safely(workload, location:) cmd = "cpln workload get-replicas #{workload} #{gvc_org} --location #{location} -o yaml" cmd += " 2> /dev/null" if Shell.should_hide_output? Shell.debug("CMD", cmd) result = `#{cmd}` $CHILD_STATUS.success? ? YAML.safe_load(result) : nil end |
#workload_set_image_ref(workload, container:, image:) ⇒ Object
187 188 189 190 191 192 |
# File 'lib/core/controlplane.rb', line 187 def workload_set_image_ref(workload, container:, image:) cmd = "cpln workload update #{workload} #{gvc_org}" cmd += " --set spec.containers.#{container}.image=/org/#{config.org}/image/#{image}" cmd += " > /dev/null" if Shell.should_hide_output? perform!(cmd) end |