Skip to content

Commit

Permalink
Add cb config-param support.
Browse files Browse the repository at this point in the history
Add basic support for managing supported cluster configuration
parameters.

This command provides the following sub-commands:

```
❯ cb config-param --help
Usage:
    cb config-param <command>

Commands:
    get                              display one or all configuration parameters for a cluster
    list-supported                   display supported configuration parameters
    reset                            reset one or more configuration parameter values to default
    set                              set one or more configuration parameter values

Options:
    -h, --help                       Show this help
```
  • Loading branch information
abrightwell committed Jul 18, 2023
1 parent 4a09f3a commit 0074916
Show file tree
Hide file tree
Showing 15 changed files with 742 additions and 4 deletions.
8 changes: 5 additions & 3 deletions .ameba.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# This configuration file was generated by `ameba --gen-config`
# on 2023-04-27 15:07:08 UTC using Ameba version 1.4.2.
# on 2023-07-17 18:42:36 UTC using Ameba version 1.4.3.
# The point is for the user to remove these configuration records
# one by one as the reported problems are removed from the code base.

# Problems found: 14
# Problems found: 23
# Run `ameba --only Layout/TrailingWhitespace` for details
Layout/TrailingWhitespace:
Description: Disallows trailing whitespace
Expand All @@ -13,10 +13,11 @@ Layout/TrailingWhitespace:
- spec/cb/role_spec.cr
- spec/cb/cluster_list_spec.cr
- spec/cb/team_spec.cr
- spec/cb/config_param_spec.cr
Enabled: true
Severity: Convention

# Problems found: 10
# Problems found: 11
# Run `ameba --only Style/QueryBoolMethods` for details
Style/QueryBoolMethods:
Description: Reports boolean properties without the `?` suffix
Expand All @@ -26,6 +27,7 @@ Style/QueryBoolMethods:
- src/cb/cluster_list.cr
- src/cb/cluster_upgrade.cr
- src/cb/detach.cr
- src/cb/config_param.cr
- src/cb/cluster_destroy.cr
- src/cb/network.cr
- src/cb/program.cr
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Added
- `cb config-param` command to manage supported cluster configuration
parameters. Supports `get`, `list-supported`, `reset` and `set`.

## [3.3.3] - 2023-05-18
### Added
Expand Down
62 changes: 62 additions & 0 deletions spec/cb/completion_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,68 @@ Spectator.describe CB::Completion do
expect(result).to_not have_option "-v"
end

it "config-param" do
result = parse("cb config-param ")
expect(result).to have_option "get"
expect(result).to have_option "list-supported"
expect(result).to have_option "set"
expect(result).to have_option "reset"

# cb config-param get
result = parse("cb config-param get ")
expect(result).to have_option "--cluster"
expect(result).to have_option "--format"

result = parse("cb config-param get --cluster ")
expect(result).to eq expected_cluster_suggestion

result = parse("cb config-param get --cluster abc ")
expect(result).to have_option "--format"

result = parse("cb config-param get --format ")
expect(result).to eq ["json", "table"]

# cb config-param list-supported
result = parse("cb config-param list-supported ")
expect(result).to have_option "--format"

result = parse("cb config-param list-supported --format ")
expect(result).to eq ["json", "table"]

# cb config-param reset
result = parse("cb config-param reset ")
expect(result).to have_option "--allow-restart"
expect(result).to have_option "--cluster"
expect(result).to have_option "--format"

result = parse("cb config-param reset --cluster ")
expect(result).to eq expected_cluster_suggestion

result = parse("cb config-param reset --cluster abc ")
expect(result).to have_option "--format"

result = parse("cb config-param reset --allow-restart ")
expect(result).to eq ["false", "true"]

result = parse("cb config-param reset --format ")
expect(result).to eq ["json", "table"]

# cb config-param set
result = parse("cb config-param set ")
expect(result).to have_option "--allow-restart"
expect(result).to have_option "--cluster"
expect(result).to have_option "--format"

result = parse("cb config-param set --cluster ")
expect(result).to eq expected_cluster_suggestion

result = parse("cb config-param set --cluster abc ")
expect(result).to have_option "--allow-restart"

result = parse("cb config-param set --allow-restart ")
expect(result).to eq ["false", "true"]
end

it "destroy" do
result = parse("cb destroy ")
expect(result).to eq expected_cluster_suggestion
Expand Down
254 changes: 254 additions & 0 deletions spec/cb/config_param_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
require "../spec_helper"

Spectator.describe ConfigurationParameterGet do
subject(action) { described_class.new client: client, output: IO::Memory.new }

let(client) { Client.new TEST_TOKEN }
let(cluster) { Factory.cluster }

mock_client

describe "#validate" do
it "validates that required arguments are present" do
expect(&.validate).to raise_error Program::Error, /Missing required argument/

action.cluster_id = cluster.id

expect(&.validate).to be_true
end
end

describe "#call" do
before_each {
action.cluster_id = cluster.id
}

it "gets by name" do
action.args = ["postgres:max_connections"]

expect(client).to receive(:get_configuration_parameter).and_return(Factory.configuration_parameter)

action.call

expected = <<-EXPECTED
Component Name Value
postgres max_connections 100 \n
EXPECTED

expect(&.output.to_s).to eq expected
end

it "lists no parameters when none are set" do
expect(client).to receive(:list_configuration_parameters).and_return([] of CB::Model::ConfigurationParameter)

action.call

expected = <<-EXPECTED
Component Name Value \n
EXPECTED

expect(&.output.to_s).to eq expected
end

it "outputs default format" do
expect(client).to receive(:list_configuration_parameters).and_return([Factory.configuration_parameter, Factory.configuration_parameter])

action.call

expected = <<-EXPECTED
Component Name Value
postgres max_connections 100
postgres max_connections 100 \n
EXPECTED

expect(&.output.to_s).to eq expected
end

it "outputs json format" do
action.format = Format::JSON

expect(client).to receive(:list_configuration_parameters).and_return([Factory.configuration_parameter])

action.call

expected = <<-EXPECTED
{
"parameters": [
{
"component": "postgres",
"name": "postgres:max_connections",
"parameter_name": "max_connections",
"requires_restart": false,
"value": "100"
}
]
}\n
EXPECTED

expect(&.output.to_s).to eq expected
end
end
end

Spectator.describe ConfigurationParameterListSupported do
subject(action) { described_class.new client: client, output: IO::Memory.new }

let(client) { Client.new TEST_TOKEN }
let(cluster) { Factory.cluster }

mock_client

describe "#call" do
before_each {
expect(client).to receive(:list_supported_configuration_parameters).and_return [
Factory.configuration_parameter(value: nil),
Factory.configuration_parameter(
component: "pgbouncer",
name: "pgbouncer:default_pool_size",
parameter_name: "default_pool_size",
value: nil
),
]
}

it "outputs all" do
action.call

expected = <<-EXPECTED
Component Name Requires Restart
postgres max_connections no
pgbouncer default_pool_size no \n
EXPECTED

expect(&.output.to_s).to eq expected
end

it "outputs specific component" do
action.args = ["postgres"]
action.call

expected = <<-EXPECTED
Component Name Requires Restart
postgres max_connections no \n
EXPECTED

expect(&.output.to_s).to eq expected
end
end
end

Spectator.describe ConfigurationParameterSet do
subject(action) { described_class.new client: client, output: IO::Memory.new }

let(client) { Client.new TEST_TOKEN }
let(cluster) { Factory.cluster }

mock_client

describe "#call" do
before_each {
action.args = ["postgres:max_connections=100"]
action.cluster_id = cluster.id
}

it "outputs default" do
expect(client).to receive(:update_configuration_parameters).and_return [Factory.configuration_parameter]

action.call

expected = <<-EXPECTED
Component Name Value
postgres max_connections 100 \n
EXPECTED

expect(&.output.to_s).to eq expected
end

it "outputs json format" do
action.format = Format::JSON

expect(client).to receive(:update_configuration_parameters).and_return([Factory.configuration_parameter])

action.call

expected = <<-EXPECTED
{
"parameters": [
{
"component": "postgres",
"name": "postgres:max_connections",
"parameter_name": "max_connections",
"requires_restart": false,
"value": "100"
}
]
}\n
EXPECTED

expect(&.output.to_s).to eq expected
end
end
end

Spectator.describe ConfigurationParameterReset do
subject(action) { described_class.new client: client, output: IO::Memory.new }

let(client) { Client.new TEST_TOKEN }
let(cluster) { Factory.cluster }

mock_client

describe "#call" do
before_each {
action.cluster_id = cluster.id

expect(client).to receive(:update_configuration_parameters).and_return [Factory.configuration_parameter]
}

it "resets parameters" do
action.args = ["postgres:max_connections"]

action.call

expected = <<-EXPECTED
Component Name Value
postgres max_connections 100 \n
EXPECTED

expect(&.output.to_s).to eq expected
end

it "outputs default" do
action.call

expected = <<-EXPECTED
Component Name Value
postgres max_connections 100 \n
EXPECTED

expect(&.output.to_s).to eq expected
end

it "outputs json format" do
action.format = Format::JSON

action.call

expected = <<-EXPECTED
{
"parameters": [
{
"component": "postgres",
"name": "postgres:max_connections",
"parameter_name": "max_connections",
"requires_restart": false,
"value": "100"
}
]
}\n
EXPECTED

expect(&.output.to_s).to eq expected
end
end
end
6 changes: 6 additions & 0 deletions spec/cb/login_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Spectator.describe CB::Login do
let(client) { mock(Client) }

before_each {
ENV["CB_API_KEY"] = nil
action.client = client
action.open_browser = ->(_url : String) { true }
action.store_credentials = ->(_account : String, _secret : String) { true }
Expand All @@ -43,5 +44,10 @@ Spectator.describe CB::Login do
result = action.call
expect(result).to_not be_empty
end

it "raises error if CB_API_KEY is set" do
ENV["CB_API_KEY"] = "cbkey_secret"
expect(&.call).to raise_error(CB::Program::Error)
end
end
end
Loading

0 comments on commit 0074916

Please sign in to comment.