Skip to content

Commit

Permalink
Added pipeline resource operations for list, delete and delete-all
Browse files Browse the repository at this point in the history
Signed-off-by: cd-at-iteratec <[email protected]>
  • Loading branch information
cd-at-iteratec committed Mar 18, 2022
1 parent 9ba7028 commit 2042d25
Show file tree
Hide file tree
Showing 11 changed files with 157 additions and 11 deletions.
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
## [1.1.0]
## Added
New pipeline resource parameter : `-r pipeline`.
It is possible to operator: list, delete and delete-all on pipelines
Pipelines require to give a project ID Number with parameter `-i <INT>`
Additional added pipeline ID parameter for delete operation: `--pipelineId <INT>`
## Changed
Round the LastActivity/Finished value from listing projects and pipelines

## [1.0.2]
## Added
Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,22 @@ The CLI is able to list, remove and archive a set of resources.
| Action | Resource | Query filter applicable | Age filter applicable | Status filter applicable | Example |
|---|---|---|---|---|---|
|list|user|YES|-|-| List user with name admin: <br> `gitlab-sanity-cli -o list -r user -q admin`|
|list|project|YES|YES|-| List internal projects older two years: <br> `gitlab-sanity-cli -o list -r project -a 24 -p internal`|
|list|project|YES|YES|-| List internal projects older two years: <br> `gitlab-sanity-cli -o list -r project -a 24 -p public`|
|list|runner|YES|-|YES| List docker based runner: <br> `gitlab-sanity-cli -o list -r runner -q docker`|
|list|groupRunner|YES|-|YES| List online kubernetes based runner: <br> `gitlab-sanity-cli -o list -r groupRunner -q kubernetes -s online` |
|list|pipeline|-|YES|-| List all Pipelines from specific project id: <BR> `gitlab-sanity-cli -o list -r pipeline -i 1337 -a 0` |
|delete|user|-|-|-| <b>Delete is not capable on users</b> |
|delete|project|-|-|-| Remove project with ID 123: <br> `gitlab-sanity-cli -o delete -r project -i 123`|
|delete|runner|-|-|-| Remove runner with ID 123: <br> `gitlab-sanity-cli -o delete -r runner -i 123`|
|delete|groupRunner|-|-|-| Remove runner with ID 123: <br> `gitlab-sanity-cli -o delete -r groupRunner -i 123`|
|delete|pipeline|-|-|-| Remove Pipeline with ID 123 from project: <BR> `gitlab-sanity-cli -o delete -r pipeline -i 1337 --pipelineId 123` |
|delete-all|user|-|-|-|<b>Delete-All is not capable on users</b> |
|delete-all|project|YES|YES|-| Remove all projects with name testing: <br>`gitlab-sanity-cli -o delete-all -r project -a 0 -q testing` <br><br> Remove all projects older than five years: <br> `gitlab-sanity-cli -o delete-all -r project -a 60`|
|delete-all|runner|YES|-|YES| Remove all offline runner: <br>`gitlab-sanity-cli -o delete-all -r runner -s offline`|
|delete-all|groupRunner|YES|-|YES| Remove all groupRunner (offline and online): <br>`gitlab-sanity-cli -o delete-all -r groupRunner` |
|delete-all|pipeline|-|YES|-| Remove all Pipelines from project: <BR> `gitlab-sanity-cli -o delete-all -r pipeline -i 1337` |
|archive|project|-|-|-|Archive project with ID 123:<br>`gitlab-sanity-cli -o archive -r project -i 123`|
|archive-all|project|YES|YES|-|Archive project with name testing:<br>`gitlab-sanity-cli -o archive-all -r project -q testing -a 0 -p private`|

## How to run

### Requirements
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.0.2
1.1.0
18 changes: 17 additions & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
)

const (
version = "1.0.2"
version = "1.1.0"
hoursPerMonth = 30 * 24
newLine = "\r\n"
)
Expand Down Expand Up @@ -63,6 +63,18 @@ func validateParameters(config *gitlabsanitycli.Config) error {
if len(config.ProjectType) < 1 {
config.ProjectType = "internal"
}
switch config.ProjectType {
case "private", "internal", "public":
default:
return errors.New("Project type not valid. Please choose between: public, internal, private")
}

if config.Resource == gitlabsanitycli.Pipeline {
if config.ResourceId <= 0 {
return errors.New("Need project ID to get Pipelines: `-i <number>`")
}
}

return nil
}

Expand All @@ -73,11 +85,13 @@ func newHandlers(git *gitlab.Client, config gitlabsanitycli.Config) map[string]m
userHandler := gitlabsanitycli.UserHandler{Git: git, Printer: printer, Config: &config}
runnerHandler := gitlabsanitycli.RunnerHandler{Git: git, Printer: printer, Config: &config}
groupRunnerHandler := gitlabsanitycli.GroupRunnerHandler{Git: git, Printer: printer, Config: &config}
pipelineHandler := gitlabsanitycli.PipelineHandler{Git: git, Printer: printer, Config: &config}
handlers[gitlabsanitycli.List] = make(map[string]func())
handlers[gitlabsanitycli.List][gitlabsanitycli.Project] = projectHandler.List
handlers[gitlabsanitycli.List][gitlabsanitycli.User] = userHandler.List
handlers[gitlabsanitycli.List][gitlabsanitycli.Runner] = runnerHandler.List
handlers[gitlabsanitycli.List][gitlabsanitycli.GroupRunner] = groupRunnerHandler.List
handlers[gitlabsanitycli.List][gitlabsanitycli.Pipeline] = pipelineHandler.List
handlers[gitlabsanitycli.Archive] = make(map[string]func())
handlers[gitlabsanitycli.Archive][gitlabsanitycli.Project] = projectHandler.Archive
handlers[gitlabsanitycli.ArchiveAll] = make(map[string]func())
Expand All @@ -86,10 +100,12 @@ func newHandlers(git *gitlab.Client, config gitlabsanitycli.Config) map[string]m
handlers[gitlabsanitycli.Delete][gitlabsanitycli.Project] = projectHandler.Delete
handlers[gitlabsanitycli.Delete][gitlabsanitycli.Runner] = runnerHandler.Delete
handlers[gitlabsanitycli.Delete][gitlabsanitycli.GroupRunner] = groupRunnerHandler.Delete
handlers[gitlabsanitycli.Delete][gitlabsanitycli.Pipeline] = pipelineHandler.Delete
handlers[gitlabsanitycli.DeleteAll] = make(map[string]func())
handlers[gitlabsanitycli.DeleteAll][gitlabsanitycli.Project] = projectHandler.DeleteAll
handlers[gitlabsanitycli.DeleteAll][gitlabsanitycli.Runner] = runnerHandler.DeleteAll
handlers[gitlabsanitycli.DeleteAll][gitlabsanitycli.GroupRunner] = groupRunnerHandler.DeleteAll
handlers[gitlabsanitycli.DeleteAll][gitlabsanitycli.Pipeline] = pipelineHandler.DeleteAll
return handlers
}

Expand Down
2 changes: 2 additions & 0 deletions config/stdout.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ Runner ID: {{ .ID}}
ID: {{ .ID }}, Name: {{ .Name }}
{{ else if eq .Req "project" -}}
ID: {{ .ID }}, Name: {{ .Name }}, Last Activity: {{ .LastActivity }} h
{{ else if eq .Req "pipeline" -}}
ID: {{ .ID }}, ProjectID: {{ .ProjectID }}, Status: {{ .Status }}, Finished: {{ .LastActivity }} h ago, Url: {{ .URL }}
{{ end }}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ replace github.com/iteratec/gitlab-sanity-cli/pkg => ./pkg

require (
github.com/voxelbrain/goptions v0.0.0-20180630082107-58cddc247ea2
github.com/xanzy/go-gitlab v0.50.1
github.com/xanzy/go-gitlab v0.59.0
)
11 changes: 7 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=
Expand All @@ -19,8 +21,8 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/voxelbrain/goptions v0.0.0-20180630082107-58cddc247ea2 h1:txplJASvd6b/hrE0s/Ixfpp2cuwH9IO9oZBAN9iYa4A=
github.com/voxelbrain/goptions v0.0.0-20180630082107-58cddc247ea2/go.mod h1:DGCIhurYgnLz8J9ga1fMV/fbLDyUvTyrWXVWUIyJon4=
github.com/xanzy/go-gitlab v0.50.1 h1:eH1G0/ZV1j81rhGrtbcePjbM5Ern7mPA4Xjt+yE+2PQ=
github.com/xanzy/go-gitlab v0.50.1/go.mod h1:Q+hQhV508bDPoBijv7YjK/Lvlb4PhVhJdKqXVQrUoAE=
github.com/xanzy/go-gitlab v0.59.0 h1:fAr6rT/YIdfmBavYgI42+Op7yAAex2Y4xOfvbjN9hxQ=
github.com/xanzy/go-gitlab v0.59.0/go.mod h1:F0QEXwmqiBUxCgJm8fE9S+1veX4XC9Z4cfaAbqwk4YM=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
Expand All @@ -39,6 +41,7 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
Expand Down
4 changes: 3 additions & 1 deletion pkg/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const (
Runner = "runner"
GroupRunner = "groupRunner"
User = "user"
Pipeline = "pipeline"

// GitLab API OK Response Code
gitlabReponseCodeOk = 204
Expand All @@ -34,8 +35,9 @@ type Config struct {
Insecure bool `goptions:"--insecure, description='Skip certificate Verfication for Gitlab API URL, (bool)'"`
Token string `goptions:"-t, --token, description='Gitlab API access token, can also be set via env \"GITLAB_TOKEN\" or file \".token\"'"`
Operation string `goptions:"-o, --operation, description='Operation to start, (list, archive, archive-all, delete, delete-all)', obligatory"`
Resource string `goptions:"-r, --resource, description='Resource to interact with, (project, runner, groupRunner, user)', obligatory"`
Resource string `goptions:"-r, --resource, description='Resource to interact with, (project, runner, groupRunner, user, pipeline)', obligatory"`
ResourceId int `goptions:"-i, --identifier, description='Resource ID to interact with, (int)'"`
PipelineId int `goptions:"--pipelineId, description='Pipeline ID to interact with, (int)'"`
ProjectType string `goptions:"-p, --project-type, description='Type of project (internal, private, public), (default: internal), (string)'"`
Age int `goptions:"-a, --age, description='Filter by last activity in months (not available for runner), (int)'"`
Query string `goptions:"-q, --query, description='Search by name, (string)'"`
Expand Down
2 changes: 2 additions & 0 deletions pkg/content.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@ type content struct {
GroupName string
GroupID int
LastActivity float64
URL string
ProjectID int
}
110 changes: 110 additions & 0 deletions pkg/pipeline.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package gitlabsanitycli

import (
"log"
"math"
"sync"
"time"

"github.com/xanzy/go-gitlab"
)

// PipelineHandler implements AbstractHandler
// implementation for interacting with Gitlab Project Pipelines
type PipelineHandler struct {
Git *gitlab.Client
Printer Printer
Config *Config
ListOptions gitlab.ListProjectPipelinesOptions
}

func (p PipelineHandler) Pipe(wg *sync.WaitGroup, wc chan<- content, rc <-chan int) {
defer wg.Done()
now := time.Now()
for id := range rc {
pipeline, _, err := p.Git.Pipelines.GetPipeline(p.Config.ResourceId, id)
if err != nil {
log.Fatal(err)
}
if pipeline.FinishedAt == nil {
log.Printf("Unable to fetch data for Pipeline ID: %v, URL: %v", pipeline.ID, pipeline.WebURL)
} else {
// Age filter
if now.Sub(*pipeline.FinishedAt).Hours() > float64(p.Config.Age) {
wc <- content{
Req: Pipeline,
ID: pipeline.ID,
Status: pipeline.Status,
URL: pipeline.WebURL,
ProjectID: pipeline.ProjectID,
LastActivity: math.Round(now.Sub(*pipeline.FinishedAt).Hours()),
}
}
}
}
}

func (p PipelineHandler) ApiCallFunc(page int) ([]int, *gitlab.Response, error) {
p.ListOptions.Page = page

values, resp, err := p.Git.Pipelines.ListProjectPipelines(p.Config.ResourceId, &p.ListOptions)

var xIds []int
for _, value := range values {
xIds = append(xIds, value.ID)
}
return xIds, resp, err
}

func (p PipelineHandler) Controller(channelHandlerFunc ChannelHandlerFunc) {
p.ListOptions = gitlab.ListProjectPipelinesOptions{
Sort: gitlab.String("desc"),
ListOptions: gitlab.ListOptions{PerPage: PageSize},
}

_, resp, err := p.Git.Pipelines.ListProjectPipelines(p.Config.ResourceId, &p.ListOptions)

if err != nil {
log.Fatal(err)
}

genericHandler(p, channelHandlerFunc, resp.TotalPages)

}

func (p PipelineHandler) deletePipeline(pipelineId int, dryRun bool) {
project, _, err0 := p.Git.Projects.GetProject(p.Config.ResourceId, nil)
if err0 != nil {
log.Fatal(err0)
}
log.Printf("Deleting Pipeline %v in Project: %v\n", pipelineId, project.Name)
if !dryRun {
_, err1 := p.Git.Pipelines.DeletePipeline(project.ID, pipelineId)
if err1 != nil {
log.Fatal(err1)
}
log.Printf("Pipeline %v deleted \n", pipelineId)
} else {
log.Printf("[DryRun] Pipeline %v was not deleted\n", pipelineId)
}
}

func (p PipelineHandler) deleteAllPipeline(Pipeline <-chan content) {
go func() {
for pipeline := range Pipeline {
p.deletePipeline(pipeline.ID, p.Config.DryRun)
}
}()
}

func (p PipelineHandler) List() {
Run(p, p.Printer.Print)
}

func (p PipelineHandler) Delete() {
p.deletePipeline(p.Config.ResourceId, p.Config.DryRun)
}

func (p PipelineHandler) DeleteAll() {
Run(p, p.deleteAllPipeline)
}
3 changes: 2 additions & 1 deletion pkg/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package gitlabsanitycli

import (
"log"
"math"
"sync"
"time"

Expand Down Expand Up @@ -31,7 +32,7 @@ func (p ProjectHandler) Pipe(wg *sync.WaitGroup, wc chan<- content, rc <-chan in
Req: Project,
ID: project.ID,
Name: project.Name,
LastActivity: now.Sub(*project.LastActivityAt).Hours(),
LastActivity: math.Round(now.Sub(*project.LastActivityAt).Hours()),
}
}
}
Expand Down

0 comments on commit 2042d25

Please sign in to comment.