Commit ae2574a5 authored by Bas Couwenberg's avatar Bas Couwenberg

Add script to delete pipelines.

parent e13aff3b
#!/usr/bin/perl -w
#
# Copyright 2018-2019, Bas Couwenberg <sebastic@debian.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
use strict;
use Data::Dumper;
use File::Basename;
use Getopt::Long qw(:config bundling no_ignore_case);
use HTTP::Request::Common;
use JSON;
use LWP::UserAgent;
use URI::Escape;
$|=1;
my %cfg = (
url => 'https://salsa.debian.org/api/v4',
token => '',
token_file => $ENV{HOME}.'/.salsa-token',
namespace => '2052',
user => '',
group => 'debian-gis-team',
project => '',
debug => 0,
verbose => 0,
help => 0,
);
my $result = GetOptions(
'u|url=s' => \$cfg{url},
'n|namespace=i' => \$cfg{namespace},
'U|user=s' => \$cfg{user},
'G|group=s' => \$cfg{group},
't|token=s' => \$cfg{token},
'p|project=s' => \$cfg{project},
'd|debug' => \$cfg{debug},
'v|verbose' => \$cfg{verbose},
'h|help' => \$cfg{help},
);
if(!$result || $cfg{help} || !$cfg{project}) {
print STDERR "\n" if(!$result);
print "Usage: ". basename($0) ." [OPTIONS]\n\n";
print "Options:\n";
print "-u, --url <URL> Salsa URL ($cfg{url})\n";
print "-t, --token <STRING> Salsa token (". '*' x length($cfg{token}) .")\n";
print "-T, --token-file <PATH> Salsa token file ($cfg{token_file})\n";
print "\n";
print "-n, --namespace <ID> Salsa namespace ($cfg{namespace})\n";
print "-U, --user <NAME> Salsa user path ($cfg{user})\n";
print "-G, --group <NAME> Salsa group path ($cfg{group})\n";
print "\n";
print "-p, --project <NAME> Project name\n";
print "\n";
print "-d, --debug Enable debug output\n";
print "-v, --verbose Enable verbose output\n";
print "-h, --help Display this usage information\n";
exit 1;
}
my $ua = new LWP::UserAgent(agent => basename($0));
$cfg{token} = get_private_token() if(!$cfg{token});
if(!$cfg{token}) {
print "Error: No private token specified with file nor option!\n";
exit 1;
}
$cfg{namespace} = get_namespace() if(!$cfg{namespace});
if(!$cfg{namespace}) {
print "Error: No namespace found! Specify namespace, user or group!\n";
exit 1;
}
# Get projects for team
my $team_projects = get_team_projects();
print "team projects:\n".Dumper($team_projects) if($cfg{debug});
# Get service settings
foreach my $project (@{$team_projects}) {
if($project->{name} eq $cfg{project} || $project->{id} eq $cfg{project}) {
print "\nProject: ". $project->{name} ." (". $project->{id} .")\n" if($cfg{verbose});
my $pipelines = get_project_pipelines($project);
print "pipelines:\n".Dumper($pipelines);
foreach my $pipeline (@{$pipelines}) {
delete_project_pipeline($project, $pipeline);
}
}
}
exit 0;
################################################################################
# Subroutines
sub get_private_token {
my $token = '';
if(!$cfg{token_file}) {
print "No private token file to check.\n" if($cfg{verbose});
return $token;
}
print "Checking file for private token: $cfg{token_file}\n" if($cfg{debug});
if(-r $cfg{token_file}) {
my $mode = sprintf("%o", (stat($cfg{token_file}))[2] & 07777);
if($mode != 600) {
print "Warning: Permissions on $cfg{token_file} are not 600 (-rw-------)\n";
}
print "Loading private token from: $cfg{token_file} ($mode)\n" if($cfg{debug});
open(F, $cfg{token_file}) || die "Error: Failed to open file: $cfg{token_file} ($!)";
while(<F>) {
next if(/^\s*#|^\s*$/);
if(/^(\S{10,})\s*/) {
$token = $1;
last;
}
}
close F;
}
else {
print "File not readable: $cfg{token_file}\n" if($cfg{debug});
}
return $token;
}
sub get_namespace {
my $url = $cfg{url}.'/namespaces';
print "Getting namespaces\n" if($cfg{verbose});
my $req = new HTTP::Request(GET => $url);
$req->header('PRIVATE-TOKEN' => $cfg{token});
my $res = $ua->request($req);
if($res->is_success) {
my $content = $res->content;
my $data = decode_json($content);
print "namespaces:\n".Dumper($data) if($cfg{debug});
my $namespace = '';
foreach my $ns (@{$data}) {
if($cfg{user} && $ns->{kind} eq 'user' && $ns->{path} eq $cfg{user}) {
print "Found namespace: ". $ns->{id} ." for user: $cfg{user}\n" if($cfg{verbose});
$namespace = $ns->{id};
last;
}
elsif($cfg{group} && $ns->{kind} eq 'group' && $ns->{path} eq $cfg{group}) {
print "Found namespace: ". $ns->{id} ." for group: $cfg{group}\n" if($cfg{verbose});
$namespace = $ns->{id};
last;
}
}
return $namespace;
}
else {
print "Error: Request failed! ($url)\n";
print "HTTP Status: ".$res->code." ".$res->message."\n";
print $res->content if($res->content);
exit 1;
}
}
sub get_team_projects {
my ($projects, $page) = @_;
$projects = [] if(!$projects);
$page = 1 if(!$page);
my $url = $cfg{url}.'/groups/'.uri_escape($cfg{namespace}).'/projects';
$url .= '?order_by=name';
$url .= '&sort=asc';
$url .= '&page='.uri_escape($page);
$url .= '&per_page=100';
print "Getting projects for namespace: $cfg{namespace} (page: $page)\n" if($cfg{verbose});
my $req = new HTTP::Request(GET => $url);
$req->header('PRIVATE-TOKEN' => $cfg{token});
my $res = $ua->request($req);
if($res->is_success) {
my $content = $res->content;
my $data = decode_json($content);
foreach my $project (@{$data}) {
push @{$projects}, $project;
}
my $next_page = $res->header('X-Next-Page');
if($next_page && $next_page ne $page) {
$projects = get_team_projects($projects, $next_page);
}
return $projects;
}
else {
print "Error: Request failed! ($url)\n";
print "HTTP Status: ".$res->code." ".$res->message."\n";
print $res->content if($res->content);
exit 1;
}
}
sub get_project_pipelines {
my ($project) = @_;
my $url = $cfg{url}.'/projects/'. $project->{id} .'/pipelines';
print "Getting pipelines for project: ". $project->{name} ."\n" if($cfg{verbose});
my $req = new HTTP::Request(GET => $url);
$req->header('PRIVATE-TOKEN' => $cfg{token});
my $res = $ua->request($req);
if($res->is_success) {
my $content = $res->content;
my $data = decode_json($content);
return $data;
}
else {
print "Error: Request failed! ($url)\n";
print "HTTP Status: ".$res->code." ".$res->message."\n";
print $res->content if($res->content);
exit 1;
}
}
sub delete_project_pipeline {
my ($project, $pipeline) = @_;
my $url = $cfg{url}.'/projects/'. $project->{id} .'/pipelines/'. $pipeline->{id};
my $req = new HTTP::Request(DELETE => $url);
$req->header('PRIVATE-TOKEN' => $cfg{token});
my $res = $ua->request($req);
if(!$res->is_success) {
print "Error: Request failed! ($url)\n";
print "HTTP Status: ".$res->code." ".$res->message."\n";
print $res->content if($res->content);
exit 1;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment