1
+ #!/usr/bin/env python
2
+
3
+ '''
4
+ Copyright (C) 2023 Synopsys, Inc.
5
+ http://www.blackducksoftware.com/
6
+
7
+ Licensed to the Apache Software Foundation (ASF) under one
8
+ or more contributor license agreements. See the NOTICE file
9
+ distributed with this work for additional information
10
+ regarding copyright ownership. The ASF licenses this file
11
+ to you under the Apache License, Version 2.0 (the
12
+ "License"); you may not use this file except in compliance
13
+ with the License. You may obtain a copy of the License at
14
+
15
+ http://www.apache.org/licenses/LICENSE-2.0
16
+
17
+ Unless required by applicable law or agreed to in writing,
18
+ software distributed under the License is distributed on an
19
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
20
+ KIND, either express or implied. See the License for the
21
+ specific language governing permissions and limitations
22
+ under the License.
23
+
24
+ usage: Get all the users [-h] -u BASE_URL -t TOKEN_FILE [-nv] -pn PROJECT_NAME [-mv MAX_VERSIONS] [--dry-run]
25
+
26
+ options:
27
+ -h, --help show this help message and exit
28
+ -u BASE_URL, --base-url BASE_URL
29
+ Hub server URL e.g. https://your.blackduck.url
30
+ -t TOKEN_FILE, --token-file TOKEN_FILE
31
+ containing access token
32
+ -nv, --no-verify disable TLS certificate verification
33
+ -pn PROJECT_NAME, --project-name PROJECT_NAME
34
+ Project name to be processed
35
+ -mv MAX_VERSIONS, --max-versions MAX_VERSIONS
36
+ Max versions to allow
37
+ --dry-run Dry run, do not delete
38
+
39
+ '''
40
+ import argparse
41
+ import json
42
+ import logging
43
+ import sys
44
+ import arrow
45
+
46
+ from blackduck import Client
47
+ from pprint import pprint
48
+
49
+ parser = argparse .ArgumentParser ("Get all the users" )
50
+ parser .add_argument ("-u" , "--base-url" , required = True , help = "Hub server URL e.g. https://your.blackduck.url" )
51
+ parser .add_argument ("-t" , "--token-file" , dest = 'token_file' , required = True , help = "containing access token" )
52
+ parser .add_argument ("-nv" , "--no-verify" , dest = 'verify' , action = 'store_false' , help = "disable TLS certificate verification" )
53
+ parser .add_argument ("-pn" , "--project-name" , dest = 'project_name' , required = True , help = 'Project name to be processed' )
54
+ parser .add_argument ("-mv" , "--max-versions" , default = 10 , type = int , dest = "max_versions" , help = "Max versions to allow" )
55
+ parser .add_argument ("--dry-run" , dest = 'dry_run' , action = 'store_true' , help = "Dry run, do not delete" )
56
+ args = parser .parse_args ()
57
+
58
+
59
+ logging .basicConfig (format = '%(asctime)s:%(levelname)s:%(message)s' , stream = sys .stderr , level = logging .DEBUG )
60
+ logging .getLogger ("requests" ).setLevel (logging .WARNING )
61
+ logging .getLogger ("urllib3" ).setLevel (logging .WARNING )
62
+ logging .getLogger ("blackduck" ).setLevel (logging .WARNING )
63
+
64
+ with open (args .token_file , 'r' ) as tf :
65
+ access_token = tf .readline ().strip ()
66
+
67
+ bd = Client (
68
+ base_url = args .base_url ,
69
+ token = access_token ,
70
+ verify = args .verify
71
+ )
72
+
73
+ # Locate project of interest
74
+
75
+ params = {
76
+ 'q' : [f"name:{ args .project_name } " ]
77
+ }
78
+ projects = bd .get_resource ('projects' , params = params , items = False )
79
+ num_projects = len (projects ['items' ])
80
+ if not num_projects == 1 :
81
+ logging .info (f"Project name { args .project_name } is not specific enough to identify a single project" )
82
+ sys .exit (1 )
83
+
84
+ # Analyze versions
85
+
86
+ versions = bd .get_resource ('versions' , projects ['items' ][0 ], items = False )
87
+ num_versions = len (versions ['items' ])
88
+ if (num_versions < args .max_versions ):
89
+ logging .info (f"Number of versions { num_versions } is less than maximum { args .max_versions } , No deletion necessary" )
90
+ sys .exit ()
91
+ else :
92
+ num_versions_to_delete = num_versions - args .max_versions + 1
93
+ logging .info (f"Found { num_versions } which is greater or equal to maximum allowed: { args .max_versions } " )
94
+ logging .info (f"Have to delete { num_versions_to_delete } project version(s)" )
95
+ sorted_version_list = sorted (versions ['items' ], key = lambda s : arrow .get (s ['createdAt' ]))
96
+ logging .info ("List of versions in chronological order" )
97
+ for version in sorted_version_list :
98
+ logging .info (f"Version { version ['versionName' ]} created at { version ['createdAt' ]} " )
99
+ versions_to_delete = sorted_version_list [- num_versions_to_delete :]
100
+ logging .info ("List of versions to delete" )
101
+ for version in versions_to_delete :
102
+ logging .info (f"Version { version ['versionName' ]} created at { version ['createdAt' ]} " )
103
+ version_url = version ['_meta' ]['href' ]
104
+ logging .info (f"Version URL { version_url } " )
105
+ if not args .dry_run :
106
+ # Deleting older versions
107
+ logging .info (f"Deleting { version ['versionName' ]} created at { version ['createdAt' ]} " )
108
+ result = bd .session .delete (version_url )
109
+ logging .info (f"Delete request completed with { result } " )
0 commit comments