Initial import

This commit is contained in:
Glenn Y. Rolland 2022-07-09 16:19:44 +02:00
commit 92faeb2c1b
9 changed files with 303 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
lib
bin

37
Dockerfile Normal file
View File

@ -0,0 +1,37 @@
## Stage 1 : build binary
FROM crystallang/crystal:1.4.1 AS builder
COPY . /app
WORKDIR /app
RUN shards build
## Stage 2 : include binary into final image
FROM python:3.7-bullseye AS runner
RUN apt-get update \
&& apt-get -yq install \
libevent-core-2.1-7 \
gettext \
jq \
python3-aodhclient \
python3-barbicanclient \
python3-ceilometerclient \
python3-cinderclient \
python3-cloudkittyclient \
python3-designateclient \
python3-gnocchiclient \
python3-octaviaclient \
python3-osc-placement \
python3-openstackclient \
python3-pankoclient \
zip \
&& rm -rf /var/lib/apt/lists/*
# RUN wget https://github.com/sapcc/cyclone/releases/download/v0.1.28/cyclone \
# -O /usr/bin/cyclone \
# && chmod +x /usr/bin/cyclone
COPY --from=builder /app/bin/arkisto /usr/bin/arkisto
CMD /bin/bash

15
Makefile Normal file
View File

@ -0,0 +1,15 @@
build:
shards build
docker: docker-build docker-test docker-push
docker-build:
docker build -t glenux/openstack-arkisto .
docker-push:
docker push glenux/openstack-arkisto
docker-test:
docker run glenux/openstack-arkisto arkisto --version

4
README.md Normal file
View File

@ -0,0 +1,4 @@
# Arkisto
A simple tool to automate openstack snapshots

22
arkisto.sample.yml Normal file
View File

@ -0,0 +1,22 @@
---
version: "1"
retention:
days: 8
cycle: true
max_items: 2
targets:
- name: smart-app
volume_id: x
snapshot_prefix: y
- name: smart-db
volume_id: x
snapshot_prefix: y
- name: short-db
volume_id: x2
snapshot_prefix: y
- name: collector-db
volume_id: x2
snapshot_prefix: y
#

6
shard.lock Normal file
View File

@ -0,0 +1,6 @@
version: 2.0
shards:
tablo:
git: https://github.com/hutou/tablo.git
version: 0.10.1

25
shard.yml Normal file
View File

@ -0,0 +1,25 @@
---
name: arkisto
version: 0.1.0
authors:
- Glenn Y. Rolland <glenn.rolland@boldcode.io>
description: |
Simple and stupid utility to cycle openstack volume backups/snapshots
targets:
arkisto:
main: src/arkistoctl/main.cr
dependencies:
# Text tables
tablo:
github: hutou/tablo
# development_dependencies:
# webmock:
# github: manastech/webmock.cr
license: MIT

View File

@ -0,0 +1,51 @@
- Attached to: []
ID: 7b715476-5397-48de-87ac-5a63170fff71
Name: ovh-managed-kubernetes-e6j07m-pvc-fc264e28-94e3-43c5-afe1-3c99b6d95bfb
Size: 1
Status: available
- Attached to: []
ID: c9d05e3e-c668-47fd-8bd6-0cedc9dc02c5
Name: ovh-managed-kubernetes-e6j07m-pvc-44bca100-2f8c-4be2-9491-d2254a42287f
Size: 2000
Status: available
- Attached to: []
ID: 8c87c196-1dd6-4190-bff5-00b543965093
Name: ovh-managed-kubernetes-e6j07m-pvc-9fad19b4-b32c-452a-9893-524fcdc3a4b1
Size: 50
Status: available
- Attached to:
- attached_at: '2022-06-26T19:03:31.000000'
attachment_id: 503f8552-e2f9-4aff-a489-8382bbed3883
device: /dev/sdb
host_name: null
id: c9b11fcb-a6a4-4387-b55b-34121f97dac4
server_id: 7ee31946-16ab-4759-be33-6499a339f929
volume_id: c9b11fcb-a6a4-4387-b55b-34121f97dac4
ID: c9b11fcb-a6a4-4387-b55b-34121f97dac4
Name: ovh-managed-kubernetes-e6j07m-pvc-13dcac68-71c9-4794-b0ab-d48e76d843ef
Size: 5800
Status: in-use
- Attached to:
- attached_at: '2022-06-21T12:47:29.000000'
attachment_id: 569b7110-74e1-4f87-b92d-ab5e1a2a473c
device: /dev/sdb
host_name: null
id: de7b118f-413b-4962-a028-a742df4bc4fc
server_id: e1753464-9328-4eea-ae98-21c332e94dc5
volume_id: de7b118f-413b-4962-a028-a742df4bc4fc
ID: de7b118f-413b-4962-a028-a742df4bc4fc
Name: ovh-managed-kubernetes-e6j07m-pvc-dfbf1e3a-7ed6-4a90-a4e0-4b5516f88051
Size: 50
Status: in-use
- Attached to:
- attached_at: '2022-06-27T17:31:53.000000'
attachment_id: 845a7ff2-ad54-4040-b69b-fce7fdfdece2
device: /dev/sdb
host_name: null
id: 6d4492e5-6b38-4ad3-b9bf-27ba86e2506b
server_id: 37220c33-19e7-45cc-9c6a-ddf957be3c76
volume_id: 6d4492e5-6b38-4ad3-b9bf-27ba86e2506b
ID: 6d4492e5-6b38-4ad3-b9bf-27ba86e2506b
Name: ovh-managed-kubernetes-e6j07m-pvc-7bf995bf-ac82-4f42-94ca-78cd9c78959d
Size: 1
Status: in-use

141
src/arkistoctl/main.cr Normal file
View File

@ -0,0 +1,141 @@
require "yaml"
require "option_parser"
require "colorize"
# require "xdg_basedir"
# require "completion"
require "log"
require "../lib/actions"
require "../lib/types"
require "../lib/models"
require "../lib/version"
module Arkisto
class CtlCli
property config : ConfigModel?
property options : GlobalOptions?
def initialize
# @config = nil
@options = nil
end
def self.parse_options(args) : GlobalOptions
# default values
action = NoneAction
config_file = "arkisto.yml"
verbose = true
dry_run = false
# parse
OptionParser.parse(args) do |parser|
parser.banner = "Usage: #{Version::PROGRAM_ARKISTOCTL} [options] [commands] [arguments]"
parser.separator
parser.separator "Options"
parser.on "-c CONFIG_FILE", "--config=CONFIG_FILE", "Use the following config file" do |file|
config_file = file
end
parser.on "-v", "--verbose", "Be verbose" do
verbose = !verbose
end
parser.on "--dry-run", "Dry run (no real openstack command is executed" do
dry_run = true
end
parser.on "--version", "Show version" do
puts "version #{Version::VERSION}"
exit 0
end
parser.on "-h", "--help", "Show this help" do
puts parser
exit 0
end
parser.on "--completion", "Provide autocompletion for bash" do
# nothing here
end
parser.on "plan", "Display backup plan" do
action = PlanAction
end
parser.on "apply", "Apply backup plan" do
action = ApplyAction
end
parser.separator
parser.missing_option do |flag|
STDERR.puts parser
STDERR.puts "ERROR: #{flag} requires an argument.".colorize(:red)
exit(1)
end
parser.invalid_option do |flag|
STDERR.puts parser
STDERR.puts "ERROR: #{flag} is not a valid option.".colorize(:red)
exit(1)
end
# complete_with Version::PROGRAM_ARKISTOCTL, parser
end
return {
action: action,
config_file: config_file,
dry_run: dry_run,
verbose: verbose,
}.as(GlobalOptions)
end
def self.parse_config(options)
config_file = options[:config_file]
puts "Loading configuration... #{config_file}".colorize(:yellow) if options[:verbose]
if ! File.exists? config_file
STDERR.puts "ERROR: Unable to read configuration file '#{config_file}'".colorize(:red)
exit 1
end
yaml_str = File.read(config_file)
config = ConfigModel.from_yaml(yaml_str)
if config.nil?
STDERR.puts "ERROR: Invalid YAML content in '#{config_file}'"
exit 1
end
return config
end
def self.run(args)
app = CtlCli.new
options = CtlCli.parse_options(args)
config = CtlCli.parse_config(options)
app.options = options
app.config = config
action = ActionFactory.build(
options[:action],
config,
{
dry_run: options[:dry_run],
verbose: options[:verbose]
}
)
action.perform
rescue ex : YAML::ParseException
STDERR.puts "ERROR: #{ex.message}".colorize(:red)
end
end
end
Arkisto::CtlCli.run(ARGV)