Skip to content

Commit 66d3495

Browse files
committed
implement generate_config
1 parent 52746ff commit 66d3495

4 files changed

Lines changed: 155 additions & 1 deletion

File tree

lib/cronitor.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,17 @@ def self.validate_config
4949
apply_config(rollback: true)
5050
end
5151

52+
def self.generate_config(path = nil)
53+
config_path = path || Cronitor.config || './cronitor.yaml'
54+
yaml_content = Monitor.as_yaml
55+
56+
File.open(config_path, 'w') do |file|
57+
file.write(yaml_content)
58+
end
59+
60+
puts("Configuration saved to #{config_path}")
61+
end
62+
5263
def self.job(key, &block)
5364
monitor = Monitor.new(key)
5465
series = Time.now.to_f

lib/cronitor/monitor.rb

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,35 @@ def self.put(opts = {})
7777
end
7878
end
7979

80+
def self.as_yaml(api_key: nil, api_version: nil)
81+
timeout = Cronitor.timeout || 10
82+
api_key = api_key || Cronitor.api_key
83+
84+
unless api_key
85+
raise Error.new('No API key detected. Set Cronitor.api_key or pass api_key parameter')
86+
end
87+
88+
headers = Cronitor::Monitor::Headers::YAML.dup
89+
headers[:'Cronitor-Version'] = api_version if api_version
90+
91+
resp = HTTParty.get(
92+
"#{MONITOR_API_URL}.yaml",
93+
basic_auth: {
94+
username: api_key,
95+
password: ''
96+
},
97+
headers: headers,
98+
timeout: timeout
99+
)
100+
101+
case resp.code
102+
when 200
103+
resp.body
104+
else
105+
raise Error.new("Unexpected error #{resp.code}: #{resp.body}")
106+
end
107+
end
108+
80109
def delete
81110
resp = HTTParty.delete(
82111
"#{monitor_api_url}/#{key}",

lib/cronitor/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# frozen_string_literal: true
22

33
module Cronitor
4-
VERSION = '5.2.2'
4+
VERSION = '5.3.0'
55
end

spec/cronitor_spec.rb

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,57 @@
102102
Cronitor.validate_config()
103103
end
104104
end
105+
106+
context '#generate_config' do
107+
let(:yaml_content) { "jobs:\n test-job:\n schedule: '* * * * *'\n" }
108+
let(:temp_config_path) { './spec/temp_cronitor.yaml' }
109+
let(:default_config_path) { './cronitor.yaml' }
110+
111+
after(:each) do
112+
File.delete(temp_config_path) if File.exist?(temp_config_path)
113+
File.delete(default_config_path) if File.exist?(default_config_path)
114+
Cronitor.config = nil # Reset config to avoid test interference
115+
end
116+
117+
context 'when no config path is set' do
118+
it 'uses default path ./cronitor.yaml' do
119+
Cronitor.config = nil
120+
expect(Cronitor::Monitor).to receive(:as_yaml).and_return(yaml_content)
121+
expect(File).to receive(:open).with('./cronitor.yaml', 'w').and_call_original
122+
123+
# Mock the file write to avoid creating actual file
124+
allow(File).to receive(:open).with('./cronitor.yaml', 'w').and_yield(StringIO.new)
125+
126+
result = Cronitor.generate_config
127+
expect(result).to be_nil
128+
end
129+
end
130+
131+
context 'when config path is provided' do
132+
it 'uses the provided path' do
133+
expect(Cronitor::Monitor).to receive(:as_yaml).and_return(yaml_content)
134+
135+
result = Cronitor.generate_config(temp_config_path)
136+
137+
expect(result).to be_nil
138+
expect(File.exist?(temp_config_path)).to be(true)
139+
expect(File.read(temp_config_path)).to eq(yaml_content)
140+
end
141+
end
142+
143+
context 'when Cronitor.config is set' do
144+
it 'uses Cronitor.config path' do
145+
Cronitor.config = temp_config_path
146+
expect(Cronitor::Monitor).to receive(:as_yaml).and_return(yaml_content)
147+
148+
result = Cronitor.generate_config
149+
150+
expect(result).to be_nil
151+
expect(File.exist?(temp_config_path)).to be(true)
152+
expect(File.read(temp_config_path)).to eq(yaml_content)
153+
end
154+
end
155+
end
105156
end
106157

107158
describe '#job' do
@@ -243,6 +294,69 @@
243294
end
244295
end
245296

297+
context '#as_yaml' do
298+
let(:yaml_response) { "jobs:\n test-job:\n schedule: '* * * * *'\n" }
299+
300+
it 'should fetch YAML configuration from API' do
301+
expect(HTTParty).to receive(:get).with(
302+
'https://cronitor.io/api/monitors.yaml',
303+
hash_including(
304+
basic_auth: { username: FAKE_API_KEY, password: '' },
305+
headers: hash_including('Content-Type': 'application/yaml'),
306+
timeout: 10
307+
)
308+
).and_return(instance_double(HTTParty::Response, code: 200, body: yaml_response))
309+
310+
result = Cronitor::Monitor.as_yaml
311+
expect(result).to eq(yaml_response)
312+
end
313+
314+
it 'should use custom API key when provided' do
315+
custom_api_key = 'custom_key'
316+
expect(HTTParty).to receive(:get).with(
317+
'https://cronitor.io/api/monitors.yaml',
318+
hash_including(
319+
basic_auth: { username: custom_api_key, password: '' }
320+
)
321+
).and_return(instance_double(HTTParty::Response, code: 200, body: yaml_response))
322+
323+
Cronitor::Monitor.as_yaml(api_key: custom_api_key)
324+
end
325+
326+
it 'should use custom API version when provided' do
327+
api_version = '2023-01-01'
328+
expect(HTTParty).to receive(:get).with(
329+
'https://cronitor.io/api/monitors.yaml',
330+
hash_including(
331+
headers: hash_including(:'Cronitor-Version' => api_version)
332+
)
333+
).and_return(instance_double(HTTParty::Response, code: 200, body: yaml_response))
334+
335+
Cronitor::Monitor.as_yaml(api_version: api_version)
336+
end
337+
338+
context 'when no API key is available' do
339+
it 'raises an error' do
340+
original_api_key = Cronitor.api_key
341+
Cronitor.api_key = nil
342+
343+
expect { Cronitor::Monitor.as_yaml }.to raise_error(Cronitor::Error, /No API key detected/)
344+
345+
Cronitor.api_key = original_api_key
346+
end
347+
end
348+
349+
context 'when API returns an error' do
350+
it 'raises an error with the response details' do
351+
expect(HTTParty).to receive(:get).and_return(
352+
instance_double(HTTParty::Response, code: 400, body: 'Bad Request')
353+
)
354+
355+
expect { Cronitor::Monitor.as_yaml }.to raise_error(Cronitor::Error, /Unexpected error 400: Bad Request/)
356+
end
357+
end
358+
end
359+
246360
context '#data' do
247361
it 'should fetch the monitor with cronitor api key' do
248362
expect(HTTParty).to receive(:get).with("https://cronitor.io/api/monitors", hash_including(basic_auth: {username: Cronitor.api_key, password: ''})).and_return(

0 commit comments

Comments
 (0)