File: revoke_spec.rb

package info (click to toggle)
ruby-puppetserver-ca-cli 2.7.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 696 kB
  • sloc: ruby: 6,970; sh: 4; makefile: 3
file content (119 lines) | stat: -rw-r--r-- 4,679 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
require 'spec_helper'
require 'utils/http'
require 'utils/helpers'

require 'puppetserver/ca/action/revoke'
require 'puppetserver/ca/logger'
require 'puppetserver/ca/utils/http_client'

RSpec.describe Puppetserver::Ca::Action::Revoke do
  let(:stdout) { StringIO.new }
  let(:stderr) { StringIO.new }
  let(:logger) { Puppetserver::Ca::Logger.new(:info, stdout, stderr) }

  subject { Puppetserver::Ca::Action::Revoke.new(logger) }

  describe 'flags' do
    it 'takes a single certname' do
      result, maybe_code = subject.parse(['--certname', 'foo.example.com'])
      expect(maybe_code).to eq(nil)
      expect(result['certnames']).to eq(['foo.example.com'])
    end

    it 'takes a comma separated list of certnames' do
      result, maybe_code = subject.parse(['--certname', 'foo,bar'])
      expect(maybe_code).to eq(nil)
      expect(result['certnames']).to eq(['foo', 'bar'])
    end

    it 'takes a custom puppet.conf location' do
      result, maybe_code = subject.parse(['--certname', 'foo',
                                          '--config', '/dev/tcp/example.com'])
      expect(maybe_code).to be(nil)
      expect(result['config']).to eq('/dev/tcp/example.com')
    end
  end

  describe 'validation' do
    it 'requires at least one certname' do
      result, code = subject.parse([])
      expect(code).to eq(1)
      expect(stderr.string).to include('one certname is required')
    end

    it 'cannot revoke certs with the names of flags' do
      result, code = subject.parse(['--certname', '--config'])
      expect(code).to eq(1)
      expect(stderr.string).to include('Cannot manage cert named `--config`')
      expect(result['certnames']).to eq(['--config'])
    end
  end

  describe 'revocation' do
    let(:success) { Utils::Http::Result.new('204', '') }
    let(:connection) { double }

    before do
      allow_any_instance_of(Puppetserver::Ca::Utils::HttpClient).
        to receive(:with_connection).and_yield(connection)
      allow_any_instance_of(Puppetserver::Ca::Utils::HttpClient).
        to receive(:make_store)
      allow_any_instance_of(Puppetserver::Ca::Utils::HttpClient).
        to receive(:load_cert)
      allow_any_instance_of(Puppetserver::Ca::Utils::HttpClient).
        to receive(:load_key)
    end

    it 'logs success and returns zero if revoked' do
      allow(connection).to receive(:put).and_return(success)

      code = subject.run({'certnames' => ['foo']})
      expect(code).to eq(0)
      expect(stdout.string.chomp).to eq('Certificate for foo has been revoked')
      expect(Utils::Helpers.remove_cadir_deprecation(stderr)).to be_empty
    end

    it 'logs an error and returns 1 if any could not be revoked' do
      not_found = Utils::Http::Result.new('404', 'Not Found')
      allow(connection).to receive(:put).and_return(not_found, success)

      code = subject.run({'certnames' => ['foo', 'bar']})
      expect(code).to eq(1)
      expect(stdout.string.chomp).to eq('Certificate for bar has been revoked')
      expect(stderr.string).to match(/Error.*not find certificate for foo/m)
    end

    it 'logs an error and returns 24 if any were certificate requests rather than certs' do
      unsigned = Utils::Http::Result.new('409', 'Conflict')
      allow(connection).to receive(:put).and_return(unsigned, success)

      code = subject.run({'certnames' => ['foo', 'bar']})
      expect(code).to eq(24)
      expect(stdout.string.chomp).to eq('Certificate for bar has been revoked')
      expect(stderr.string).to match(/Error.*not revoke unsigned csr for foo/m)
    end

    it 'returns 1 if any erred, regardless of if some were unsigned' do
      unsigned = Utils::Http::Result.new('409', 'Conflict')
      not_found = Utils::Http::Result.new('404', 'Not Found')
      allow(connection).to receive(:put).and_return(not_found, success, unsigned)

      code = subject.run({'certnames' => ['foo', 'bar', 'baz']})
      expect(code).to eq(1)
      expect(stdout.string.chomp).to eq('Certificate for bar has been revoked')
      expect(stderr.string).to match(/Error.*not revoke unsigned csr for baz/m)
      expect(stderr.string).to match(/Error.*not find certificate for foo/m)
    end

    it 'prints an error and returns 1 if an unknown error occurs' do
      error = Utils::Http::Result.new('500', 'Internal Server Error')
      allow(connection).to receive(:put).and_return(error, success)

      code = subject.run({'certnames' => ['foo', 'bar']})
      expect(code).to eq(1)
      expect(stdout.string.chomp).to eq('Certificate for bar has been revoked')
      expect(stderr.string).
        to match(/Error.*attempting to revoke.*code: 500.*body: Internal Server Error/m)
    end
  end
end