mirror of
https://github.com/goharbor/harbor.git
synced 2025-02-22 14:52:17 +01:00
Merge remote-tracking branch 'upstream/master' into batchDelection
This commit is contained in:
commit
5e14601d2e
@ -17,9 +17,25 @@ In addition, the deployment instructions on Kubernetes has been created by the c
|
||||
|
||||
## Prerequisites for the target host
|
||||
Harbor is deployed as several Docker containers, and, therefore, can be deployed on any Linux distribution that supports Docker. The target host requires Python, Docker, and Docker Compose to be installed.
|
||||
* Python should be version 2.7 or higher. Note that you may have to install Python on Linux distributions (Gentoo, Arch) that do not come with a Python interpreter installed by default
|
||||
* Docker engine should be version 1.10 or higher. For installation instructions, please refer to: https://docs.docker.com/engine/installation/
|
||||
* Docker Compose needs to be version 1.6.0 or higher. For installation instructions, please refer to: https://docs.docker.com/compose/install/
|
||||
### Hardware
|
||||
|Resource|Capacity|Description|
|
||||
|---|---|---|
|
||||
|CPU|minimal 2 CPU|4 CPU is prefered|
|
||||
|Mem|minimal 4GB|8GB is prefered|
|
||||
|Disk|minimal 40GB|160GB is prefered|
|
||||
### Software
|
||||
|Software|Version|Description|
|
||||
|---|---|---|
|
||||
|Python|version 2.7 or higher|Note that you may have to install Python on Linux distributions (Gentoo, Arch) that do not come with a Python interpreter installed by default|
|
||||
|Docker engine|version 1.10 or higher|For installation instructions, please refer to: https://docs.docker.com/engine/installation/|
|
||||
|Docker Compose|version 1.6.0 or higher|For installation instructions, please refer to: https://docs.docker.com/compose/install/|
|
||||
|Openssl|latest is prefered|Generate certificate and keys for Harbor|
|
||||
### Network ports
|
||||
|Port|Protocol|Description|
|
||||
|---|---|---|
|
||||
|443|HTTPS|Harbor UI and API will accept requests on this port for https protocol|
|
||||
|4443|HTTS|Connections to the Docker Content Trust service for Harbor, only needed when Notary is enabled|
|
||||
|80|HTTP|Harbor UI and API will accept requests on this port for http protocol|
|
||||
|
||||
## Installation Steps
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "harbor-ui",
|
||||
"version": "0.6.30",
|
||||
"version": "0.6.41",
|
||||
"description": "Harbor shared UI components based on Clarity and Angular4",
|
||||
"scripts": {
|
||||
"start": "ng serve --host 0.0.0.0 --port 4500 --proxy-config proxy.config.json",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "harbor-ui",
|
||||
"version": "0.6.30",
|
||||
"version": "0.6.41",
|
||||
"description": "Harbor shared UI components based on Clarity and Angular4",
|
||||
"author": "VMware",
|
||||
"module": "index.js",
|
||||
|
@ -0,0 +1,2 @@
|
||||
export const LIST_REPLICATION_RULE_CSS = `
|
||||
`
|
@ -18,7 +18,15 @@ export const LIST_REPLICATION_RULE_TEMPLATE: string = `
|
||||
<clr-dg-cell *ngIf="!projectScope">
|
||||
<a href="javascript:void(0)" (click)="redirectTo(p)">{{p.projects?.length>0 ? p.projects[0].name : ''}}</a>
|
||||
</clr-dg-cell>
|
||||
<clr-dg-cell>{{p.description ? p.description : '-'}}</clr-dg-cell>
|
||||
<clr-dg-cell>
|
||||
{{p.description ? trancatedDescription(p.description) : '-'}}
|
||||
<clr-tooltip>
|
||||
<clr-icon *ngIf="p.description && p.description.length > 35" clrTooltipTrigger shape="ellipsis-horizontal" size="18"></clr-icon>
|
||||
<clr-tooltip-content clrPosition="bottom-right" clrSize="md" *clrIfOpen>
|
||||
<span>{{p.description}}</span>
|
||||
</clr-tooltip-content>
|
||||
</clr-tooltip>
|
||||
</clr-dg-cell>
|
||||
<clr-dg-cell>{{p.targets?.length>0 ? p.targets[0].name : ''}}</clr-dg-cell>
|
||||
<clr-dg-cell>{{p.trigger ? p.trigger.kind : ''}}</clr-dg-cell>
|
||||
</clr-dg-row>
|
||||
|
@ -42,12 +42,14 @@ import { toPromise, CustomComparator } from '../utils';
|
||||
import { State, Comparator } from 'clarity-angular';
|
||||
|
||||
import { LIST_REPLICATION_RULE_TEMPLATE } from './list-replication-rule.component.html';
|
||||
import { LIST_REPLICATION_RULE_CSS } from './list-replication-rule.component.css';
|
||||
import {BatchInfo, BathInfoChanges} from "../confirmation-dialog/confirmation-batch-message";
|
||||
import {Observable} from "rxjs/Observable";
|
||||
|
||||
@Component({
|
||||
selector: 'hbr-list-replication-rule',
|
||||
template: LIST_REPLICATION_RULE_TEMPLATE,
|
||||
styles: [LIST_REPLICATION_RULE_CSS],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class ListReplicationRuleComponent implements OnInit, OnChanges {
|
||||
@ -102,6 +104,14 @@ export class ListReplicationRuleComponent implements OnInit, OnChanges {
|
||||
return !this.readonly && !this.projectId ? true : false;
|
||||
}
|
||||
|
||||
trancatedDescription(desc: string): string {
|
||||
if (desc.length > 35 ) {
|
||||
return desc.substr(0, 35);
|
||||
} else {
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
//Global scope
|
||||
if (!this.projectScope) {
|
||||
|
@ -24,11 +24,9 @@ export const TAG_TEMPLATE = `
|
||||
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
|
||||
<clr-datagrid [clrDgLoading]="loading" [class.embeded-datagrid]="isEmbedded" [(clrDgSelected)]="selectedRow" (clrDgSelectedChange)="selectedChange()">
|
||||
<clr-dg-action-bar>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!(canScanNow(selectedRow) && selectedRow.length==1)" (click)="scanNow(selectedRow)">{{'VULNERABILITY.SCAN_NOW' | translate}}</button>
|
||||
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!(selectedRow.length==1)" (click)="showDigestId(selectedRow)" >{{'REPOSITORY.COPY_DIGEST_ID' | translate}}</button>
|
||||
<button type="button" class="btn btn-sm btn-secondary" *ngIf="hasProjectAdminRole" (click)="deleteTags(selectedRow)" [disabled]="!selectedRow.length">{{'REPOSITORY.DELETE' | translate}}</button>
|
||||
</div>
|
||||
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!(canScanNow(selectedRow) && selectedRow.length==1)" (click)="scanNow(selectedRow)"><clr-icon shape="shield-check" size="16"></clr-icon> {{'VULNERABILITY.SCAN_NOW' | translate}}</button>
|
||||
<button type="button" class="btn btn-sm btn-secondary" [disabled]="!(selectedRow.length==1)" (click)="showDigestId(selectedRow)" ><clr-icon shape="copy" size="16"></clr-icon> {{'REPOSITORY.COPY_DIGEST_ID' | translate}}</button>
|
||||
<button type="button" class="btn btn-sm btn-secondary" *ngIf="hasProjectAdminRole" (click)="deleteTags(selectedRow)" [disabled]="!selectedRow.length"><clr-icon shape="times" size="16"></clr-icon> {{'REPOSITORY.DELETE' | translate}}</button>
|
||||
</clr-dg-action-bar>
|
||||
<clr-dg-column style="width: 160px;" [clrDgField]="'name'">{{'REPOSITORY.TAG' | translate}}</clr-dg-column>
|
||||
<clr-dg-column style="width: 90px;" [clrDgField]="'size'">{{'REPOSITORY.SIZE' | translate}}</clr-dg-column>
|
||||
|
@ -69,11 +69,6 @@
|
||||
"check-else",
|
||||
"check-whitespace"
|
||||
],
|
||||
"quotemark": [
|
||||
true,
|
||||
"double",
|
||||
"avoid-escape"
|
||||
],
|
||||
"radix": true,
|
||||
"semicolon": [
|
||||
"always"
|
||||
|
@ -31,7 +31,7 @@
|
||||
"clarity-icons": "^0.10.17",
|
||||
"clarity-ui": "^0.10.17",
|
||||
"core-js": "^2.4.1",
|
||||
"harbor-ui": "0.6.37",
|
||||
"harbor-ui": "0.6.41",
|
||||
"intl": "^1.2.5",
|
||||
"mutationobserver-shim": "^0.3.2",
|
||||
"ngx-cookie": "^1.0.0",
|
||||
|
@ -12,7 +12,7 @@
|
||||
<clr-icon clrTooltipTrigger shape="info-circle" size="24"></clr-icon>
|
||||
</button>
|
||||
<clr-tooltip-content clrPosition="bottom-left" clrSize="md" *clrIfOpen>
|
||||
<span (click)="openRenameAlert()"> {{'PROFILE.ADMIN_RENAME_TIP'}}</span>
|
||||
<span (click)="openRenameAlert()"> {{'PROFILE.ADMIN_RENAME_TIP' | translate}}</span>
|
||||
</clr-tooltip-content>
|
||||
</clr-tooltip>
|
||||
</div>
|
||||
|
@ -221,7 +221,15 @@ export class ListProjectComponent implements OnDestroy {
|
||||
this.batchDelectionInfos.push(initBatchMessage);
|
||||
});
|
||||
this.deletionDialogService.addBatchInfoList(this.batchDelectionInfos);
|
||||
this.delProjects(p);
|
||||
let deletionMessage = new ConfirmationMessage(
|
||||
"PROJECT.DELETION_TITLE",
|
||||
"PROJECT.DELETION_SUMMARY",
|
||||
nameArr.join(","),
|
||||
p,
|
||||
ConfirmationTargets.PROJECT,
|
||||
ConfirmationButtons.DELETE_CANCEL
|
||||
);
|
||||
this.deletionDialogService.openComfirmDialog(deletionMessage);
|
||||
}
|
||||
}
|
||||
delProjects(projects: Project[]) {
|
||||
|
@ -63,6 +63,7 @@ export class MemberComponent implements OnInit, OnDestroy {
|
||||
isDelete = false;
|
||||
isChangeRole = false;
|
||||
batchActionInfos: BatchInfo[] = [];
|
||||
batchDeletionInfos: BatchInfo[] = [];
|
||||
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
@ -206,17 +207,25 @@ export class MemberComponent implements OnInit, OnDestroy {
|
||||
this.isDelete = true;
|
||||
this.isChangeRole = false;
|
||||
let nameArr: string[] = [];
|
||||
this.batchActionInfos = [];
|
||||
this.batchDeletionInfos = [];
|
||||
if (m && m.length) {
|
||||
m.forEach(data => {
|
||||
nameArr.push(data.username);
|
||||
let initBatchMessage = new BatchInfo ();
|
||||
initBatchMessage.name = data.username;
|
||||
this.batchActionInfos.push(initBatchMessage);
|
||||
this.batchDeletionInfos.push(initBatchMessage);
|
||||
});
|
||||
this.OperateDialogService.addBatchInfoList(this.batchActionInfos);
|
||||
this.OperateDialogService.addBatchInfoList(this.batchDeletionInfos);
|
||||
|
||||
this.deleteMem(m);
|
||||
let deletionMessage = new ConfirmationMessage(
|
||||
"MEMBER.DELETION_TITLE",
|
||||
"MEMBER.DELETION_SUMMARY",
|
||||
nameArr.join(","),
|
||||
m,
|
||||
ConfirmationTargets.PROJECT_MEMBER,
|
||||
ConfirmationButtons.DELETE_CANCEL
|
||||
);
|
||||
this.OperateDialogService.openComfirmDialog(deletionMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,7 +234,7 @@ export class MemberComponent implements OnInit, OnDestroy {
|
||||
let promiseLists: any[] = [];
|
||||
members.forEach(member => {
|
||||
if (member.user_id === this.currentUser.user_id) {
|
||||
let findedList = this.batchActionInfos.find(data => data.name === member.username);
|
||||
let findedList = this.batchDeletionInfos.find(data => data.name === member.username);
|
||||
this.translate.get("BATCH.DELETED_FAILURE").subscribe(res => {
|
||||
findedList = BathInfoChanges(findedList, res, false, true);
|
||||
});
|
||||
@ -243,7 +252,7 @@ export class MemberComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
delOperate(projectId: number, memberId: number, username: string) {
|
||||
let findedList = this.batchActionInfos.find(data => data.name === username);
|
||||
let findedList = this.batchDeletionInfos.find(data => data.name === username);
|
||||
return this.memberService
|
||||
.deleteMember(projectId, memberId)
|
||||
.then(
|
||||
|
@ -69,11 +69,6 @@
|
||||
"check-else",
|
||||
"check-whitespace"
|
||||
],
|
||||
"quotemark": [
|
||||
true,
|
||||
"double",
|
||||
"avoid-escape"
|
||||
],
|
||||
"radix": true,
|
||||
"semicolon": [
|
||||
true
|
||||
|
Loading…
Reference in New Issue
Block a user