Skip to content

Commit

Permalink
Cobbler-Frontend: Add UI for "cobbler replicate"
Browse files Browse the repository at this point in the history
  • Loading branch information
SchoolGuy committed Jul 19, 2024
1 parent fecfd31 commit ac35124
Show file tree
Hide file tree
Showing 6 changed files with 187 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<h1>REPLICATE</h1>

<form class="form-replicate" [formGroup]="replicateFormGroup">
<mat-form-field class="form-field-full-width">
<mat-label>Master</mat-label>
<input matInput type="text" formControlName="master" placeholder="cobbler-master.example.org" />
</mat-form-field>
<mat-form-field class="form-field-full-width">
<mat-label>Port</mat-label>
<input matInput type="number" formControlName="port" placeholder="80" />
</mat-form-field>
<mat-form-field class="form-field-full-width">
<mat-label>Distro Pattern</mat-label>
<input matInput type="text" formControlName="distro_patterns" placeholder="leap-15-*" />
</mat-form-field>
<mat-form-field class="form-field-full-width">
<mat-label>Profile Pattern</mat-label>
<input matInput type="text" formControlName="profile_patterns" placeholder="leap-15-*-autoinstall" />
</mat-form-field>
<mat-form-field class="form-field-full-width">
<mat-label>System Pattern</mat-label>
<input matInput type="text" formControlName="system_patterns" placeholder="*-staging.example.org" />
</mat-form-field>
<mat-form-field class="form-field-full-width">
<mat-label>Repository Pattern</mat-label>
<input matInput type="text" formControlName="repo_patterns" placeholder="opensuse-*" />
</mat-form-field>
<mat-form-field class="form-field-full-width">
<mat-label>Image Pattern</mat-label>
<input matInput type="text" formControlName="image_patterns" placeholder="sles-15-sp*" />
</mat-form-field>
<mat-form-field class="form-field-full-width">
<mat-label>Management-Class Pattern</mat-label>
<input matInput type="text" formControlName="mgmtclass_patterns" placeholder="example-pattern-*" />
</mat-form-field>
<mat-form-field class="form-field-full-width">
<mat-label>File Pattern</mat-label>
<input matInput type="text" formControlName="file_patterns" placeholder="ssh-configs-*" />
</mat-form-field>
<mat-slide-toggle labelPosition="before" formControlName="prune" class="form-field-full-width">Prune</mat-slide-toggle>
<mat-slide-toggle labelPosition="before" formControlName="omit_data" class="form-field-full-width">Omit data</mat-slide-toggle>
<mat-slide-toggle labelPosition="before" formControlName="sync_all" class="form-field-full-width">Sync all</mat-slide-toggle>
<mat-slide-toggle labelPosition="before" formControlName="use_ssl" class="form-field-full-width">Use SSL</mat-slide-toggle>
<button mat-button (click)="runReplicate()">Run</button>
</form>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.form-replicate {
min-width: 150px;
max-width: 600px;
width: 100%;
}

.form-field-full-width {
width: 100%;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import {provideHttpClient} from '@angular/common/http';
import {provideHttpClientTesting} from '@angular/common/http/testing';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import {MatButtonModule} from '@angular/material/button';
import {MatFormFieldModule} from '@angular/material/form-field';
import {MatInputModule} from '@angular/material/input';
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {COBBLER_URL} from 'cobbler-api';

import { ReplicateComponent } from './replicate.component';

describe('ReplicateComponent', () => {
let component: ReplicateComponent;
let fixture: ComponentFixture<ReplicateComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
ReplicateComponent,
NoopAnimationsModule,
MatFormFieldModule,
MatInputModule,
MatButtonModule,
],
providers: [
provideHttpClient(),
provideHttpClientTesting(),
{
provide: COBBLER_URL,
useValue: new URL('http://localhost/cobbler_api')
}
]
})
.compileComponents();

fixture = TestBed.createComponent(ReplicateComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import {Component, inject} from '@angular/core';
import {FormBuilder, ReactiveFormsModule} from '@angular/forms';
import {MatButton} from '@angular/material/button';
import {MatFormFieldModule, MatLabel} from '@angular/material/form-field';
import {MatFormField, MatInput} from '@angular/material/input';
import {MatSlideToggle} from '@angular/material/slide-toggle';
import {MatSnackBar} from '@angular/material/snack-bar';
import {BackgroundReplicateOptions, CobblerApiService} from 'cobbler-api';
import {UserService} from '../../services/user.service';

@Component({
selector: 'cobbler-replicate',
standalone: true,
imports: [
MatFormField,
ReactiveFormsModule,
MatLabel,
MatFormFieldModule,
MatInput,
MatSlideToggle,
MatButton,
],
templateUrl: './replicate.component.html',
styleUrl: './replicate.component.scss'
})
export class ReplicateComponent {
private readonly _formBuilder = inject(FormBuilder);
replicateFormGroup = this._formBuilder.group({
master: "",
port: "",
distro_patterns: "",
profile_patterns: "",
system_patterns: "",
repo_patterns: "",
image_patterns: "",
mgmtclass_patterns: "",
package_patterns: "",
file_patterns: "",
prune: false,
omit_data: false,
sync_all: false,
use_ssl: false,
});

constructor(
public userService: UserService,
private cobblerApiService: CobblerApiService,
private _snackBar: MatSnackBar
) {
}

runReplicate(): void {
const replicateOptions: BackgroundReplicateOptions = {
master: this.replicateFormGroup.controls.master.value,
port: this.replicateFormGroup.controls.port.value,
distro_patterns: this.replicateFormGroup.controls.distro_patterns.value,
profile_patterns: this.replicateFormGroup.controls.profile_patterns.value,
system_patterns: this.replicateFormGroup.controls.system_patterns.value,
repo_patterns: this.replicateFormGroup.controls.repo_patterns.value,
image_patterns: this.replicateFormGroup.controls.image_patterns.value,
mgmtclass_patterns: this.replicateFormGroup.controls.mgmtclass_patterns.value,
package_patterns: this.replicateFormGroup.controls.package_patterns.value,
file_patterns: this.replicateFormGroup.controls.file_patterns.value,
prune: this.replicateFormGroup.controls.prune.value,
omit_data: this.replicateFormGroup.controls.omit_data.value,
sync_all: this.replicateFormGroup.controls.sync_all.value,
use_ssl: this.replicateFormGroup.controls.use_ssl.value,
}
console.log(replicateOptions)
this.cobblerApiService.background_replicate(replicateOptions, this.userService.token).subscribe(
value => {
// TODO
},
error => {
// HTML encode the error message since it originates from XML
this._snackBar.open(this.toHTML(error.message), 'Close');
})
}

toHTML(input: string) : any {
// FIXME: Deduplicate method
return new DOMParser().parseFromString(input, "text/html").documentElement.textContent;
}
}
2 changes: 2 additions & 0 deletions projects/cobbler-frontend/src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { BuildISOComponent } from './actions/build-iso/build-iso.component';
import { CheckSysComponent } from './actions/check-sys/check-sys.component';
import {HardlinkComponent} from './actions/hardlink/hardlink.component';
import { ImportDVDComponent } from './actions/import-dvd/import-dvd.component';
import {ReplicateComponent} from './actions/replicate/replicate.component';
import { RepoSyncComponent } from './actions/repo-sync/repo-sync.component';
import {StatusComponent} from './actions/status/status.component';
import { SyncComponent } from './actions/sync/sync.component';
Expand Down Expand Up @@ -57,6 +58,7 @@ export const routes: Routes = [
{path: 'events', component: AppEventsComponent, canActivate: [AuthGuardService]},
{path: 'signatures', component: SignaturesComponent, canActivate: [AuthGuardService]},
{path: 'validate-autoinstalls', component: ValidateAutoinstallsComponent, canActivate: [AuthGuardService]},
{path: 'replicate', component: ReplicateComponent, canActivate: [AuthGuardService]},
{path: '404', component: NotFoundComponent},
{path: '**', redirectTo: '/404'},
];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ <h2 matSubheader>Actions</h2>
<a mat-list-item class="nav-link" [routerLink]="['/validate-autoinstalls']">
<b class="symbol">&#9881;</b>Validate Autoinstalls</a
>
<a mat-list-item class="nav-link" [routerLink]="['/replicate']">
<b class="symbol">&#9881;</b>Replicate</a
>
<mat-divider></mat-divider>
<h2 matSubheader>Cobbler</h2>
<a mat-list-item class="nav-link" [routerLink]="['/check']">
Expand Down

0 comments on commit ac35124

Please sign in to comment.