Skip to content

Commit 242a8ad

Browse files
committed
Merge remote-tracking branch 'origin/dev'
2 parents 6a90df7 + de5404b commit 242a8ad

File tree

12 files changed

+380
-26
lines changed

12 files changed

+380
-26
lines changed

README.md

Lines changed: 163 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
- [Create API Key](#create-api-key)
6565
- [Regenerate API Key](#regenerate-api-key)
6666
- [Get API Key](#get-api-key)
67+
- [Creating and Updating Multiple Repositories](#creating-and-updating-multiple-repositories)
6768
- [Creating and Updating Local Repository](#creating-and-updating-local-repository)
6869
- [Creating and Updating Remote Repository](#creating-and-updating-remote-repository)
6970
- [Creating and Updating Virtual Repository](#creating-and-updating-virtual-repository)
@@ -80,6 +81,7 @@
8081
- [Creating and Updating Permission Targets](#creating-and-updating-permission-targets)
8182
- [Removing a Permission Target](#removing-a-permission-target)
8283
- [Fetching a Permission Target](#fetching-a-permission-target)
84+
- [Fetching All Permission Targets](#fetching-all-permission-targets)
8385
- [Fetching Artifactory's Version](#fetching-artifactorys-version)
8486
- [Fetching Running Artifactory Nodes in a Cluster](#fetching-running-artifactory-nodes-in-a-cluster)
8587
- [Fetching Artifactory's Service ID](#fetching-artifactorys-service-id)
@@ -1081,6 +1083,150 @@ Updating federated Generic repository:
10811083
err = servicesManager.UpdateFederatedRepository().Generic(params)
10821084
```
10831085

1086+
#### Creating and Updating Multiple Repositories
1087+
1088+
NOTE:
1089+
- Creating of multiple repositories is supported from Artifactory 7.84.3 and later versions.
1090+
- Updating of multiple repositories is supported from Artifactory 7.104.2 and later versions.
1091+
1092+
You can create and update multiple repositories in a single batch operation using the `CreateUpdateRepositoriesInBatch` method. This method accepts a JSON byte array containing repository configurations and can handle mixed repository and package types within the same request.
1093+
1094+
****Creating Multiple Repositories:****
1095+
1096+
```go
1097+
// Define repository configurations as JSON array
1098+
repositoriesConfig := `[
1099+
{
1100+
"key": "maven-local-repo",
1101+
"rclass": "local",
1102+
"packageType": "maven",
1103+
"description": "Local Maven repository",
1104+
"repoLayoutRef": "maven-2-default"
1105+
},
1106+
{
1107+
"key": "npm-remote-repo",
1108+
"rclass": "remote",
1109+
"packageType": "npm",
1110+
"description": "Remote NPM repository",
1111+
"url": "https://registry.npmjs.org/",
1112+
"repoLayoutRef": "npm-default"
1113+
}
1114+
]`
1115+
1116+
// Create multiple repositories (isUpdate = false)
1117+
err = rtManager.CreateUpdateRepositoriesInBatch([]byte(repositoriesConfig), false)
1118+
if err != nil {
1119+
return err
1120+
}
1121+
```
1122+
1123+
**Updating Multiple Repositories:**
1124+
1125+
```go
1126+
// Define update configurations as JSON
1127+
updateConfig := `[
1128+
{
1129+
"key": "maven-local-repo",
1130+
"description": "Updated Maven local repository description",
1131+
"notes": "Updated internal notes"
1132+
},
1133+
{
1134+
"key": "npm-remote-repo",
1135+
"description": "Updated NPM remote repository",
1136+
"retrievalCachePeriodSecs": 7200
1137+
}
1138+
]`
1139+
1140+
// Update multiple repositories (isUpdate = true)
1141+
err = rtManager.CreateUpdateRepositoriesInBatch([]byte(updateConfig), true)
1142+
if err != nil {
1143+
return err
1144+
}
1145+
```
1146+
1147+
**Configurations with mixed repository and package types:**
1148+
1149+
```go
1150+
// configuration with different repository and package types
1151+
config := `[
1152+
{
1153+
"key": "maven-local-prod",
1154+
"rclass": "local",
1155+
"packageType": "maven",
1156+
"description": "Production Maven artifacts",
1157+
"repoLayoutRef": "maven-2-default",
1158+
"archiveBrowsingEnabled": true,
1159+
"xrayIndex": true,
1160+
"includesPattern": "**/*",
1161+
"excludesPattern": "com/example/test/**"
1162+
},
1163+
{
1164+
"key": "npm-remote-proxy",
1165+
"rclass": "remote",
1166+
"packageType": "npm",
1167+
"description": "NPM remote proxy",
1168+
"url": "https://registry.npmjs.org/",
1169+
"repoLayoutRef": "npm-default",
1170+
"retrievalCachePeriodSecs": 3600,
1171+
"assumedOfflinePeriodSecs": 300,
1172+
"missedRetrievalCachePeriodSecs": 1800
1173+
},
1174+
{
1175+
"key": "docker-virtual-all",
1176+
"rclass": "virtual",
1177+
"packageType": "docker",
1178+
"description": "All Docker repositories",
1179+
"repositories": ["docker-local-prod", "docker-remote-proxy"],
1180+
"repoLayoutRef": "simple-default",
1181+
"defaultDeploymentRepo": "docker-local-prod",
1182+
"artifactoryRequestsCanRetrieveRemoteArtifacts": true
1183+
},
1184+
{
1185+
"key": "maven-federated-shared",
1186+
"rclass": "federated",
1187+
"packageType": "maven",
1188+
"description": "Federated Maven repository",
1189+
"repoLayoutRef": "maven-2-default",
1190+
"members": [
1191+
{
1192+
"url": "http://artifactory2.company.com/artifactory/maven-federated-shared",
1193+
"enabled": true
1194+
},
1195+
{
1196+
"url": "http://artifactory3.company.com/artifactory/maven-federated-shared",
1197+
"enabled": true
1198+
}
1199+
]
1200+
}
1201+
]`
1202+
1203+
// Create all repositories in a single batch operation
1204+
err = rtManager.CreateUpdateRepositoriesInBatch([]byte(config), false)
1205+
if err != nil {
1206+
return err
1207+
}
1208+
```
1209+
1210+
**Supported Repository Classes:**
1211+
- `local` - Local repositories for storing artifacts
1212+
- `remote` - Remote repositories for proxying external repositories
1213+
- `virtual` - Virtual repositories for aggregating multiple repositories
1214+
- `federated` - Federated repositories for cross-instance synchronization
1215+
1216+
**Supported Package Types:**
1217+
Alpine, Bower, Cran, Cargo, Chef, Cocoapods, Composer, Conan, Conda, Debian, Docker, Gems, Generic, Gitlfs, Go, Gradle, Helm, Ivy, Maven, Npm, Nuget, Opkg, P2, Puppet, Pypi, Rpm, Sbt, Swift, Terraform, Vcs, Vagrant, and Yum.
1218+
1219+
**Method Parameters:**
1220+
- `body []byte` - JSON byte array containing repository configurations
1221+
- `isUpdate bool` - Set to `false` for creating repositories, `true` for updating existing repositories
1222+
1223+
**HTTP Details:**
1224+
- **Endpoint**: `/artifactory/api/v2/repositories/batch`
1225+
- **HTTP Method**: `PUT` for create operations, `POST` for update operations
1226+
- **Content-Type**: `application/json`
1227+
- **Authentication**: Requires admin privileges or appropriate repository permissions
1228+
- **Response**: Returns HTTP 201 for successful creation, HTTP 200 for successful updates
1229+
10841230
#### Removing a Repository
10851231

10861232
You can remove a repository from Artifactory using its key:
@@ -1278,6 +1424,12 @@ permissionTargetParams, err = servicesManager.GetPermissionTarget("java-develope
12781424
If the requested permission target does not exist, a nil value is returned for the _permissionTargetParams_ param, with
12791425
a nil error value
12801426

1427+
#### Fetching all Permission Targets
1428+
1429+
```go
1430+
permissions, err = servicesManager.GetAllPermissionTargets()
1431+
```
1432+
12811433
#### Fetching Artifactory's Version
12821434

12831435
```go
@@ -3081,17 +3233,23 @@ resp, err := serviceManager.DeleteReleaseBundleVersionPromotion(rbDetails, query
30813233
#### Remote Delete Release Bundle
30823234
30833235
```go
3236+
rbDetails := ReleaseBundleDetails{"rbName", "rbVersion"}
3237+
30843238
rules := &distribution.DistributionCommonParams{
3085-
SiteName: "*",
3086-
CityName: "*",
3087-
CountryCodes: []string{"*"},
3239+
SiteName: "*",
3240+
CityName: "*",
3241+
CountryCodes: []string{"*"},
30883242
}
30893243
params := distribution.NewDistributeReleaseBundleParams("rbName", "rbVersion")
30903244
params.DistributionRules = append(params.DistributionRules, rules)
30913245

3092-
dryRun := true
3246+
queryParams := CommonOptionalQueryParams{}
3247+
queryParams.ProjectKey = "project"
3248+
queryParams.Async = true
30933249

3094-
resp, err := serviceManager.RemoteDeleteReleaseBundle(params, dryRun)
3250+
isNewReleaseBundleApiSupported=true
3251+
//From 7.63.2, isNewReleaseBundleApiSupported is true, below that version it should be false.
3252+
resp, err := serviceManager.RemoteDeleteReleaseBundle(rbDetails, params, isNewReleaseBundleApiSupported)
30953253
```
30963254
30973255
#### check-rb-exists

artifactory/emptymanager.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
)
1818

1919
type ArtifactoryServicesManager interface {
20+
CreateUpdateRepositoriesInBatch(body []byte, isUpdate bool) error
2021
CreateLocalRepository() *services.LocalRepositoryService
2122
CreateLocalRepositoryWithParams(params services.LocalRepositoryBaseParams) error
2223
CreateRemoteRepository() *services.RemoteRepositoryService
@@ -117,6 +118,10 @@ type ArtifactoryServicesManager interface {
117118
type EmptyArtifactoryServicesManager struct {
118119
}
119120

121+
func (esm *EmptyArtifactoryServicesManager) CreateUpdateRepositoriesInBatch(_ []byte, _ bool) error {
122+
panic("Failed: Method is not implemented")
123+
}
124+
120125
func (esm *EmptyArtifactoryServicesManager) CreateLocalRepository() *services.LocalRepositoryService {
121126
panic("Failed: Method is not implemented")
122127
}

artifactory/manager.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ func NewWithClient(config config.Config, client *jfroghttpclient.JfrogHttpClient
5454
return manager, nil
5555
}
5656

57+
func (sm *ArtifactoryServicesManagerImp) CreateUpdateRepositoriesInBatch(body []byte, isUpdate bool) error {
58+
repositoryService := services.NewBatchRepositoryService(sm.client, isUpdate)
59+
repositoryService.ArtDetails = sm.config.GetServiceDetails()
60+
return repositoryService.PerformBatchRequest(body)
61+
}
62+
5763
func (sm *ArtifactoryServicesManagerImp) CreateLocalRepository() *services.LocalRepositoryService {
5864
repositoryService := services.NewLocalRepositoryService(sm.client, false)
5965
repositoryService.ArtDetails = sm.config.GetServiceDetails()
@@ -198,6 +204,12 @@ func (sm *ArtifactoryServicesManagerImp) GetPermissionTarget(permissionTargetNam
198204
return permissionTargetService.Get(permissionTargetName)
199205
}
200206

207+
func (sm *ArtifactoryServicesManagerImp) GetAllPermissionTargets() (*[]services.PermissionTargetParams, error) {
208+
permissionTargetService := services.NewPermissionTargetService(sm.client)
209+
permissionTargetService.ArtDetails = sm.config.GetServiceDetails()
210+
return permissionTargetService.GetAll()
211+
}
212+
201213
func (sm *ArtifactoryServicesManagerImp) PublishBuildInfo(build *buildinfo.BuildInfo, projectKey string) (*clientutils.Sha256Summary, error) {
202214
buildInfoService := services.NewBuildInfoService(sm.config.GetServiceDetails(), sm.client)
203215
buildInfoService.DryRun = sm.config.IsDryRun()
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package services
2+
3+
import (
4+
"net/http"
5+
6+
"github.com/jfrog/jfrog-client-go/http/jfroghttpclient"
7+
"github.com/jfrog/jfrog-client-go/utils/errorutils"
8+
)
9+
10+
const batchApi = "api/v2/repositories/batch"
11+
12+
type BatchRepositoryService struct {
13+
RepositoryService
14+
}
15+
16+
func NewBatchRepositoryService(client *jfroghttpclient.JfrogHttpClient, isUpdate bool) *BatchRepositoryService {
17+
return &BatchRepositoryService{
18+
RepositoryService: RepositoryService{
19+
client: client,
20+
isUpdate: isUpdate,
21+
},
22+
}
23+
}
24+
25+
func (brs *BatchRepositoryService) PerformBatchRequest(content []byte) (err error) {
26+
httpClientsDetails := brs.ArtDetails.CreateHttpClientDetails()
27+
httpClientsDetails.SetContentTypeApplicationJson()
28+
29+
url := brs.ArtDetails.GetUrl() + batchApi
30+
var (
31+
resp *http.Response
32+
body []byte
33+
)
34+
35+
if brs.isUpdate {
36+
resp, body, err = brs.client.SendPost(url, content, &httpClientsDetails)
37+
} else {
38+
resp, body, err = brs.client.SendPut(url, content, &httpClientsDetails)
39+
}
40+
41+
if err != nil {
42+
return err
43+
}
44+
expectedStatusCode := http.StatusCreated
45+
if brs.isUpdate {
46+
expectedStatusCode = http.StatusOK
47+
}
48+
49+
err = errorutils.CheckResponseStatusWithBody(resp, body, expectedStatusCode)
50+
if err != nil {
51+
return err
52+
}
53+
return
54+
}

artifactory/services/permissiontarget.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,24 @@ func (pts *PermissionTargetService) Get(permissionTargetName string) (*Permissio
6262
return permissionTarget, nil
6363
}
6464

65+
func (pts *PermissionTargetService) GetAll() (*[]PermissionTargetParams, error) {
66+
httpClientsDetails := pts.ArtDetails.CreateHttpClientDetails()
67+
log.Info("Getting all permission target ...")
68+
resp, body, _, err := pts.client.SendGet(pts.ArtDetails.GetUrl()+"api/v2/security/permissions", true, &httpClientsDetails)
69+
if err != nil {
70+
return nil, err
71+
}
72+
if err = errorutils.CheckResponseStatusWithBody(resp, body, http.StatusOK); err != nil {
73+
return nil, err
74+
}
75+
76+
permissionTargets := &[]PermissionTargetParams{}
77+
if err := json.Unmarshal(body, &permissionTargets); err != nil {
78+
return nil, err
79+
}
80+
return permissionTargets, nil
81+
}
82+
6583
func (pts *PermissionTargetService) Create(params PermissionTargetParams) error {
6684
return pts.performRequest(params, false)
6785
}
@@ -116,6 +134,7 @@ type PermissionTargetParams struct {
116134
Repo *PermissionTargetSection `json:"repo,omitempty"`
117135
Build *PermissionTargetSection `json:"build,omitempty"`
118136
ReleaseBundle *PermissionTargetSection `json:"releaseBundle,omitempty"`
137+
Uri *PermissionTargetSection `json:"uri"`
119138
}
120139

121140
type PermissionTargetSection struct {

0 commit comments

Comments
 (0)