Skip to content
Snippets Groups Projects
Commit 1ccb573a authored by Gabriel Mazetto's avatar Gabriel Mazetto
Browse files

Added ability to disable a previously enabled consul service

This is done following the same pattern of an `enable` and `disable`
recipe. Unless a service is explicitly enabled, we consider it to be disabled.

Test coverage for existing consul recipe was split into the corresponding
spec files at the correct folder location.
parent 648d1ec7
No related branches found
No related tags found
No related merge requests found
Showing
with 261 additions and 127 deletions
---
title: Added ability to disable a previously enabled consul service
merge_request: 4502
author:
type: changed
class ConsulHelper
attr_reader :node, :default_configuration, :default_server_configuration
 
# List of existing services that we provide configuration for consul monitoring
#
# When adding a new service to consul, add to the constant below and make sure you
# provide an `enable_service_#{service_name}` and `disable_service_#{service_name}` recipe
SERVICES = %w(postgresql).freeze
def initialize(node)
@node = node
@default_configuration = {
Loading
Loading
@@ -68,4 +74,20 @@ class ConsulHelper
 
cfg
end
# Return a list of enabled services
#
# @return [Array] list of enabled services
def enabled_services
node['consul']['services']
end
# Return a list of disabled services
#
# The list is generated by intersecting the existing services with the list of enabled
#
# @return [Array] list of services that are disabled
def disabled_services
SERVICES - node['consul']['services']
end
end
#
# Copyright:: Copyright (c) 2020 GitLab Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
consul_helper = ConsulHelper.new(node)
consul_helper.enabled_services.each do |service|
include_recipe "consul::enable_service_#{service}"
end
consul_helper.disabled_services.each do |service|
include_recipe "consul::disable_service_#{service}"
end
#
# Copyright:: Copyright (c) 2020 GitLab Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
file "#{node['consul']['config_dir']}/postgresql_service.json" do
action :delete
notifies :run, 'execute[reload consul]', :delayed
end
Loading
Loading
@@ -61,9 +61,7 @@ file "#{node['consul']['dir']}/config.json" do
notifies :run, 'execute[reload consul]'
end
 
node['consul']['services'].each do |service|
include_recipe "consul::service_#{service}"
end
include_recipe 'consul::configure_services'
 
include_recipe 'consul::watchers'
 
Loading
Loading
require 'chef_helper'
RSpec.describe 'consul::configure_services' do
let(:chef_run) { ChefSpec::SoloRunner.new(step_into: %w(runit_service)).converge('gitlab-ee::default') }
before do
allow(Gitlab).to receive(:[]).and_call_original
end
describe 'enabling services' do
before do
stub_gitlab_rb(
consul: {
enable: true,
services: %w(postgresql)
}
)
end
it 'includes the enable_service recipe for the corresponding service' do
expect(chef_run).to include_recipe('consul::enable_service_postgresql')
end
end
describe 'disabling services' do
before do
stub_gitlab_rb(
consul: {
enable: true,
services: []
}
)
end
it 'includes the disable_service for all known services' do
expect(chef_run).to include_recipe('consul::disable_service_postgresql')
end
end
end
Loading
Loading
@@ -24,8 +24,7 @@ RSpec.describe 'consul' do
consul: {
enable: true,
config_dir: '/fake/config.d',
data_dir: '/fake/data',
services: %w(postgresql)
data_dir: '/fake/data'
}
)
end
Loading
Loading
@@ -41,8 +40,8 @@ RSpec.describe 'consul' do
expect(chef_run).to create_account('Consul user and group').with(username: 'gitlab-consul', groupname: 'gitlab-consul')
end
 
it 'includes the postgresql_service recipe' do
expect(chef_run).to include_recipe('consul::service_postgresql')
it 'includes the configure_services recipe' do
expect(chef_run).to include_recipe('consul::configure_services')
end
 
it 'only enables the agent by default' do
Loading
Loading
@@ -137,124 +136,4 @@ RSpec.describe 'consul' do
end
end
end
describe 'consul::service_postgresql' do
let(:chef_run) { ChefSpec::SoloRunner.new(step_into: %w(runit_service)).converge('gitlab-ee::default') }
before do
allow(Gitlab).to receive(:[]).and_call_original
end
context 'default' do
before do
stub_gitlab_rb(
consul: {
enable: true,
services: %w(postgresql)
}
)
end
it 'renders the service configuration file' do
rendered = {
'service' => {
'name' => 'postgresql',
'address' => '',
'port' => 5432,
'check' => {
'id' => 'service:postgresql',
'args' => ["/opt/gitlab/bin/gitlab-ctl", "repmgr-check-master"],
'interval' => '10s',
'status' => 'failing'
}
},
'watches' => [
{
'type' => 'keyprefix',
'prefix' => 'gitlab/ha/postgresql/failed_masters/',
'args' => ["/opt/gitlab/bin/gitlab-ctl", "consul", "watchers", "handle-failed-master"]
}
]
}
expect(chef_run).to render_file('/var/opt/gitlab/consul/config.d/postgresql_service.json').with_content { |content|
expect(JSON.parse(content)).to eq(rendered)
}
end
end
context 'when patroni is enabled' do
before do
stub_gitlab_rb(
patroni: {
enable: true
},
consul: {
enable: true,
services: %w(postgresql)
}
)
end
it 'renders the service configuration file' do
rendered = {
'service' => {
'name' => 'postgresql',
'address' => '',
'port' => 5432,
'check' => {
'id' => 'service:postgresql',
'args' => ['/opt/gitlab/bin/gitlab-ctl', 'patroni', 'check-leader'],
'interval' => '10s',
'status' => 'failing'
}
}
}
expect(chef_run).to render_file('/var/opt/gitlab/consul/config.d/postgresql_service.json').with_content { |content|
expect(JSON.parse(content)).to eq(rendered)
}
end
end
end
describe 'consul::watchers' do
let(:chef_run) { ChefSpec::SoloRunner.converge('gitlab-ee::default') }
let(:watcher_conf) { '/var/opt/gitlab/consul/config.d/watcher_postgresql.json' }
let(:watcher_check) { '/var/opt/gitlab/consul/scripts/failover_pgbouncer' }
before do
allow(Gitlab).to receive(:[]).and_call_original
stub_gitlab_rb(
consul: {
enable: true,
watchers: %w(
postgresql
)
}
)
end
it 'includes the watcher recipe' do
expect(chef_run).to include_recipe('consul::watchers')
end
it 'creates the watcher config file' do
rendered = {
'watches' => [
{
'type' => 'service',
'service' => 'postgresql',
'args' => [watcher_check]
}
]
}
expect(chef_run).to render_file(watcher_conf).with_content { |content|
expect(JSON.parse(content)).to eq(rendered)
}
end
it 'creates the watcher handler file' do
expect(chef_run).to render_file(watcher_check)
end
end
end
require 'chef_helper'
RSpec.describe 'consul::watchers' do
let(:chef_run) { ChefSpec::SoloRunner.converge('gitlab-ee::default') }
let(:watcher_conf) { '/var/opt/gitlab/consul/config.d/watcher_postgresql.json' }
let(:watcher_check) { '/var/opt/gitlab/consul/scripts/failover_pgbouncer' }
before do
allow(Gitlab).to receive(:[]).and_call_original
stub_gitlab_rb(
consul: {
enable: true,
watchers: %w(postgresql)
}
)
end
it 'includes the watcher recipe' do
expect(chef_run).to include_recipe('consul::watchers')
end
it 'creates the watcher config file' do
rendered = {
'watches' => [
{
'type' => 'service',
'service' => 'postgresql',
'args' => [watcher_check]
}
]
}
expect(chef_run).to render_file(watcher_conf).with_content { |content|
expect(JSON.parse(content)).to eq(rendered)
}
end
it 'creates the watcher handler file' do
expect(chef_run).to render_file(watcher_check)
end
end
require 'chef_helper'
RSpec.describe 'consul::disable_service_postgresql' do
let(:chef_run) { ChefSpec::SoloRunner.new(step_into: %w(runit_service)).converge('gitlab-ee::default', 'consul::disable_service_postgresql') }
before do
allow(Gitlab).to receive(:[]).and_call_original
end
context 'default' do
before do
stub_gitlab_rb(
consul: {
enable: true,
services: []
}
)
end
it 'deletes the service configuration file' do
expect(chef_run).to delete_file('/var/opt/gitlab/consul/config.d/postgresql_service.json')
end
end
end
require 'chef_helper'
RSpec.describe 'consul::enable_service_postgresql' do
let(:chef_run) { ChefSpec::SoloRunner.new(step_into: %w(runit_service)).converge('gitlab-ee::default') }
before do
allow(Gitlab).to receive(:[]).and_call_original
end
context 'default' do
before do
stub_gitlab_rb(
consul: {
enable: true,
services: %w(postgresql)
}
)
end
it 'renders the service configuration file' do
rendered = {
'service' => {
'name' => 'postgresql',
'address' => '',
'port' => 5432,
'check' => {
'id' => 'service:postgresql',
'args' => ["/opt/gitlab/bin/gitlab-ctl", "repmgr-check-master"],
'interval' => '10s',
'status' => 'failing'
}
},
'watches' => [
{
'type' => 'keyprefix',
'prefix' => 'gitlab/ha/postgresql/failed_masters/',
'args' => ["/opt/gitlab/bin/gitlab-ctl", "consul", "watchers", "handle-failed-master"]
}
]
}
expect(chef_run).to render_file('/var/opt/gitlab/consul/config.d/postgresql_service.json').with_content { |content|
expect(JSON.parse(content)).to eq(rendered)
}
end
end
context 'when patroni is enabled' do
before do
stub_gitlab_rb(
patroni: {
enable: true
},
consul: {
enable: true,
services: %w(postgresql)
}
)
end
it 'renders the service configuration file' do
rendered = {
'service' => {
'name' => 'postgresql',
'address' => '',
'port' => 5432,
'check' => {
'id' => 'service:postgresql',
'args' => ['/opt/gitlab/bin/gitlab-ctl', 'patroni', 'check-leader'],
'interval' => '10s',
'status' => 'failing'
}
}
}
expect(chef_run).to render_file('/var/opt/gitlab/consul/config.d/postgresql_service.json').with_content { |content|
expect(JSON.parse(content)).to eq(rendered)
}
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment