Merge pull request #107 from hurricanehrndz/develop

Big PR that introduces `gawk`, `kitchen`, and other cool stuff
pull/119/merge
Nikita Sobolev 7 years ago committed by GitHub
commit d3a5f38356

@ -0,0 +1,66 @@
FROM debian:stable
ENV DEBIAN_FRONTEND="noninteractive" container="docker"
RUN apt-get update \
&& apt-get upgrade -y \
&& apt-get install -y \
apt-utils \
curl \
locales \
lsb-release \
net-tools \
openssh-server \
python-pip \
python2.7 \
sudo \
systemd \
&& pip install --upgrade pip \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
&& if ! getent passwd <%= @username %>; then \
useradd -d /home/<%= @username %> -m -s /bin/bash -p '*' <%= @username %>; \
fi \
&& echo "<%= @username %> ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers \
&& echo "Defaults !requiretty" >> /etc/sudoers \
&& mkdir -p /home/<%= @username %>/.ssh \
&& chown -R <%= @username %> /home/<%= @username %>/.ssh \
&& chmod 0700 /home/<%= @username %>/.ssh \
&& echo '<%= IO.read(@public_key).strip %>' >> /home/<%= @username %>/.ssh/authorized_keys \
&& chown <%= @username %> /home/<%= @username %>/.ssh/authorized_keys \
&& chmod 0600 /home/<%= @username %>/.ssh/authorized_keys \
&& echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && locale-gen \
&& cd /lib/systemd/system/sysinit.target.wants/; ls | grep -v systemd-tmpfiles-setup | /usr/bin/xargs rm -f $1 \
&& /bin/rm -f /lib/systemd/system/multi-user.target.wants/* \
&& /bin/rm -f /etc/systemd/system/*.wants/* \
&& /bin/rm -f /lib/systemd/system/local-fs.target.wants/* \
&& /bin/rm -f /lib/systemd/system/sockets.target.wants/*udev* \
&& /bin/rm -f /lib/systemd/system/sockets.target.wants/*initctl* \
&& /bin/rm -f /lib/systemd/system/basic.target.wants/* \
&& /bin/rm -f /lib/systemd/system/anaconda.target.wants/* \
&& /bin/rm -f /lib/systemd/system/plymouth* \
&& /bin/rm -f /lib/systemd/system/systemd-update-utmp* \
&& sed -ri 's/^#?UsePAM\s+.*/UsePAM no/' /etc/ssh/sshd_config \
&& sed -ri 's/^#?PubkeyAuthentication\s+.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config \
&& sed -ri 's/^#?UsePrivilegeSeparation\s+.*/UsePrivilegeSeparation no/' /etc/ssh/sshd_config \
&& echo "UseDNS=no" >> /etc/ssh/sshd_config \
&& systemctl set-default multi-user.target \
&& ln -s /lib/systemd/system/sshd.service /etc/systemd/system/multi-user.target.wants/sshd.service \
&& ln -s /lib/systemd/system/systemd-journald.service /etc/systemd/system/multi-user.target.wants/systemd-journald.service \
&& echo $'[Unit]\
\nDescription=Finish boot up\
\nAfter=ssh.service\
\n\
\n[Service]\
\nType=oneshot\
\nRemainAfterExit=yes\
\nExecStartPre=/bin/sleep 3s\
\nExecStart=/bin/rm -f /run/nologin\
\n\
\n[Install]\
\nWantedBy=default.target' >> /etc/systemd/system/FinishBootUp.service \
&& ln -s /etc/systemd/system/FinishBootUp.service /etc/systemd/system/multi-user.target.wants/FinishBootUp.service
EXPOSE 22
VOLUME [ "/sys/fs/cgroup" ]

@ -0,0 +1,69 @@
FROM fedora:latest
ENV container="docker"
RUN dnf clean all \
&& dnf makecache \
&& dnf install -y \
curl \
findutils \
gcc \
glibc-langpack-en.x86_64 \
libffi-devel \
net-tools \
openssh-server \
openssl-devel \
python2-devel \
python2-pip \
redhat-lsb \
redhat-rpm-config \
sudo \
systemd \
&& pip install --upgrade pip \
&& dnf clean all \
&& if ! getent passwd <%= @username %>; then \
useradd -d /home/<%= @username %> -m -s /usr/bin/bash -p '*' <%= @username %>; \
fi \
&& echo "<%= @username %> ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers \
&& echo "Defaults !requiretty" >> /etc/sudoers \
&& mkdir -p /home/<%= @username %>/.ssh \
&& chown -R <%= @username %> /home/<%= @username %>/.ssh \
&& chmod 0700 /home/<%= @username %>/.ssh \
&& echo '<%= IO.read(@public_key).strip %>' >> /home/<%= @username %>/.ssh/authorized_keys \
&& chown <%= @username %> /home/<%= @username %>/.ssh/authorized_keys \
&& chmod 0600 /home/<%= @username %>/.ssh/authorized_keys \
&& export LANG="en_US.UTF-8" && echo "LANG=\"en_US.UTF-8\"" > /etc/locale.conf \
&& cd /lib/systemd/system/sysinit.target.wants/; ls | grep -v systemd-tmpfiles-setup | /usr/bin/xargs rm -f $1 \
&& /usr/bin/rm -f /lib/systemd/system/multi-user.target.wants/* \
&& /usr/bin/rm -f /etc/systemd/system/*.wants/* \
&& /usr/bin/rm -f /lib/systemd/system/local-fs.target.wants/* \
&& /usr/bin/rm -f /lib/systemd/system/sockets.target.wants/*udev* \
&& /usr/bin/rm -f /lib/systemd/system/sockets.target.wants/*initctl* \
&& /usr/bin/rm -f /lib/systemd/system/basic.target.wants/* \
&& /usr/bin/rm -f /lib/systemd/system/anaconda.target.wants/* \
&& /usr/bin/rm -f /lib/systemd/system/plymouth* \
&& /usr/bin/rm -f /lib/systemd/system/systemd-update-utmp* \
&& sed -ri 's/^#?PubkeyAuthentication\s+.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config \
&& sed -ri 's/^#?UsePrivilegeSeparation\s+.*/UsePrivilegeSeparation no/' /etc/ssh/sshd_config \
&& echo "UseDNS=no" >> /etc/ssh/sshd_config \
&& systemctl set-default multi-user.target \
&& ln -s /lib/systemd/system/sshd.service /etc/systemd/system/multi-user.target.wants/sshd.service \
&& ln -s /lib/systemd/system/systemd-journald.service /etc/systemd/system/multi-user.target.wants/systemd-journald.service \
&& echo $'[Unit]\
\nDescription=Finish boot up\
\nAfter=ssh.service\
\n\
\n[Service]\
\nType=oneshot\
\nRemainAfterExit=yes\
\nExecStartPre=/bin/sleep 3s\
\nExecStart=/bin/rm -f /run/nologin\
\n\
\n[Install]\
\nWantedBy=default.target' >> /etc/systemd/system/FinishBootUp.service \
&& ln -s /etc/systemd/system/FinishBootUp.service /etc/systemd/system/multi-user.target.wants/FinishBootUp.service
EXPOSE 22
VOLUME [ "/sys/fs/cgroup" ]

@ -0,0 +1,66 @@
FROM ubuntu:latest
ENV DEBIAN_FRONTEND="noninteractive" container="docker"
RUN apt-get update \
&& apt-get upgrade -y \
&& apt-get install -y \
apt-utils \
curl \
locales \
lsb-release \
net-tools \
openssh-server \
python-pip \
python2.7 \
sudo \
systemd \
&& pip install --upgrade pip \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
&& if ! getent passwd <%= @username %>; then \
useradd -d /home/<%= @username %> -m -s /bin/bash -p '*' <%= @username %>; \
fi \
&& echo "<%= @username %> ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers \
&& echo "Defaults !requiretty" >> /etc/sudoers \
&& mkdir -p /home/<%= @username %>/.ssh \
&& chown -R <%= @username %> /home/<%= @username %>/.ssh \
&& chmod 0700 /home/<%= @username %>/.ssh \
&& echo '<%= IO.read(@public_key).strip %>' >> /home/<%= @username %>/.ssh/authorized_keys \
&& chown <%= @username %> /home/<%= @username %>/.ssh/authorized_keys \
&& chmod 0600 /home/<%= @username %>/.ssh/authorized_keys \
&& echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && /usr/sbin/locale-gen \
&& cd /lib/systemd/system/sysinit.target.wants/; ls | grep -v systemd-tmpfiles-setup | xargs rm -f $1 \
&& /bin/rm -f /lib/systemd/system/multi-user.target.wants/* \
&& /bin/rm -f /etc/systemd/system/*.wants/* \
&& /bin/rm -f /lib/systemd/system/local-fs.target.wants/* \
&& /bin/rm -f /lib/systemd/system/sockets.target.wants/*udev* \
&& /bin/rm -f /lib/systemd/system/sockets.target.wants/*initctl* \
&& /bin/rm -f /lib/systemd/system/basic.target.wants/* \
&& /bin/rm -f /lib/systemd/system/anaconda.target.wants/* \
&& /bin/rm -f /lib/systemd/system/plymouth* \
&& /bin/rm -f /lib/systemd/system/systemd-update-utmp* \
&& sed -ri 's/^#?UsePAM\s+.*/UsePAM no/' /etc/ssh/sshd_config \
&& sed -ri 's/^#?PubkeyAuthentication\s+.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config \
&& sed -ri 's/^#?UsePrivilegeSeparation\s+.*/UsePrivilegeSeparation no/' /etc/ssh/sshd_config \
&& echo "UseDNS=no" >> /etc/ssh/sshd_config \
&& systemctl set-default multi-user.target \
&& ln -s /lib/systemd/system/sshd.service /etc/systemd/system/multi-user.target.wants/sshd.service \
&& ln -s /lib/systemd/system/systemd-journald.service /etc/systemd/system/multi-user.target.wants/systemd-journald.service \
&& echo $'[Unit]\
\nDescription=Finish boot up\
\nAfter=ssh.service\
\n\
\n[Service]\
\nType=oneshot\
\nRemainAfterExit=yes\
\nExecStartPre=/bin/sleep 3s\
\nExecStart=/bin/rm -f /run/nologin\
\n\
\n[Install]\
\nWantedBy=default.target' >> /etc/systemd/system/FinishBootUp.service \
&& ln -s /etc/systemd/system/FinishBootUp.service /etc/systemd/system/multi-user.target.wants/FinishBootUp.service
EXPOSE 22
VOLUME [ "/sys/fs/cgroup" ]

@ -0,0 +1,66 @@
FROM ubuntu:rolling
ENV DEBIAN_FRONTEND="noninteractive" container="docker"
RUN apt-get update \
&& apt-get upgrade -y \
&& apt-get install -y \
apt-utils \
curl \
locales \
lsb-release \
net-tools \
openssh-server \
python-pip \
python2.7 \
sudo \
systemd \
&& pip install --upgrade pip \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
&& if ! getent passwd <%= @username %>; then \
useradd -d /home/<%= @username %> -m -s /bin/bash -p '*' <%= @username %>; \
fi \
&& echo "<%= @username %> ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers \
&& echo "Defaults !requiretty" >> /etc/sudoers \
&& mkdir -p /home/<%= @username %>/.ssh \
&& chown -R <%= @username %> /home/<%= @username %>/.ssh \
&& chmod 0700 /home/<%= @username %>/.ssh \
&& echo '<%= IO.read(@public_key).strip %>' >> /home/<%= @username %>/.ssh/authorized_keys \
&& chown <%= @username %> /home/<%= @username %>/.ssh/authorized_keys \
&& chmod 0600 /home/<%= @username %>/.ssh/authorized_keys \
&& echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && /usr/sbin/locale-gen \
&& cd /lib/systemd/system/sysinit.target.wants/; ls | grep -v systemd-tmpfiles-setup | xargs rm -f $1 \
&& /bin/rm -f /lib/systemd/system/multi-user.target.wants/* \
&& /bin/rm -f /etc/systemd/system/*.wants/* \
&& /bin/rm -f /lib/systemd/system/local-fs.target.wants/* \
&& /bin/rm -f /lib/systemd/system/sockets.target.wants/*udev* \
&& /bin/rm -f /lib/systemd/system/sockets.target.wants/*initctl* \
&& /bin/rm -f /lib/systemd/system/basic.target.wants/* \
&& /bin/rm -f /lib/systemd/system/anaconda.target.wants/* \
&& /bin/rm -f /lib/systemd/system/plymouth* \
&& /bin/rm -f /lib/systemd/system/systemd-update-utmp* \
&& sed -ri 's/^#?UsePAM\s+.*/UsePAM no/' /etc/ssh/sshd_config \
&& sed -ri 's/^#?PubkeyAuthentication\s+.*/PubkeyAuthentication yes/' /etc/ssh/sshd_config \
&& sed -ri 's/^#?UsePrivilegeSeparation\s+.*/UsePrivilegeSeparation no/' /etc/ssh/sshd_config \
&& echo "UseDNS=no" >> /etc/ssh/sshd_config \
&& systemctl set-default multi-user.target \
&& ln -s /lib/systemd/system/sshd.service /etc/systemd/system/multi-user.target.wants/sshd.service \
&& ln -s /lib/systemd/system/systemd-journald.service /etc/systemd/system/multi-user.target.wants/systemd-journald.service \
&& echo $'[Unit]\
\nDescription=Finish boot up\
\nAfter=ssh.service\
\n\
\n[Service]\
\nType=oneshot\
\nRemainAfterExit=yes\
\nExecStartPre=/bin/sleep 3s\
\nExecStart=/bin/rm -f /run/nologin\
\n\
\n[Install]\
\nWantedBy=default.target' >> /etc/systemd/system/FinishBootUp.service \
&& ln -s /etc/systemd/system/FinishBootUp.service /etc/systemd/system/multi-user.target.wants/FinishBootUp.service
EXPOSE 22
VOLUME [ "/sys/fs/cgroup" ]

@ -0,0 +1,131 @@
---
# host to test against
- hosts: test-kitchen
remote_user: root
tasks:
- include_tasks: tasks/dependencies.yml
- name: Install build tools
package:
name: "{{ item }}"
with_items: "{{ build_tools }}"
- name: Check wether deb-src repos are enabled
command: grep -c -e "^deb-src.*" /etc/apt/sources.list
register: deb_src_check
ignore_errors: yes
when:
- ansible_os_family == "Debian"
- name: Set deb-src check results
set_fact:
deb_src_check_result: "{{ deb_src_check.stdout | default(0) | int }}"
- name: Enable Ubuntu main & restricted source repo
replace:
path: '/etc/apt/sources.list'
regexp: '^(#\s)(.*main\srestricted)$'
replace: '\2 # enabled'
when:
- ansible_distribution == "Ubuntu"
- deb_src_check_result >= 1
- name: Enable Debian source repos
replace:
path: '/etc/apt/sources.list'
regexp: '^(deb)(.*)$'
replace: '\1\2\ndeb-src\2'
when:
- ansible_distribution == "Debian"
- deb_src_check_result >= 1
- name: Install gnupg build dependencies for Debian based distros
apt:
name: gnupg2
state: build-dep
update_cache: yes
when:
- ansible_os_family == "Debian"
- name: Install gnupg build dependencies for RedHat based distros
command: bash -lc "yum --assumeyes install yum-utils && yum-builddep --assumeyes gnupg2"
when:
- ansible_os_family == "RedHat"
- name: Get GnuPG github api content
uri:
url: https://api.github.com/repos/gpg/gnupg/tags
method: GET
return_content: yes
body_format: json
register: gnupg_tags
- name: Set url for latest gnupg release source
set_fact:
gnupg_tarball_url: >-
{{
gnupg_tags.json |
selectattr('name','match','gnupg-2.*') |
map(attribute='tarball_url') | first
}}
- name: Download latest release of gnupg source
get_url:
url: "{{ gnupg_tarball_url }}"
dest: /tmp/gnupg.tar.gz
force: yes
retries: 5
delay: 10
- name: Extract gnupg source tarball
unarchive:
src: /tmp/gnupg.tar.gz
dest: /usr/local/src/
- name: Find gnupg src directory
find:
paths: /usr/local/src
patterns: "gpg-gnupg*"
file_type: directory
recurse: no
register: found_gpg_src
- name: Set gnupg src directory
set_fact:
gpg_src_path: "{{ found_gpg_src.files | map(attribute='path') | first }}"
- name: Run gnupg autogen
command: bash -lc "cd {{ gpg_src_path }} && ./autogen.sh "
changed_when: False
- name: Disable development msg for gnupg
lineinfile:
path: "{{ gpg_src_path }}/configure"
regexp: '^development_version=.*'
line: 'development_version=no'
- name: Set gnupg build config
set_fact:
gpg_build_config: >-
--sysconfdir=/etc
--prefix=/usr
--enable-symcryptrun
--docdir=/usr/share/doc/gnupg-2.2.0
--disable-rpath
--enable-maintainer-mode
changed_when: False
- name: Configure gnupg build
command: bash -lc "cd {{ gpg_src_path }} && ./configure {{ gpg_build_config }}"
changed_when: False
- name: Compile gnupg src
command: bash -lc "cd {{ gpg_src_path }} && make"
changed_when: False
- name: Install compiled gnupg
command: bash -lc "cd {{ gpg_src_path }} && make install"
changed_when: False
- include_tasks: tasks/prep-tests.yml
- include_tasks: tasks/run-tests.yml

@ -0,0 +1,45 @@
require_relative './spec_helper'
describe 'git-secret::test' do
describe package('git-secret') do
it { should be_installed }
end
if host_inventory['platform'] == 'fedora'
describe command('find /tmp/git-secret/build -name "*.rpm"') do
its(:stdout) { should match /git-secret.*rpm/ }
end
else
describe command('find /tmp/git-secret/build -name "*.deb"') do
its(:stdout) { should match /git-secret.*deb/ }
end
end
describe file('/.git-secret_test-passed') do
it { should exist }
end
describe file('/.git-secret_lint-passed') do
it { should exist }
end
if host_inventory['platform'] == 'fedora'
describe command('rpm --query --info git-secret') do
its(:exit_status) { should eq 0 }
end
else
describe command('dpkg-query --status git-secret') do
its(:exit_status) { should eq 0 }
end
end
describe command('man --where "git-secret"') do
its(:exit_status) { should eq 0 }
end
describe command('man --where "git-secret-init"') do
its(:exit_status) { should eq 0 }
end
end

@ -0,0 +1,11 @@
require 'serverspec'
# :backend can be either :exec or :ssh
# since we are running local we use :exec
set :backend, :exec
RSpec.configure do |c|
c.before :all do
c.path = '/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin'
end
end

@ -0,0 +1,34 @@
---
# host to test against
- hosts: test-kitchen
remote_user: root
tasks:
- include_tasks: tasks/dependencies.yml
- name: Install gnupg
package:
name: "{{ item.name }}"
state: present
when:
- ansible_distribution == item.distribution
with_items:
- name: gnupg
distribution: Fedora
- name: gnupg1
distribution: Debian
- name: Check for gpg1 binary
stat:
path: /usr/bin/gpg1
register: gpg1
- name: Make gpg1 default binary
file:
src: /usr/bin/gpg1
dest: /usr/bin/gpg
state: link
force: yes
when: gpg1.stat.exists
- include_tasks: tasks/prep-tests.yml
- include_tasks: tasks/run-tests.yml

@ -0,0 +1,45 @@
require_relative './spec_helper'
describe 'git-secret::test' do
describe package('git-secret') do
it { should be_installed }
end
if host_inventory['platform'] == 'fedora'
describe command('find /tmp/git-secret/build -name "*.rpm"') do
its(:stdout) { should match /git-secret.*rpm/ }
end
else
describe command('find /tmp/git-secret/build -name "*.deb"') do
its(:stdout) { should match /git-secret.*deb/ }
end
end
describe file('/.git-secret_test-passed') do
it { should exist }
end
describe file('/.git-secret_lint-passed') do
it { should exist }
end
if host_inventory['platform'] == 'fedora'
describe command('rpm --query --info git-secret') do
its(:exit_status) { should eq 0 }
end
else
describe command('dpkg-query --status git-secret') do
its(:exit_status) { should eq 0 }
end
end
describe command('man --where "git-secret"') do
its(:exit_status) { should eq 0 }
end
describe command('man --where "git-secret-init"') do
its(:exit_status) { should eq 0 }
end
end

@ -0,0 +1,11 @@
require 'serverspec'
# :backend can be either :exec or :ssh
# since we are running local we use :exec
set :backend, :exec
RSpec.configure do |c|
c.before :all do
c.path = '/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin'
end
end

@ -0,0 +1,38 @@
---
# host to test against
- hosts: test-kitchen
remote_user: root
tasks:
- include_tasks: tasks/dependencies.yml
- name: Install gnupg
package:
name: "{{ item.name }}"
state: present
when:
- ansible_distribution == item.distribution
with_items:
- name: gnupg2
distribution: Fedora
- name: gnupg2
distribution: Ubuntu
- name: gnupg
distribution: Debian
- name: Check for gpg2 binary
stat:
path: /usr/bin/gpg2
register: gpg2
- name: Make gpg2 default binary
file:
src: /usr/bin/gpg2
dest: /usr/bin/gpg
state: link
force: yes
when:
- gpg2.stat.exists
- gpg2.stat.islnk == False
- include_tasks: tasks/prep-tests.yml
- include_tasks: tasks/run-tests.yml

@ -0,0 +1,45 @@
require_relative './spec_helper'
describe 'git-secret::test' do
describe package('git-secret') do
it { should be_installed }
end
if host_inventory['platform'] == 'fedora'
describe command('find /tmp/git-secret/build -name "*.rpm"') do
its(:stdout) { should match /git-secret.*rpm/ }
end
else
describe command('find /tmp/git-secret/build -name "*.deb"') do
its(:stdout) { should match /git-secret.*deb/ }
end
end
describe file('/.git-secret_test-passed') do
it { should exist }
end
describe file('/.git-secret_lint-passed') do
it { should exist }
end
if host_inventory['platform'] == 'fedora'
describe command('rpm --query --info git-secret') do
its(:exit_status) { should eq 0 }
end
else
describe command('dpkg-query --status git-secret') do
its(:exit_status) { should eq 0 }
end
end
describe command('man --where "git-secret"') do
its(:exit_status) { should eq 0 }
end
describe command('man --where "git-secret-init"') do
its(:exit_status) { should eq 0 }
end
end

@ -0,0 +1,11 @@
require 'serverspec'
# :backend can be either :exec or :ssh
# since we are running local we use :exec
set :backend, :exec
RSpec.configure do |c|
c.before :all do
c.path = '/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin'
end
end

@ -0,0 +1,30 @@
---
- name: Load a variable file based on the OS type, or a default if not found.
include_vars: "{{ item }}"
with_first_found:
- "{{ ansible_distribution }}.yml"
- "{{ ansible_os_family }}.yml"
- "default.yml"
- name: Install Dependencies
package:
name: "{{ item }}"
state: present
with_items: "{{ test_dependencies }}"
- name: Get bats
git:
repo: 'https://github.com/sstephenson/bats.git'
dest: /opt/bats
- name: Install bats
file:
src: /opt/bats/libexec/bats
dest: /usr/bin/bats
state: link
- name: Install fpm
gem:
name: fpm
state: present
user_install: no

@ -0,0 +1,31 @@
---
- name: Get OS package type
set_fact:
os_pkg_type: "{{ item.os_pkg_type }}"
when:
- item.os_family == ansible_os_family
with_items:
- os_family: RedHat
os_pkg_type: "rpm"
- os_family: Debian
os_pkg_type: "deb"
- os_family: Suse
os_pkg_type: "rpm"
changed_when: false
tags:
- skip_ansible_lint
- name: Get gpg version
command: gpg --version
register: gpg_version
changed_when: False
- name: Print gpg version
debug:
msg: "Running test againts {{ gpg_version.stdout_lines | first | string }}."
changed_when: False
- name: Copy git-secret src
synchronize:
src: /opt/workspace/
dest: /tmp/git-secret

@ -0,0 +1,65 @@
---
- name: Run ci-test
command: bash -lc "cd /tmp/git-secret && make test"
changed_when: False
ignore_errors: yes
register: test_results
environment:
PATH: /usr/local/bin:{{ ansible_env.PATH }}
- name: Print ci-test results
debug:
var: test_results.stdout_lines
- name: Create file when ci-test passes
file:
path: /.git-secret_test-passed
state: touch
when:
- test_results.rc == 0
- name: Run lint
command: bash -lc "cd /tmp/git-secret && make lint"
ignore_errors: yes
register: lint_results
changed_when: False
- name: Print lint results
debug:
var: lint_results.stdout_lines
- name: Create file when lint passes
file:
path: /.git-secret_lint-passed
state: touch
when:
- lint_results.rc == 0
- name: Create git-secret {{ os_pkg_type }} package
command: bash -lc "cd /tmp/git-secret && make build-{{ os_pkg_type }}"
changed_when: False
ignore_errors: yes
register: test_results
environment:
PATH: /usr/local/bin:{{ ansible_env.PATH }}
- name: Find git-secret {{ os_pkg_type }} file
find:
paths: /tmp/git-secret/build
patterns: "*.{{ os_pkg_type }}"
recurse: yes
register: pkg_location
- name: Set git-secret {{ os_pkg_type }} location
set_fact:
pkg_path: "{{ pkg_location.files | map(attribute='path') | first }}"
- name: Install git-secret {{ os_pkg_type }} package
command: bash -lc "{{ item.command }} {{ pkg_path }}"
when:
- item.os_family == ansible_os_family
with_items:
- command: "rpm --nodeps --install --force"
os_family: "RedHat"
- command: "dpkg --force-all --install"
os_family: "Debian"

@ -0,0 +1,17 @@
---
test_dependencies:
- gawk
- make
- git
- shellcheck
- ruby-dev
- rubygems
- man
build_tools:
- autoconf
- automake
- build-essential
- imagemagick
- texinfo
- transfig

@ -0,0 +1,20 @@
---
test_dependencies:
- ShellCheck
- gawk
- git
- make
- man
- redhat-rpm-config
- rpm-build
- rsync
- ruby-devel
- rubygems
- rubygems-devel
build_tools:
- ImageMagick
- autoconf
- automake
- texinfo
- transfig

@ -0,0 +1,17 @@
---
test_dependencies:
- gawk
- git
- make
- man
- ruby-dev
- rubygems
- shellcheck
build_tools:
- autoconf
- automake
- build-essential
- imagemagick
- texinfo
- transfig

@ -0,0 +1,17 @@
---
test_dependencies:
- gawk
- make
- git
- shellcheck
- ruby-dev
- rubygems
- man
build_tools:
- autoconf
- automake
- build-essential
- imagemagick
- texinfo
- transfig

4
.gitignore vendored

@ -133,3 +133,7 @@ temp/
build/
*.deb
*.fpm
# Kithcne files
Gemfile.lock
.kitchen/

@ -0,0 +1,112 @@
---
driver:
name: docker
use_sudo: false
provisioner:
# name of the host
hosts: test-kitchen
# use an ansible playbook to provision our server
name: ansible_playbook
ansible_verbose: false
require_ansible_repo: false
require_ansible_omnibus: true
ansible_version: 2.4
require_chef_for_busser: false
sudo_command: sudo -E -H
idempotency_test: false
sudo: true
ansible_extra_flags: "-e '{ kitchen_testrun: True }'"
additional_copy_path:
- ".ci-tests/integration/vars"
- ".ci-tests/integration/tasks"
transport:
max_ssh_sessions: 3
platforms:
- name: debian-stable
driver_config:
run_command: /lib/systemd/systemd
dockerfile: .Dockerfiles/debian/stable/Dockerfile
platform: debian
cap_add:
- SYS_ADMIN
volume:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
- <%=ENV['PWD']%>:/opt/workspace # Make the working directory available inside the container
run_options:
tmpfs:
- /run
- name: fedora-latest
driver_config:
run_command: /lib/systemd/systemd
dockerfile: .Dockerfiles/fedora/latest/Dockerfile
platform: fedora
cap_add:
- SYS_ADMIN
volume:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
- <%=ENV['PWD']%>:/opt/workspace # Make the working directory available inside the container
run_options:
tmpfs:
- /run
- name: ubuntu-latest
driver_config:
run_command: /lib/systemd/systemd
dockerfile: .Dockerfiles/ubuntu/latest/Dockerfile
platform: ubuntu
cap_add:
- SYS_ADMIN
volume:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
- <%=ENV['PWD']%>:/opt/workspace # Make the working directory available inside the container
run_options:
tmpfs:
- /run
- name: ubuntu-rolling
driver_config:
run_command: /lib/systemd/systemd
dockerfile: .Dockerfiles/ubuntu/rolling/Dockerfile
platform: ubuntu
cap_add:
- SYS_ADMIN
volume:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
- <%=ENV['PWD']%>:/opt/workspace # Make the working directory available inside the container
run_options:
tmpfs:
- /run
verifier:
name: serverspec
sudo_path: true
suites:
# suites found at /test/integration/$test-name
# in container @/tmp/kitchen
- name: gnupg1
verifier:
patterns:
- roles/git-secret/.ci-tests/integration/gnupg1/serverspec/*_spec.rb
bundler_path: '/usr/local/bin'
rspec_path: '/usr/local/bin'
- name: gnupg2
verifier:
patterns:
- roles/git-secret/.ci-tests/integration/gnupg2/serverspec/*_spec.rb
bundler_path: '/usr/local/bin'
rspec_path: '/usr/local/bin'
excludes:
- ubuntu-latest
- name: gnupg-git
verifier:
patterns:
- roles/git-secret/.ci-tests/integration/gnupg-git/serverspec/*_spec.rb
bundler_path: '/usr/local/bin'
rspec_path: '/usr/local/bin'
excludes:
- ubuntu-latest

@ -10,8 +10,14 @@ Before starting make sure you have:
- git
- bash
- bundler
- docker
- gawk
- gnupg (or gnupg2)
- ruby
- sha256sum
- [shellcheck](https://github.com/koalaman/shellcheck)
- test-kitchen
Only required if dealing with manuals, `gh-pages` or releases:
@ -21,7 +27,8 @@ Only required if dealing with manuals, `gh-pages` or releases:
1. Create your own or pick an opened issue from the [tracker][tracker]. Take a look at the [`help-wanted` tag][help-wanted]
2. Fork and clone your repository: `git clone https://github.com/${YOUR_NAME}/git-secret.git`
3. Make sure that everything works fine by running `make test`
3. Make sure that everything works on the current platform by running `make test`
4. [Run local CI tests](#running-local-ci-tests) to verify functionality on supported platforms `bundle exec kitchen verify --test-base-path="$PWD/.ci-tests/integration"`.
### Development Process
@ -46,12 +53,20 @@ It basically looks like that:
### Continuous integration
CI is done with the help of `travis`. `travis` handles multiple environments:
Local CI is done with the help [`test-kitchen`](http://kitchen.ci/). `test-kitchen` handles multiple test-suites on various platforms.
`bundle exec kitchen list` will output the list of test suites to be run aginst supported platforms.
Cloud CI is done with the help of `travis`. `travis` handles multiple environments:
- `Docker`-based jobs or so-called 'integration tests', these tests create a local release, install it with the package manager and then run unit-tests and system checks
- `OSX` jobs, which handle basic unit-tests on `OSX`
- Native `travis` jobs, which handle basic unit-tests and stylechecks
### Running local ci-tests
1. Install requied gems with `bundle install`.
2. Run ci-tests with `bundle exec kitchen verify --test-base-path="$PWD/.ci-tests/integration"`
### Release process
The release process is defined in the `git`-hooks and `.travis.yml`.

@ -0,0 +1,7 @@
source 'https://rubygems.org'
gem 'test-kitchen'
gem 'serverspec'
gem 'kitchen-ansible'
gem 'kitchen-docker'
gem 'kitchen-verifier-serverspec'

@ -27,6 +27,7 @@ It is possible to modify the names of the encrypted files by setting \fBSECRETS_
\-v \- verbose, shows extra information\.
\-c \- deletes encrypted files before creating new ones\.
\-d \- deletes unencrypted files after encryption\.
\-m \- encrypt files only when modified\.
\-h \- shows help\.
.
.fi

@ -17,6 +17,7 @@ It is possible to modify the names of the encrypted files by setting `SECRETS_EX
-v - verbose, shows extra information.
-c - deletes encrypted files before creating new ones.
-d - deletes unencrypted files after encryption.
-m - encrypt files only when modified.
-h - shows help.

@ -15,6 +15,76 @@ _SECRETS_DIR_PATHS_MAPPING="${_SECRETS_DIR_PATHS}/mapping.cfg"
# Commands:
: "${SECRETS_GPG_COMMAND:="gpg"}"
: "${SECRETS_CHECKSUM_COMMAND:="sha256sum"}"
# AWK scripts:
# shellcheck disable=2016
AWK_FSDB_HAS_RECORD='
BEGIN { FS=":"; OFS=":"; cnt=0; }
{
if ( key == $1 )
{
cnt++
}
}
END { if ( cnt > 0 ) print "0"; else print "1"; }
'
# shellcheck disable=2016
AWK_FSDB_RM_RECORD='
BEGIN { FS=":"; OFS=":"; }
{
if ( key != $1 )
{
print $1,$2;
}
}
'
# shellcheck disable=2016
AWK_FSDB_CLEAR_HASHES='
BEGIN { FS=":"; OFS=":"; }
{
print $1,"";
}
'
# shellcheck disable=2016
AWK_GPG_VER_CHECK='
/^gpg/{
version=$3
n=split(version,array,".")
if( n >= 2) {
if(array[1] >= 2)
{
if(array[2] >= 1)
{
print 1
}
else
{
print 0
}
}
else
{
print 0
}
}
else if(array[1] >= 2)
{
print 1
}
else
{
print 0
}
}
'
# This is 1 for gpg vesion 2.1 or greater, otherwise 0
GPG_VER_21="$(gpg --version | gawk "$AWK_GPG_VER_CHECK")"
# Bash:
@ -129,6 +199,57 @@ function _unique_filename {
}
# File System Database (fsdb):
function _get_record_filename {
# Returns 1st field from passed record
local record="$1"
local filename
filename=$(echo "$record" | awk -F: '{print $1}')
echo "$filename"
}
function _get_record_hash {
# Returns 2nd field from passed record
local record="$1"
local hash
hash=$(echo "$record" | awk -F: '{print $2}')
echo "$hash"
}
function _fsdb_has_record {
# First parameter is the key
# Second is the fsdb
local key="$1" # required
local fsdb="$2" # required
# 0 on contains, 1 for error.
gawk -v key="$key" "$AWK_FSDB_HAS_RECORD" "$fsdb"
}
function _fsdb_rm_record {
# First parameter is the key (filename)
# Second is the path to fsdb
local key="$1" # required
local fsdb="$2" # required
gawk -i inplace -v key="$key" "$AWK_FSDB_RM_RECORD" "$fsdb"
}
function _fsdb_clear_hashes {
# First parameter is the path to fsdb
local fsdb="$1" # required
gawk -i inplace "$AWK_FSDB_CLEAR_HASHES" "$fsdb"
}
# Manuals:
function _show_manual_for {
@ -315,7 +436,7 @@ function _list_all_added_files {
fi
while read -r line; do
echo "$line"
_get_record_filename "$line"
done < "$path_mappings"
}
@ -445,6 +566,10 @@ function _decrypt {
base="$base --homedir=$homedir"
fi
if [[ "$GPG_VER_21" -eq 1 ]]; then
base="$base --pinentry-mode loopback"
fi
if [[ ! -z "$passphrase" ]]; then
echo "$passphrase" | $base --quiet --batch --yes --no-tty --passphrase-fd 0 \
"$encrypted_filename"

@ -69,18 +69,20 @@ function add {
# Adding files to path mappings:
local path_mappings
path_mappings=$(_get_secrets_dir_paths_mapping)
local fsdb
fsdb=$(_get_secrets_dir_paths_mapping)
for item in "${items[@]}"; do
local path
local key
path=$(_git_normalize_filename "$item")
key="$path"
# Adding files into system, skipping duplicates.
local already_in
already_in=$(_file_has_line "$path" "$path_mappings")
already_in=$(_fsdb_has_record "$key" "$fsdb")
if [[ "$already_in" -eq 1 ]]; then
echo "$path" >> "$path_mappings"
echo "$key" >> "$fsdb"
fi
done

@ -1,5 +1,19 @@
#!/usr/bin/env bash
# shellcheck disable=2016
AWK_FSDB_UPDATE_HASH='
BEGIN { FS=":"; OFS=":"; }
{
if ( key == $1 )
{
print key,hash;
}
else
{
print $1,$2;
}
}
'
function _optional_clean {
local clean="$1"
@ -26,7 +40,9 @@ function _optional_delete {
while read -r line; do
# So the formating would not be repeated several times here:
_find_and_clean "*$line" "$verbose"
local filename
filename=$(_get_record_filename "$line")
_find_and_clean "*$filename" "$verbose"
done < "$path_mappings"
if [[ ! -z "$verbose" ]]; then
@ -35,20 +51,49 @@ function _optional_delete {
fi
}
function _get_checksum_local {
local checksum="$SECRETS_CHECKSUM_COMMAND"
echo "$checksum"
}
function _get_file_hash {
local input_path="$1" # Required
local checksum_local
local file_hash
checksum_local="$(_get_checksum_local)"
file_hash=$($checksum_local "$input_path" | awk '{print $1}')
echo "$file_hash"
}
function _optional_fsdb_update_hash {
local key="$1"
local hash="$2"
local fsdb # path_mappings
fsdb=$(_get_secrets_dir_paths_mapping)
gawk -i inplace -v key="$key" -v hash="$hash" "$AWK_FSDB_UPDATE_HASH" "$fsdb"
}
function hide {
local clean=0
local delete=0
local fsdb_update_hash=0 # add checksum hashes to fsdb
local verbose=''
OPTIND=1
while getopts 'cdvh' opt; do
while getopts 'cdmvh' opt; do
case "$opt" in
c) clean=1;;
d) delete=1;;
m) fsdb_update_hash=1;;
v) verbose='v';;
h) _show_manual_for 'hide';;
@ -71,9 +116,13 @@ function hide {
path_mappings=$(_get_secrets_dir_paths_mapping)
local counter=0
while read -r line; do
while read -r record; do
local filename
local fsdb_file_hash
local encrypted_filename
encrypted_filename=$(_get_encrypted_filename "$line")
filename=$(_get_record_filename "$record")
fsdb_file_hash=$(_get_record_hash "$record")
encrypted_filename=$(_get_encrypted_filename "$filename")
local recipients
recipients=$(_get_recepients)
@ -83,13 +132,23 @@ function hide {
local input_path
local output_path
input_path=$(_append_root_path "$line")
input_path=$(_append_root_path "$filename")
output_path=$(_append_root_path "$encrypted_filename")
# shellcheck disable=2086
$gpg_local --use-agent --yes --trust-model=always --encrypt \
$recipients -o "$output_path" "$input_path"
file_hash=$(_get_file_hash "$input_path")
# encrypt file only if required
if [[ "$fsdb_file_hash" != "$file_hash" ]]; then
# shellcheck disable=2086
$gpg_local --use-agent --yes --trust-model=always --encrypt \
$recipients -o "$output_path" "$input_path" > /dev/null 2>&1
# If -m option was provided, it will update unencrypted file hash
local key="$filename"
local hash="$file_hash"
# Update file hash if required in fsdb
[[ "$fsdb_update_hash" -gt 0 ]] && \
_optional_fsdb_update_hash "$key" "$hash"
fi
counter=$((counter+1))
done < "$path_mappings"

@ -1,5 +1,25 @@
#!/usr/bin/env bash
# shellcheck disable=2016
AWK_ADD_TO_GITIGNORE='
BEGIN { cnt=0; }
{
print $0
if ( $0 == pattern ) cnt++;
}
ENDFILE { if ( cnt == 0) print pattern; }
'
function gitignore_add_pattern {
local pattern
local gitignore_file_path
pattern="$1"
gitignore_file_path=$(_append_root_path '.gitignore')
_maybe_create_gitignore
gawk -i inplace -v pattern="$pattern" "$AWK_ADD_TO_GITIGNORE" "$gitignore_file_path"
}
function init {
OPTIND=1
@ -30,4 +50,10 @@ function init {
touch "$(_get_secrets_dir_keys_mapping)" "$(_get_secrets_dir_paths_mapping)"
echo "'$git_secret_dir/' created."
local random_seed_file
random_seed_file=".gitsecret/keys/random_seed"
gitignore_add_pattern "$random_seed_file"
# TODO: git attributes to view diffs
}

@ -39,7 +39,13 @@ function remove {
fi
# Deleting it from path mappings:
_delete_line "$normalized_path" "$path_mappings"
# _delete_line "$normalized_path" "$path_mappings"
# Remove record from fsdb with matching key
local key
key="$normalized_path"
fsdb="$path_mappings"
_fsdb_rm_record "$key" "$fsdb"
rm -f "${path_mappings}.bak" # not all systems create '.bak'
# Optional clean:

@ -32,8 +32,10 @@ function reveal {
local counter=0
while read -r line; do
local filename
local path
path=$(_append_root_path "$line")
filename=$(_get_record_filename "$line")
path=$(_append_root_path "$filename")
# The parameters are: filename, write-to-file, force, homedir, passphrase
_decrypt "$path" "1" "$force" "$homedir" "$passphrase"

@ -1,5 +1,17 @@
#!/usr/bin/env bash
# shellcheck disable=2016
AWK_GPG_KEY_CNT='
BEGIN { cnt=0; OFS=":"; FS=":"; }
flag=0; $1 == "pub" { cnt++ }
END { print cnt }
'
function get_gpg_key_count {
local gpg_local
gpg_local=$(_get_gpg_local)
$gpg_local --list-public-keys --with-colon | gawk "$AWK_GPG_KEY_CNT"
}
function tell {
local emails
@ -46,6 +58,8 @@ function tell {
_abort "you must provide at least one email address."
fi
local start_key_cnt
start_key_cnt=$(get_gpg_key_count)
for email in "${emails[@]}"; do
# This file will be removed automatically:
_temporary_file # note, that `_temporary_file` will export `filename` var.
@ -71,4 +85,11 @@ function tell {
done
echo "done. ${emails[*]} added as someone who know(s) the secret."
# force re-encrypting of files if required
local fsdb
local end_key_cnt
fsdb=$(_get_secrets_dir_paths_mapping)
end_key_cnt=$(get_gpg_key_count)
[[ $start_key_cnt -ne $end_key_cnt ]] && _fsdb_clear_hashes "$fsdb"
}

@ -13,11 +13,22 @@ FIXTURES_DIR="$BATS_TEST_DIRNAME/fixtures"
TEST_GPG_HOMEDIR="$BATS_TMPDIR"
AWK_GPG_GET_FP='
BEGIN { OFS=":"; FS=":"; }
{
if ( $1 == "fpr" )
{
print $10
exit
}
}
'
# GPG-based stuff:
: "${SECRETS_GPG_COMMAND:="gpg"}"
# This command is used with absolute homedir set and disabled warnings:
GPGTEST="$SECRETS_GPG_COMMAND --homedir=$TEST_GPG_HOMEDIR --no-permission-warning"
GPGTEST="$SECRETS_GPG_COMMAND --homedir=$TEST_GPG_HOMEDIR --no-permission-warning --batch"
# Personal data:
@ -40,6 +51,23 @@ function test_user_email {
# GPG:
function stop_gpg_agent {
local username=$(id -u -n)
ps awx -u "$username" | gawk \
'/gpg-agent --homedir/ { if ( $0 !~ "awk" ) { system("kill -9 "$1) } }' \
> /dev/null 2>&1
}
function get_gpgtest_prefix {
if [[ $GPG_VER_21 -eq 1 ]]; then
echo "echo \"$(test_user_password $1)\" | "
else
echo ""
fi
}
function get_gpg_fingerprint_by_email {
local email="$1"
local fingerprint
@ -54,13 +82,8 @@ function get_gpg_fingerprint_by_email {
function install_fixture_key {
local public_key="$BATS_TMPDIR/public-${1}.key"
local email
email=$(test_user_email "$1")
$SECRETS_GPG_COMMAND --homedir="$FIXTURES_DIR/gpg/${1}" \
--no-permission-warning --output "$public_key" \
--armor --batch --yes --export "$email" > /dev/null 2>&1
\cp "$FIXTURES_DIR/gpg/${1}/public.key" "$public_key"
$GPGTEST --import "$public_key" > /dev/null 2>&1
rm -f "$public_key"
}
@ -68,26 +91,27 @@ function install_fixture_key {
function install_fixture_full_key {
local private_key="$BATS_TMPDIR/private-${1}.key"
local gpgtest_prefix="$(get_gpgtest_prefix $1)"
local gpgtest_import="$gpgtest_prefix $GPGTEST"
local email
local fp
local fingerprint
email=$(test_user_email "$1")
$SECRETS_GPG_COMMAND --homedir="$FIXTURES_DIR/gpg/${1}" \
--no-permission-warning --output "$private_key" --armor \
--yes --export-secret-key "$email" > /dev/null 2>&1
$GPGTEST --allow-secret-key-import \
--import "$private_key" > /dev/null 2>&1
\cp "$FIXTURES_DIR/gpg/${1}/private.key" "$private_key"
fp=$($GPGTEST --with-fingerprint "$private_key")
bash -c "$gpgtest_import --allow-secret-key-import \
--import \"$private_key\"" > /dev/null 2>&1
# since 0.1.2 fingerprint is returned:
fingerprint=$(echo "$fp" | tr -d ' ' | sed -n '2p' | sed -e 's/.*=//g')
fingerprint=$($GPGTEST --with-fingerprint \
--with-colon \
--list-secret-key $email | gawk "$AWK_GPG_GET_FP")
install_fixture_key "$1"
rm -f "$private_key"
# return fingerprint to delete it later:
echo "$fingerprint"
}
@ -97,7 +121,7 @@ function uninstall_fixture_key {
local email
email=$(test_user_email "$1")
$GPGTEST --batch --yes --delete-key "$email" > /dev/null 2>&1
$GPGTEST --yes --delete-key "$email" > /dev/null 2>&1
}
@ -111,7 +135,7 @@ function uninstall_fixture_full_key {
fingerprint=$(get_gpg_fingerprint_by_email "$email")
fi
$GPGTEST --batch --yes \
$GPGTEST --yes \
--delete-secret-keys "$fingerprint" > /dev/null 2>&1
uninstall_fixture_key "$1"
@ -210,8 +234,13 @@ function unset_current_state {
# unsets `git` state
remove_git_repository
# stop gpg-agent
stop_gpg_agent
# removes gpg homedir:
rm -f "pubring.gpg" "pubring.gpg~" "secring.gpg" "trustdb.gpg" "random_seed"
find "$TEST_GPG_HOMEDIR" \
-regex ".*\/random_seed\|.*\.gpg\|.*\.kbx.?\|.*private-keys.*\|.*test_sub_dir\|.*S.gpg-agent\|.*file_to_hide.*" \
-exec rm -rf {} +
# return to the base dir:
cd "$SECRET_PROJECT_ROOT" || exit 1

@ -0,0 +1,59 @@
-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: GnuPG v1
lQO+BFaigVQBCADC5dJ0xweZ+6L0owo2wpKSbQFGQoRJxYVcc1dWe3zNZ5yBrJDV
N79rYV5AmHnIGDAJrHHV9rYM4+C8obKka7P3ROm0RMsYKDhpQXWFjsOrl1rjWL86
6D4X7Q5uuJWluPp1+hbzpBmNCX3Y5sr1fmCazvR5iIAvY3EkYbqDt2+BtGTqlevY
ivWiOoPKRY9Dc44rKQh8GmaVJzcO3D21IF70i3GnOtjUSK8DWXdD4BrtYTE/9Ua4
bmT2pOPmGMcI38pQHZQXqMPTzloakZk9qIbBoB3FS/UFxQr3R3V+tXPm1Eca/75G
+U4VCRLUFWsDU5d+oTCFCa0qNjGnLFOE85C7ABEBAAH+AwMCW7i8uGNVEnRgGKI3
2g1TXbUxgqg8ayjCkE2m99KmtbzxAAGJfuETnpxMo9U5JDOk68UC4jgArfWFOad5
Q3waxbCmKOTuSKqiA1FjXVoL5CtSzziygJ2XSLFh+fOsyeXWSdsmHjIQsXmwSnEm
9TJxNHNA5AL53lX+ike78cP8fNNlZSFWzfqGSe2nHgLICqMAk8hDUO6s/zFrHmbb
6Bu7azLTe4r9oEHcD8XsGlxhUUntK8WFPnrZlAdo++E8Ax4VQA/KXaU7STNutMQu
tvuIOB+E6RRH/lKesIwt2Hrbin/AQKzyyedUJOVqW/UCsXBN9dnpbdR5pSn3eXxy
LLb3S7whUVUE3HSrVqTRoyupyX10lAecpHPJMB6qq054x1xStPAkcsuVGrewznjD
Zywicif6QzbBc6ZN1tS7fOxxJ9vn5qT9et0xnIJqFc++eofJHJ/Wl9eBtg5XTis7
69ERbU6GjqVJhAmPPQNoEVUhS1hJimQxAF/oqhEO8yTEJhmGZIzYTrQ1GcLh/AiH
qkZ5LVwraTrXOJJaRzBL+bzfJa91MJVIpfS9wDTpW/CFvFp9Og/dYmTDfE1zLgSv
tPSD6RcFxiOTkAeLRN7X5RdFqHjWdhgu2hyd87jpfGt3u0BK1iWW6CptSeNrSFXy
lEsU3VuBFMRIjdUAXDefN8/99LdSgO7FkLyJsTeTxGOgrdp9fJF3ZEnk5wYRj6Im
/3NyEq5gdeow02LPIgBGqsXi5iHSAaSJEZnpguCsJqeDnzsGmiLBfy2/MS03+XzU
FW4OxbNxprDJdheHYqJ6k2z7xchkPedk0s9JpDVe/5ShMyrJI0THP2psPm+EVlKK
7lDpNf4hRj2by8HYLa/X21AgS8WLTWd+osyO5HQxqhMlDqtpKkOJ4q6ylb3QgDNU
GrQiYXR0YWNrZXIxIDxhdHRhY2tlcjFAZ2l0c2VjcmV0LmlvPokBOAQTAQIAIgUC
VqKBVAIbAwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQiAEDMVPMIKV1RwgA
sQAQmjtDpyKS/+zzFgVuOqu5QffqylFMXw8zrchiBLTeTCEKoixNj5cccpAG9xDU
ZcMwMw/lSAz1MXSfQ6GGvl4ErlZrlx9SSacqPwDNoKWMci9PDb3JpaXZtQQCrDmw
nZpSE6bKvhAoTIaA6Tn8g4uOo3vTyDuX1DznrcUFrMCW7vw5ztttA1hvg5iHrs4d
ia/FaRX0SOf9y/0u9kQW2pkWlVL2pRgQaYwHl7FQRGnrwibxyEpTQ8x+d8uU87DN
aaiUZ5GcsZT2U6cmhuz/k0IFGL408huF5h50KVFTYQNQc3Le3v9wrh88Obn4ciX/
2YizefDo5WGt5/mvlUfp750DvQRWooFUAQgAv54OkX9n0+L/59UUWWtqz+siBF3o
3wMU0AKoATIZbilxoOPHzvv8iWpSlShTNsY4HqsZf7tIqfJLq91EigV0uQs0v6zw
zFC31t8lQaQy0g0uv04xnMIvYw4xRhUa7dBphokeuuSCU7uJzq6za3Ia1hoNZEfd
lEG/1LdGMzMLURxUlWWwpzRJdPEpEd6/InavNiffiGaiJXfTUQfpicz0k7eyXgK5
Pat07UaIW80gol+fghu4BhEHAWAfAV6ocd/YfUn7Hax55l0/npC3Y72JMhhSW11H
gOE1iz33INGF9pfNL+VQwQj9gUQCOcczquD4NQ7RgQAdZQ2K9k4caOzbxQARAQAB
/gMDAlu4vLhjVRJ0YNV0uVpXwCia2Vq2WMzxN0UyvAeF9QwkV8LAJt3O/VwzdJDg
jWALHfUHysylbmE3nwAL6gOznL+XQ/Sf1v0dzDZZi8S64t4DNGnk7wRuui2/ZRVd
3jM2tiW/Y7ijWIpEaRwH8jtrV6+zoUt76YgBcgun+nhUzcGbdvh11Ygu5VHYxNU3
J7p4E80gClGsciNO9B+hgR8kg+wGc+C0LBey1mh5A0AWqO0NwFlF8YlpleC09Pld
I3+NJ4miZUMS6ue5Me1QvBcAvaY3Vuh2U0RPICI2Athx0xpILktnuANqjxg4BiZI
Lelaxxl12ycdO5Im1IUXiLBgMOBRFvRQ/6iEb/oTGRN8aY5W93LQ7nSyKdn6B6V5
HzDfuwrDJP6Q+sMi3SCEFgaNpNTRPu11gvMAj1V+4zwgsflZHVgkKSwvg2pRXAPp
rNfJo6d0bfImF9w2J/2d/gYSOoWsC92VG0KY8hVWkHOBUVZFyRl4zv8UNoCtBPkM
Wq00X0J3ZNAjnPE8hl2OK4q+4r0Q3CecVgK0tlTMqVfgNVgG0X6LV7xmbViY4HuA
kvfmLkTFwL3NzpGVtm4S2DjMUQQygjS2GOfOM4TrNd9Jn5WMCP/7HX5K/3VjL4ai
mpAoz0A2UeA116KaniW8PnZCm9A+ZFVALjsikgi1gBEuJC2+mgUfhbPtni41qcio
mhN9si+BE7HhiFk8I/+xg7bAmNcw6hk/zESfKKxqqV4iiauQBy9zEtA7Gg8chcK+
08eaunF2abkF8xbYPOF8p71sHo2UeJ1gK1lGMzTt1p7NSZm0F9VmPcy8WWjzna1z
oRy44TyWcW90abV5gCerAhSDAlrdwZfcRG6NXT/wG0TjoCMgiIhR1X1gjpozV6NB
3fB9sc/NDhhibsqA0i0JiYkBHwQYAQIACQUCVqKBVAIbDAAKCRCIAQMxU8wgpQqe
CACBDi7KrqQzdzeipLadUsaTptvFBlwavpCLRtNbJI8v5i4kr8cLmyqGAwCS8Yem
3SCI/K4ujln8an6XrhsOE/uwfyQz5iUcP7BN9sIEp/ITOIXu0q0kzxThmpJqHzvf
bvkPemFEiwYwGZn87cFXmd7FMEoFIt/s/bCnPCuBkxvUMj/D65Sb5x1X+FzWjK2m
OVJGpTHAixns+DDHOfXEkghQTfj1pX/LBV9nXKlSZtpDO/p/kx+xITxXA/a4EDtD
2JpZBYmSTcbyVamQEMTzMIfEUhMbSrhKRYcm6g5Jbu5oy0ci/5qIhsR45pA7JSc0
0Vjcr8GgU7JyYnSqF2Ua8YA6
=Ygfi
-----END PGP PRIVATE KEY BLOCK-----

@ -0,0 +1,30 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1
mQENBFaigVQBCADC5dJ0xweZ+6L0owo2wpKSbQFGQoRJxYVcc1dWe3zNZ5yBrJDV
N79rYV5AmHnIGDAJrHHV9rYM4+C8obKka7P3ROm0RMsYKDhpQXWFjsOrl1rjWL86
6D4X7Q5uuJWluPp1+hbzpBmNCX3Y5sr1fmCazvR5iIAvY3EkYbqDt2+BtGTqlevY
ivWiOoPKRY9Dc44rKQh8GmaVJzcO3D21IF70i3GnOtjUSK8DWXdD4BrtYTE/9Ua4
bmT2pOPmGMcI38pQHZQXqMPTzloakZk9qIbBoB3FS/UFxQr3R3V+tXPm1Eca/75G
+U4VCRLUFWsDU5d+oTCFCa0qNjGnLFOE85C7ABEBAAG0ImF0dGFja2VyMSA8YXR0
YWNrZXIxQGdpdHNlY3JldC5pbz6JATgEEwECACIFAlaigVQCGwMGCwkIBwMCBhUI
AgkKCwQWAgMBAh4BAheAAAoJEIgBAzFTzCCldUcIALEAEJo7Q6cikv/s8xYFbjqr
uUH36spRTF8PM63IYgS03kwhCqIsTY+XHHKQBvcQ1GXDMDMP5UgM9TF0n0Ohhr5e
BK5Wa5cfUkmnKj8AzaCljHIvTw29yaWl2bUEAqw5sJ2aUhOmyr4QKEyGgOk5/IOL
jqN708g7l9Q8563FBazAlu78Oc7bbQNYb4OYh67OHYmvxWkV9Ejn/cv9LvZEFtqZ
FpVS9qUYEGmMB5exUERp68Im8chKU0PMfnfLlPOwzWmolGeRnLGU9lOnJobs/5NC
BRi+NPIbheYedClRU2EDUHNy3t7/cK4fPDm5+HIl/9mIs3nw6OVhref5r5VH6e+5
AQ0EVqKBVAEIAL+eDpF/Z9Pi/+fVFFlras/rIgRd6N8DFNACqAEyGW4pcaDjx877
/IlqUpUoUzbGOB6rGX+7SKnyS6vdRIoFdLkLNL+s8MxQt9bfJUGkMtINLr9OMZzC
L2MOMUYVGu3QaYaJHrrkglO7ic6us2tyGtYaDWRH3ZRBv9S3RjMzC1EcVJVlsKc0
SXTxKRHevyJ2rzYn34hmoiV301EH6YnM9JO3sl4CuT2rdO1GiFvNIKJfn4IbuAYR
BwFgHwFeqHHf2H1J+x2seeZdP56Qt2O9iTIYUltdR4DhNYs99yDRhfaXzS/lUMEI
/YFEAjnHM6rg+DUO0YEAHWUNivZOHGjs28UAEQEAAYkBHwQYAQIACQUCVqKBVAIb
DAAKCRCIAQMxU8wgpQqeCACBDi7KrqQzdzeipLadUsaTptvFBlwavpCLRtNbJI8v
5i4kr8cLmyqGAwCS8Yem3SCI/K4ujln8an6XrhsOE/uwfyQz5iUcP7BN9sIEp/IT
OIXu0q0kzxThmpJqHzvfbvkPemFEiwYwGZn87cFXmd7FMEoFIt/s/bCnPCuBkxvU
Mj/D65Sb5x1X+FzWjK2mOVJGpTHAixns+DDHOfXEkghQTfj1pX/LBV9nXKlSZtpD
O/p/kx+xITxXA/a4EDtD2JpZBYmSTcbyVamQEMTzMIfEUhMbSrhKRYcm6g5Jbu5o
y0ci/5qIhsR45pA7JSc00Vjcr8GgU7JyYnSqF2Ua8YA6
=CU3L
-----END PGP PUBLIC KEY BLOCK-----

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,59 @@
-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: GnuPG v1
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
Bh9SiS8oRa1I+f4=
=PunG
-----END PGP PRIVATE KEY BLOCK-----

@ -0,0 +1,30 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1
mQENBFaigO0BCACwtBp5eg1d68f9WhmYew/4eU5zjaJsNj1DHsHokxsUt9QpIdVq
DuPxlW8pTOUrhqQZd0ozaaDMswwFpzkblelQJzt/juqy/lkK2StlQfK2YRk7zehV
HA6YOtTFyYbyheCeSFNJ4bfy3nn1lSDTtSmDpQBz19hVBP9JapI8K96nTSuK0NAb
FEZ7ZdFLdXbtEkXHtTL+eqrys8UI7Ou+iZZ+dBlwTl9Jszg/b6IjYCYFT/LKuLX3
ss9fI/ypuwjB+1zys9WNDiNrrb8e26GDeOjfTH0vPuV9nU2gqLVzlssTLiWkrjSW
g3OhO3jBBa59oEf60eBreL0FZ74LqRsPT8NVABEBAAG0GnVzZXIxIDx1c2VyMUBn
aXRzZWNyZXQuaW8+iQE4BBMBAgAiBQJWooDtAhsDBgsJCAcDAgYVCAIJCgsEFgID
AQIeAQIXgAAKCRDSgFpBgumf9H7JB/0SGchHccPND6sjUVYO/cK4bret8u6L7Hmr
6jesKRAoJCuLq6lTQRK8wNS6hEDjRi1I3IErQnUhgGCZcOWSeuyu6EYnczg52aLy
53U+A9VmJH+L+I55feQm5SVJD0jByp8vrsNDK4Jd0Cq4uQcQYIDB7t99HILYaclA
tD/sqotWER3Xvtj9dOyHZKS2ICdaic95aAIJugJhtJMIiusCGc2yML5xLWQ1cb6H
6zNaOZQF4B/qbscgu5WWlPIJyalxjOa2CQBDwtxOjJuOX9yZBI523ea7idO0kCdA
xpJShii+c0xtJV99DG9vBF19DgCtTDgyB73dy3Eqm1SepTF1CXoSuQENBFaigO0B
CADag/bxqEeudSnZ9M9BTlZEoGUBuNyrV7KI9Inwv3gufCaj4UQkxXEi2+eQCBi7
AB3LvskcJEsAaworEyB6jteXUm2G24/tS32F9JTgTbRhF2QODWdNoRjprAtjQ+Pt
akOWnwSIw5THeXHkGNzIqXVh59JouQhdOImiw5jDxIsuguzSqH7krPuPpMs4OPUX
Z4z/znuHCLIhHuAegrzD65zqDl8jHJOg5mc/x4/PqZHhofr2k9/7G08gqzhD5mgv
h5i39owsnK+sMVZDo8BGNVdWYVVYvtu7jdhbJJhCZqnkIbA4cCoai1pns/ZFgM/U
26gFQeROcmrSTJsXOqXCJG6RABEBAAGJAR8EGAECAAkFAlaigO0CGwwACgkQ0oBa
QYLpn/QNjQf8DXiS/dKXQIFSQCfpe1+wS90ErJ45mM82UrUfOA3A8KRuk5HiD2ZO
oDi2v9fOkmT8DZUTnLT8MhpGfGK/L22ueNAbt413KabTwzL4ZEI9Y6Rx4iVJXsgF
mHaIy9ikVVcQs5yMfrGV1z5FCInSKtFezbxdtdhztPglhmvvGANAhvrLJoAB13r/
+TWgcZB/a5Ow1ZnOzjc4EA3bN7cN1hZcy2yyQdW+ecUlIBH7TeuD3ZUxIB+HoYqr
RoUXXapNQABZUSSgAUeBEFBGpUVP1GAo6CTtVGXK07Wy/ls/lmW8Tki830cJMcs5
gKv+xOA5vehhhD/NkCYGH1KJLyhFrUj5/g==
=0Q64
-----END PGP PUBLIC KEY BLOCK-----

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -0,0 +1,59 @@
-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: GnuPG v1
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
FfGupHnbRtqsqQ==
=7tcw
-----END PGP PRIVATE KEY BLOCK-----

@ -0,0 +1,30 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1
mQENBFaigRUBCACgb+7xhV1nJZim3noxozslfrWXPYEVQt7Is8QjATaKg6ULqImi
tpgnlUNCaEAd3PMufVSqd416KyytwUOBVaFIEej/SJcJ2UU4nFvJsvo4bNmInOc3
cNSqJ5VcI7D++wdHSecr2YayWtsh85jt6xI2oGBN334Yl6sHnNGC/vmE0pWovpib
rwAW7bWSOYOQxpzANm9O+9oJ6WsTGVVWkZ/SAaRo+VYDA5rwCI6STt+rEcKalr5C
sbtqELDDDrYYviU4kZx6WYdiDcF5ATSiuGZrQTjEdBFc+GmFxbW+aumeC+Y1jYOp
aYUhbDKffnrxvFjm5+3PBbrPmJ5rFWr1f00bABEBAAG0GnVzZXIyIDx1c2VyMkBn
aXRzZWNyZXQuaW8+iQE4BBMBAgAiBQJWooEVAhsDBgsJCAcDAgYVCAIJCgsEFgID
AQIeAQIXgAAKCRDqoOTrazNsiz97CACLgvaQgkS2oLRlQUZX0Yma+P+C4TJjlu5Q
pVdQyk13w2Fn25EsEWYbrya2MiU3y3A25xdRM7aUtZiEwmlSGOht1E/PDzzus2qz
BIilZq89mt4wqBcnvb/aZ32btyv0WYRn19nHzS0HB0vb5xhrUiLG6ja+TZSfQsPj
aoJuHSdHFIN/eDrIO1IdhniLojz1fADlNIbX8LS4hytEoYMGSF3TmyoIn23+bqgD
GTcDydkz6La5LT52Y5XACYO/r8Drj4B9/mFizHztR4B1TvqeLevDSlldOf3TC/9p
jR16JwOWZJRq21I2D8boqgTpEREvjuK3JTTsPjJS9MEYvmBW94FfuQENBFaigRUB
CAC0PMNd0lI7CYOP8mECTTAP5EGPEjM79X8VcKi0dqqJJJG9nQmfoIysZrQQqSwZ
eOpjr6OEL8ctv2FeNH5yJT8TrghU0l20anvuuNVTKCuxjR/RlRJC59ML2VxUA/zA
3Hn0GTSeW47TN4fSUxFT9wt3IYKzsLeh07nFW8WXkgnqMf/3nLoF1EZIM1OfN5Bd
P59QfEtls8boBsshcM4ArY4AedRjra4YsXyXr3HUfKYtWoP1NhNT1Wlir0iXx7Xw
7p+oTUwSnjMeTJN/oi8KBms4Uv5cCnAdjLU2yQqL1Y0N1AK+kOq81I9lKqtqNN14
ng3O5WKn5xwNP+1lVMDwD7RpABEBAAGJAR8EGAECAAkFAlaigRUCGwwACgkQ6qDk
62szbIvUZQf/adIYw+fHM1zlGJH+C/lEFoGi0AXOTqBH13T+haoykwrxnBOdaTGY
196bj+uiSbtFqQWcuMNrOWNNH6NAl30Ujya/ltLv7FJ3DOuUyIU/3Bhp1t1+jEpp
MJRYk2pkRmmTg2lrOgSvPiqNgmK/FBx3t+JCtmQxtrTBBnJcmx5/8YGdOCEsiGJ2
jl+5Im4XgT0OhQX320o82XrK7/Pp+ttmc7ExT6pc53sSYRUfEyObpCYVIz1nWK1F
ujfW+ojFFUvhHPwSL3nydkJORg8lcQm/zXjbgCeMZ/l3ynkvSA+X9/Q7aQWGrpU0
LRLGAeA9PZZDYx9JTQUYFfGupHnbRtqsqQ==
=HLsH
-----END PGP PUBLIC KEY BLOCK-----

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -29,7 +29,7 @@ function teardown {
@test "run 'usage' with ignored '.gitsecret/'" {
echo ".gitsecret/" >> ".gitignore"
echo ".gitsecret" >> ".gitignore"
run git secret usage
[ "$status" -eq 1 ]

Loading…
Cancel
Save