mirror of
https://github.com/portainer/portainer.git
synced 2025-08-07 14:55:27 +02:00
chore(fdo): remove FDO code EE-7235 (#11981)
This commit is contained in:
parent
1a3db327c7
commit
19fa40286a
57 changed files with 3 additions and 2609 deletions
|
@ -200,17 +200,6 @@ angular
|
|||
},
|
||||
};
|
||||
|
||||
var deviceImport = {
|
||||
name: 'portainer.endpoints.importDevice',
|
||||
url: '/device',
|
||||
views: {
|
||||
'content@': {
|
||||
templateUrl: './views/devices/import/importDevice.html',
|
||||
controller: 'ImportDeviceController',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const edgeAutoCreateScript = {
|
||||
name: 'portainer.endpoints.edgeAutoCreateScript',
|
||||
url: '/aeec',
|
||||
|
@ -224,26 +213,6 @@ angular
|
|||
},
|
||||
};
|
||||
|
||||
var addFDOProfile = {
|
||||
name: 'portainer.endpoints.profile',
|
||||
url: '/profile',
|
||||
views: {
|
||||
'content@': {
|
||||
component: 'addProfileView',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
var editFDOProfile = {
|
||||
name: 'portainer.endpoints.profile.edit',
|
||||
url: '/:id',
|
||||
views: {
|
||||
'content@': {
|
||||
component: 'editProfileView',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
var endpointAccess = {
|
||||
name: 'portainer.endpoints.endpoint.access',
|
||||
url: '/access',
|
||||
|
@ -484,9 +453,6 @@ angular
|
|||
$stateRegistryProvider.register(endpointAccess);
|
||||
$stateRegistryProvider.register(endpointKVM);
|
||||
$stateRegistryProvider.register(edgeAutoCreateScript);
|
||||
$stateRegistryProvider.register(deviceImport);
|
||||
$stateRegistryProvider.register(addFDOProfile);
|
||||
$stateRegistryProvider.register(editFDOProfile);
|
||||
$stateRegistryProvider.register(groups);
|
||||
$stateRegistryProvider.register(group);
|
||||
$stateRegistryProvider.register(groupAccess);
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
import axios, { parseAxiosError } from '@/portainer/services/axios';
|
||||
|
||||
import { FDOConfiguration, DeviceConfiguration, Profile } from './model';
|
||||
|
||||
const BASE_URL = '/fdo';
|
||||
|
||||
export async function configureFDO(formValues: FDOConfiguration) {
|
||||
try {
|
||||
await axios.post(`${BASE_URL}/configure`, formValues);
|
||||
} catch (e) {
|
||||
throw parseAxiosError(e as Error, 'Unable to configure FDO');
|
||||
}
|
||||
}
|
||||
|
||||
export async function configureDevice(
|
||||
deviceId: string,
|
||||
deviceConfig: DeviceConfiguration
|
||||
) {
|
||||
try {
|
||||
await axios.post(`${BASE_URL}/configure/${deviceId}`, deviceConfig);
|
||||
} catch (e) {
|
||||
throw parseAxiosError(e as Error, 'Unable to configure device');
|
||||
}
|
||||
}
|
||||
|
||||
export async function createProfile(
|
||||
name: string,
|
||||
method: string,
|
||||
profileFileContent: string
|
||||
) {
|
||||
const payload = {
|
||||
name,
|
||||
profileFileContent,
|
||||
};
|
||||
try {
|
||||
await axios.post(`${BASE_URL}/profiles`, payload, {
|
||||
params: { method },
|
||||
});
|
||||
} catch (e) {
|
||||
throw parseAxiosError(e as Error, 'Unable to create profile');
|
||||
}
|
||||
}
|
||||
|
||||
export async function getProfiles() {
|
||||
try {
|
||||
const { data: profiles } = await axios.get<Profile[]>(
|
||||
`${BASE_URL}/profiles`
|
||||
);
|
||||
return profiles;
|
||||
} catch (e) {
|
||||
throw parseAxiosError(e as Error, 'Unable to retrieve the profiles');
|
||||
}
|
||||
}
|
||||
|
||||
export async function getProfile(profileId: number) {
|
||||
try {
|
||||
const { data: profile } = await axios.get<Profile>(
|
||||
`${BASE_URL}/profiles/${profileId}`
|
||||
);
|
||||
return profile;
|
||||
} catch (e) {
|
||||
throw parseAxiosError(e as Error, 'Unable to retrieve profile');
|
||||
}
|
||||
}
|
||||
|
||||
export async function deleteProfile(profileId: number) {
|
||||
try {
|
||||
await axios.delete(`${BASE_URL}/profiles/${profileId}`);
|
||||
} catch (e) {
|
||||
throw parseAxiosError(e as Error, 'Unable to delete profile');
|
||||
}
|
||||
}
|
||||
|
||||
export async function updateProfile(
|
||||
id: number,
|
||||
name: string,
|
||||
profileFileContent: string
|
||||
) {
|
||||
const payload = {
|
||||
name,
|
||||
profileFileContent,
|
||||
};
|
||||
try {
|
||||
await axios.put(`${BASE_URL}/profiles/${id}`, payload);
|
||||
} catch (e) {
|
||||
throw parseAxiosError(e as Error, 'Unable to update profile');
|
||||
}
|
||||
}
|
||||
|
||||
export async function duplicateProfile(id: number) {
|
||||
try {
|
||||
const { data: profile } = await axios.post<Profile>(
|
||||
`${BASE_URL}/profiles/${id}/duplicate`
|
||||
);
|
||||
return profile;
|
||||
} catch (e) {
|
||||
throw parseAxiosError(e as Error, 'Unable to duplicate profile');
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
export interface FDOConfiguration {
|
||||
enabled: boolean;
|
||||
ownerURL: string;
|
||||
ownerUsername: string;
|
||||
ownerPassword: string;
|
||||
}
|
||||
|
||||
export interface DeviceConfiguration {
|
||||
edgeID: string;
|
||||
edgeKey: string;
|
||||
name: string;
|
||||
profile: string;
|
||||
}
|
||||
|
||||
export type Profile = {
|
||||
id: number;
|
||||
name: string;
|
||||
fileContent: string;
|
||||
dateCreated: string;
|
||||
};
|
|
@ -6,7 +6,6 @@ export function SettingsViewModel(data) {
|
|||
this.LDAPSettings = data.LDAPSettings;
|
||||
this.OAuthSettings = new OAuthSettingsViewModel(data.OAuthSettings);
|
||||
this.openAMTConfiguration = data.openAMTConfiguration;
|
||||
this.fdoConfiguration = data.fdoConfiguration;
|
||||
this.SnapshotInterval = data.SnapshotInterval;
|
||||
this.TemplatesURL = data.TemplatesURL;
|
||||
this.EdgeAgentCheckinInterval = data.EdgeAgentCheckinInterval;
|
||||
|
@ -37,7 +36,6 @@ export function PublicSettingsViewModel(settings) {
|
|||
this.Edge = new EdgeSettingsViewModel(settings.Edge);
|
||||
this.DefaultRegistry = settings.DefaultRegistry;
|
||||
this.IsAMTEnabled = settings.IsAMTEnabled;
|
||||
this.IsFDOEnabled = settings.IsFDOEnabled;
|
||||
}
|
||||
|
||||
export function InternalAuthSettingsViewModel(data) {
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
import angular from 'angular';
|
||||
|
||||
import { SettingsFDO } from '@/react/portainer/settings/EdgeComputeView/SettingsFDO';
|
||||
import { SettingsOpenAMT } from '@/react/portainer/settings/EdgeComputeView/SettingsOpenAMT';
|
||||
import { InternalAuth } from '@/react/portainer/settings/AuthenticationView/InternalAuth';
|
||||
import { r2a } from '@/react-tools/react2angular';
|
||||
|
@ -17,10 +16,6 @@ import { AuthStyleField } from '@/react/portainer/settings/AuthenticationView/OA
|
|||
|
||||
export const settingsModule = angular
|
||||
.module('portainer.app.react.components.settings', [])
|
||||
.component(
|
||||
'settingsFdo',
|
||||
r2a(withUIRouter(withReactQuery(SettingsFDO)), ['onSubmit', 'settings'])
|
||||
)
|
||||
.component('settingsOpenAmt', r2a(SettingsOpenAMT, ['onSubmit', 'settings']))
|
||||
.component(
|
||||
'internalAuth',
|
||||
|
|
|
@ -195,15 +195,5 @@ function FileUploadFactory($q, Upload) {
|
|||
return $q.all(queue);
|
||||
};
|
||||
|
||||
service.uploadOwnershipVoucher = function (voucherFile) {
|
||||
return Upload.upload({
|
||||
url: 'api/fdo/register',
|
||||
data: {
|
||||
voucher: voucherFile,
|
||||
},
|
||||
ignoreLoadingBar: true,
|
||||
});
|
||||
};
|
||||
|
||||
return service;
|
||||
}
|
||||
|
|
|
@ -1,237 +0,0 @@
|
|||
<page-header title="'FDO Device Configuration'" breadcrumbs="[{label:'Environments', link:'portainer.endpoints'}, 'Import FDO Device']" reload="true"> </page-header>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<rd-widget>
|
||||
<rd-widget-header icon="wand-2" title-text="Import Device Set up"></rd-widget-header>
|
||||
<rd-widget-body>
|
||||
<form class="form-horizontal" name="fdoForm">
|
||||
<!-- info -->
|
||||
<span class="small">
|
||||
<p class="text-muted" style="margin-top: 10px">
|
||||
<pr-icon icon="'info'" mode="'primary'" class-name="'mr-0.5'"></pr-icon>
|
||||
You are setting up a Portainer Edge Agent that will initiate the communications with the Portainer instance and your FDO Devices.
|
||||
</p>
|
||||
</span>
|
||||
<!-- !info -->
|
||||
<!-- import voucher -->
|
||||
<div class="col-sm-12 form-section-title"> Import Voucher </div>
|
||||
<div>
|
||||
<div class="form-group" ng-show="!state.vouchersUploaded">
|
||||
<span class="small col-sm-12">
|
||||
<p class="text-muted" style="margin-top: 10px">
|
||||
<pr-icon icon="'info'" mode="'primary'" class-name="'mr-0.5'"></pr-icon>
|
||||
Import one or more Manufacturer's Ownership Vouchers to initiate device attestation
|
||||
</p>
|
||||
</span>
|
||||
<div class="col-sm-8">
|
||||
<button
|
||||
style="margin-left: 0px !important"
|
||||
class="btn btn-sm btn-primary"
|
||||
ngf-select="onVoucherFilesChange()"
|
||||
ng-model="formValues.VoucherFiles"
|
||||
name="VoucherFiles"
|
||||
ng-disabled="state.vouchersUploading"
|
||||
button-spinner="state.vouchersUploading"
|
||||
multiple
|
||||
>
|
||||
<span ng-hide="state.vouchersUploading"
|
||||
>Upload
|
||||
<pr-icon icon="'upload'" class-name="'ml-1'"></pr-icon>
|
||||
</span>
|
||||
<span ng-show="state.vouchersUploading">Uploading Voucher...</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-show="state.vouchersUploading">
|
||||
<div class="col-sm-12 small text-success">
|
||||
<p>Connecting to the Owner service...</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-show="state.vouchersUploaded">
|
||||
<div class="col-sm-12">
|
||||
<p>Ownership Voucher Uploaded <pr-icon icon="'check'" mode="'success'"></pr-icon></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !import voucher -->
|
||||
<!-- device details -->
|
||||
<div class="col-sm-12 form-section-title"> Device details </div>
|
||||
<div>
|
||||
<span class="small">
|
||||
<p class="text-muted" style="margin-top: 10px">
|
||||
<pr-icon icon="'info'" mode="'primary'" class-name="'mr-0.5'"></pr-icon>
|
||||
Device name will serve as your reference name in Portainer
|
||||
</p>
|
||||
</span>
|
||||
<!-- device name input -->
|
||||
<div class="form-group">
|
||||
<label for="device_name" class="col-sm-3 col-lg-2 control-label text-left">Device Name</label>
|
||||
<div class="col-sm-9 col-lg-10">
|
||||
<input
|
||||
type="text"
|
||||
data-cy="deviceImport-deviceNameInput"
|
||||
class="form-control"
|
||||
name="device_name"
|
||||
placeholder="e.g. FDO-Test01"
|
||||
ng-model="formValues.DeviceName"
|
||||
ng-required="state.vouchersUploaded"
|
||||
ng-disabled="!state.vouchersUploaded"
|
||||
auto-focus
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-show="fdoForm.device_name.$invalid">
|
||||
<div class="col-sm-12 small text-warning">
|
||||
<div ng-messages="fdoForm.device_name.$error">
|
||||
<p ng-message="required">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'"></pr-icon>
|
||||
This field is required.</p
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !device name input -->
|
||||
<!-- suffix input -->
|
||||
<span class="small">
|
||||
<p class="text-muted" style="margin-top: 10px">
|
||||
<pr-icon icon="'info'" mode="'primary'" class-name="'mr-0.5'"></pr-icon>
|
||||
Suffix starting number will be appended to the end of the Device name, if initiating multiple devices this will be incrementally increased
|
||||
</p>
|
||||
</span>
|
||||
<div class="form-group">
|
||||
<label for="suffix" class="col-sm-3 col-lg-2 control-label text-left"> Suffix starting number </label>
|
||||
<div class="col-sm-9 col-lg-10">
|
||||
<input
|
||||
type="text"
|
||||
data-cy="deviceImport-suffixInput"
|
||||
class="form-control"
|
||||
name="suffix"
|
||||
ng-model="formValues.Suffix"
|
||||
ng-required="state.vouchersUploaded"
|
||||
ng-disabled="!state.vouchersUploaded"
|
||||
ng-pattern="/^[0-9]+$/"
|
||||
placeholder="1"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-show="fdoForm.suffix.$invalid">
|
||||
<div class="col-sm-12 small text-warning">
|
||||
<div ng-messages="fdoForm.suffix.$error">
|
||||
<p ng-message="required">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'"></pr-icon>
|
||||
This field is required.</p
|
||||
>
|
||||
<p ng-message="pattern">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'"></pr-icon>
|
||||
This field needs to be a positive integer number.</p
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !suffix input -->
|
||||
<!-- portainer-instance-input -->
|
||||
<div class="form-group">
|
||||
<label for="endpoint_url" class="col-sm-3 col-lg-2 control-label text-left">
|
||||
Portainer server URL
|
||||
<portainer-tooltip message="'URL of the Portainer instance that the agent will use to initiate the communications.'"></portainer-tooltip>
|
||||
</label>
|
||||
<div class="col-sm-9 col-lg-10">
|
||||
<input
|
||||
type="text"
|
||||
data-cy="deviceImport-portainerServerUrlInput"
|
||||
class="form-control"
|
||||
name="endpoint_url"
|
||||
ng-model="formValues.PortainerURL"
|
||||
ng-required="state.vouchersUploaded"
|
||||
ng-disabled="!state.vouchersUploaded"
|
||||
placeholder="e.g. https://10.0.0.10:9443"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group" ng-show="fdoForm.endpoint_url.$invalid">
|
||||
<div class="col-sm-12 small text-warning">
|
||||
<div ng-messages="fdoForm.endpoint_url.$error">
|
||||
<p ng-message="required">
|
||||
<pr-icon icon="'alert-triangle'" mode="'warning'"></pr-icon>
|
||||
This field is required.</p
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !portainer-instance-input -->
|
||||
</div>
|
||||
<!-- device profile input -->
|
||||
<div class="form-group">
|
||||
<label for="device_profile" class="col-sm-3 col-lg-2 control-label text-left">Device Profile</label>
|
||||
<div class="col-sm-9 col-lg-10">
|
||||
<select
|
||||
id="device_profile"
|
||||
data-cy="deviceImport-deviceProfileSelect"
|
||||
ng-model="formValues.DeviceProfile"
|
||||
class="form-control"
|
||||
ng-required="state.vouchersUploaded"
|
||||
ng-disabled="!state.vouchersUploaded"
|
||||
>
|
||||
<option selected disabled hidden value="">Select a profile for your device</option>
|
||||
<option ng-repeat="profile in profiles | orderBy: 'name'" ng-value="profile.id">{{ profile.name }}</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !device profile input -->
|
||||
<!-- !device details -->
|
||||
<!-- tags -->
|
||||
<div class="col-sm-12 form-section-title"> Set up Tags </div>
|
||||
<div>
|
||||
<span class="small">
|
||||
<p class="text-muted" style="margin-top: 10px">
|
||||
<pr-icon icon="'info'" mode="'primary'" class-name="'mr-0.5'"></pr-icon>
|
||||
This is just an option if your device is under a certain group
|
||||
</p>
|
||||
</span>
|
||||
<!-- group -->
|
||||
<div class="form-group">
|
||||
<label for="device_group" class="col-sm-3 col-lg-2 control-label text-left"> Group </label>
|
||||
<div class="col-sm-9 col-lg-10">
|
||||
<select
|
||||
class="form-control"
|
||||
data-cy="deviceImport-deviceGroupSelect"
|
||||
ng-options="group.Id as group.Name for group in groups"
|
||||
ng-model="formValues.GroupId"
|
||||
id="device_group"
|
||||
ng-required="state.vouchersUploaded"
|
||||
ng-disabled="!state.vouchersUploaded"
|
||||
data-cy="deviceImport-deviceGroup"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !group -->
|
||||
|
||||
<tag-selector ng-if="formValues" value="formValues.TagIds" allow-create="state.allowCreateTag" on-change="(onChangeTags)"> </tag-selector>
|
||||
|
||||
<!-- actions -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary btn-sm"
|
||||
ng-click="createEndpointAndConfigureDevice()"
|
||||
ng-disabled="state.actionInProgress || !state.vouchersUploaded || !fdoForm.$valid"
|
||||
button-spinner="state.actionInProgress"
|
||||
data-cy="deviceImport-saveDeviceButton"
|
||||
>
|
||||
<span ng-hide="state.actionInProgress">Save Configuration</span>
|
||||
<span ng-show="state.actionInProgress">Saving...</span>
|
||||
</button>
|
||||
<a type="button" class="btn btn-default btn-sm" ui-sref="portainer.endpoints">Cancel</a>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !actions -->
|
||||
</div>
|
||||
</form>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
</div>
|
||||
</div>
|
|
@ -1,138 +0,0 @@
|
|||
import uuidv4 from 'uuid/v4';
|
||||
|
||||
import { PortainerEndpointCreationTypes } from 'Portainer/models/endpoint/models';
|
||||
import { configureDevice, getProfiles } from 'Portainer/hostmanagement/fdo/fdo.service';
|
||||
|
||||
angular
|
||||
.module('portainer.app')
|
||||
.controller(
|
||||
'ImportDeviceController',
|
||||
function ImportDeviceController($async, $q, $scope, $state, EndpointService, GroupService, TagService, Notifications, Authentication, FileUploadService) {
|
||||
$scope.state = {
|
||||
actionInProgress: false,
|
||||
vouchersUploading: false,
|
||||
vouchersUploaded: false,
|
||||
deviceIDs: [],
|
||||
allowCreateTag: Authentication.isAdmin(),
|
||||
};
|
||||
|
||||
$scope.formValues = {
|
||||
DeviceName: '',
|
||||
DeviceProfile: '',
|
||||
GroupId: 1,
|
||||
TagIds: [],
|
||||
VoucherFiles: [],
|
||||
PortainerURL: '',
|
||||
Suffix: 1,
|
||||
};
|
||||
|
||||
$scope.profiles = [];
|
||||
|
||||
$scope.onChangeTags = function onChangeTags(value) {
|
||||
return $scope.$evalAsync(() => {
|
||||
$scope.formValues.TagIds = value;
|
||||
});
|
||||
};
|
||||
|
||||
$scope.onVoucherFilesChange = function () {
|
||||
if ($scope.formValues.VoucherFiles.length < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.state.vouchersUploading = true;
|
||||
|
||||
let uploads = $scope.formValues.VoucherFiles.map((f) => FileUploadService.uploadOwnershipVoucher(f));
|
||||
|
||||
$q.all(uploads)
|
||||
.then(function success(responses) {
|
||||
$scope.state.vouchersUploading = false;
|
||||
$scope.state.vouchersUploaded = true;
|
||||
$scope.state.deviceIDs = responses.map((r) => r.data.guid);
|
||||
})
|
||||
.catch(function error(err) {
|
||||
$scope.state.vouchersUploading = false;
|
||||
if ($scope.formValues.VoucherFiles.length === 1) {
|
||||
Notifications.error('Failure', err, 'Unable to upload the Ownership Voucher');
|
||||
} else {
|
||||
Notifications.error('Failure', null, 'Unable to upload the Ownership Vouchers, please check the logs');
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.createEndpointAndConfigureDevice = function () {
|
||||
return $async(async () => {
|
||||
$scope.state.actionInProgress = true;
|
||||
|
||||
let suffix = $scope.formValues.Suffix;
|
||||
|
||||
for (const deviceID of $scope.state.deviceIDs) {
|
||||
let deviceName = $scope.formValues.DeviceName + suffix;
|
||||
|
||||
try {
|
||||
var endpoint = await EndpointService.createRemoteEndpoint(
|
||||
deviceName,
|
||||
PortainerEndpointCreationTypes.EdgeAgentEnvironment,
|
||||
$scope.formValues.PortainerURL,
|
||||
'',
|
||||
$scope.formValues.GroupId,
|
||||
$scope.formValues.TagIds,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null
|
||||
);
|
||||
} catch (err) {
|
||||
Notifications.error('Failure', err, 'Unable to create the environment');
|
||||
$scope.state.actionInProgress = false;
|
||||
return;
|
||||
}
|
||||
|
||||
suffix++;
|
||||
|
||||
const config = {
|
||||
edgeID: endpoint.EdgeID || uuidv4(),
|
||||
edgeKey: endpoint.EdgeKey,
|
||||
name: deviceName,
|
||||
profile: $scope.formValues.DeviceProfile,
|
||||
};
|
||||
|
||||
try {
|
||||
await configureDevice(deviceID, config);
|
||||
} catch (err) {
|
||||
Notifications.error('Failure', err, 'Unable to import device');
|
||||
return;
|
||||
} finally {
|
||||
$scope.state.actionInProgress = false;
|
||||
}
|
||||
}
|
||||
|
||||
Notifications.success('Success', 'Device(s) successfully imported');
|
||||
$state.go('edge.devices');
|
||||
});
|
||||
};
|
||||
|
||||
async function initView() {
|
||||
try {
|
||||
$scope.profiles = await getProfiles();
|
||||
} catch (err) {
|
||||
Notifications.error('Failure', err, 'Unable to load profiles');
|
||||
return;
|
||||
}
|
||||
|
||||
$q.all({
|
||||
groups: GroupService.groups(),
|
||||
})
|
||||
.then(function success(data) {
|
||||
$scope.groups = data.groups;
|
||||
})
|
||||
.catch(function error(err) {
|
||||
Notifications.error('Failure', err, 'Unable to load groups');
|
||||
});
|
||||
}
|
||||
|
||||
initView();
|
||||
}
|
||||
);
|
|
@ -1,65 +0,0 @@
|
|||
<page-header title="'Create profile'" breadcrumbs="[{label:'Settings', link:'portainer.settings'}, 'Edge Compute']" reload="true"> </page-header>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<rd-widget>
|
||||
<rd-widget-body>
|
||||
<form class="form-horizontal" name="createProfileForm">
|
||||
<!-- name-input -->
|
||||
<div class="col-sm-12 form-section-title">Device Profile Details </div>
|
||||
<div class="form-group">
|
||||
<label for="stack_name" class="col-sm-1 control-label text-left">Name</label>
|
||||
<div class="col-sm-11">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
ng-model="formValues.name"
|
||||
id="profile_name"
|
||||
name="profile_name"
|
||||
placeholder="e.g. myprofile"
|
||||
auto-focus
|
||||
data-cy="profile-name-input"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !name-input -->
|
||||
<!-- build-method -->
|
||||
<div class="col-sm-12 form-section-title"> Profile configuration </div>
|
||||
<box-selector slim="true" options="buildMethods" value="state.method"></box-selector>
|
||||
|
||||
<!-- !build-method -->
|
||||
|
||||
<web-editor-form
|
||||
ng-if="state.method === 'editor'"
|
||||
identifier="profile-creation-editor"
|
||||
value="formValues.profileFileContent"
|
||||
on-change="(onChangeFileContent)"
|
||||
ng-required="true"
|
||||
>
|
||||
</web-editor-form>
|
||||
|
||||
<!-- actions -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<a type="button" class="btn btn-default btn-sm" ui-sref="portainer.settings.edgeCompute">Cancel</a>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary btn-sm"
|
||||
ng-disabled="state.actionInProgress
|
||||
|| !createProfileForm.$valid
|
||||
|| !formValues.profileFileContent
|
||||
|| !formValues.name"
|
||||
ng-click="createProfileAsync()"
|
||||
button-spinner="state.actionInProgress"
|
||||
>
|
||||
<span ng-hide="state.actionInProgress">Save Profile</span>
|
||||
<span ng-show="state.actionInProgress">Saving...</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !actions -->
|
||||
</form>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
</div>
|
||||
</div>
|
|
@ -1,70 +0,0 @@
|
|||
import angular from 'angular';
|
||||
import { editor } from '@@/BoxSelector/common-options/build-methods';
|
||||
|
||||
import { createProfile } from 'Portainer/hostmanagement/fdo/fdo.service';
|
||||
|
||||
angular.module('portainer.app').controller('AddProfileController', AddProfileController);
|
||||
|
||||
/* @ngInject */
|
||||
export default function AddProfileController($scope, $async, $state, $window, Notifications) {
|
||||
$scope.buildMethods = [editor];
|
||||
|
||||
$scope.formValues = {
|
||||
name: '',
|
||||
profileFileContent: '',
|
||||
};
|
||||
|
||||
$scope.state = {
|
||||
method: 'editor',
|
||||
actionInProgress: false,
|
||||
isEditorDirty: false,
|
||||
};
|
||||
|
||||
$window.onbeforeunload = () => {
|
||||
if ($scope.state.method === 'editor' && $scope.formValues.profileFileContent && $scope.state.isEditorDirty) {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
$scope.$on('$destroy', function () {
|
||||
$scope.state.isEditorDirty = false;
|
||||
});
|
||||
|
||||
$scope.onChangeFormValues = onChangeFormValues;
|
||||
|
||||
$scope.createProfileAsync = function () {
|
||||
return $async(async () => {
|
||||
const method = $scope.state.method;
|
||||
|
||||
const name = $scope.formValues.name;
|
||||
const fileContent = $scope.formValues.profileFileContent;
|
||||
|
||||
if (method !== 'editor' && fileContent === '') {
|
||||
$scope.state.formValidationError = 'Profile file content must not be empty';
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.state.actionInProgress = true;
|
||||
|
||||
try {
|
||||
await createProfile(name, method, fileContent);
|
||||
Notifications.success('Success', 'Profile successfully created');
|
||||
$scope.state.isEditorDirty = false;
|
||||
$state.go('portainer.settings.edgeCompute');
|
||||
} catch (err) {
|
||||
Notifications.error('Failure', err, 'Unable to create Profile');
|
||||
} finally {
|
||||
$scope.state.actionInProgress = false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.onChangeFileContent = function onChangeFileContent(value) {
|
||||
$scope.formValues.profileFileContent = value;
|
||||
$scope.state.isEditorDirty = true;
|
||||
};
|
||||
|
||||
function onChangeFormValues(newValues) {
|
||||
$scope.formValues = newValues;
|
||||
}
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
import angular from 'angular';
|
||||
|
||||
import controller from './addProfileController';
|
||||
|
||||
angular.module('portainer.app').component('addProfileView', {
|
||||
templateUrl: './addProfile.html',
|
||||
controller,
|
||||
});
|
|
@ -1,66 +0,0 @@
|
|||
<page-header title="'Edit profile'" breadcrumbs="[{label:'Settings', link:'portainer.settings'}, 'Edge Compute']" reload="true"> </page-header>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<rd-widget>
|
||||
<rd-widget-body>
|
||||
<form class="form-horizontal" name="editProfileForm">
|
||||
<!-- name-input -->
|
||||
<div class="col-sm-12 form-section-title">Device Profile Details </div>
|
||||
<div class="form-group">
|
||||
<label for="stack_name" class="col-sm-1 control-label text-left">Name</label>
|
||||
<div class="col-sm-11">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
ng-model="formValues.name"
|
||||
id="profile_name"
|
||||
name="profile_name"
|
||||
placeholder="e.g. myprofile"
|
||||
auto-focus
|
||||
data-cy="profile-name-input"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !name-input -->
|
||||
<!-- build-method -->
|
||||
<div class="col-sm-12 form-section-title"> Profile configuration </div>
|
||||
|
||||
<box-selector slim="true" options="buildMethods" value="state.method"></box-selector>
|
||||
|
||||
<!-- !build-method -->
|
||||
|
||||
<web-editor-form
|
||||
ng-if="state.method === 'editor'"
|
||||
identifier="profile-creation-editor"
|
||||
value="formValues.profileFileContent"
|
||||
on-change="(onChangeFileContent)"
|
||||
ng-required="true"
|
||||
>
|
||||
</web-editor-form>
|
||||
|
||||
<!-- actions -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<a type="button" class="btn btn-default btn-sm" ui-sref="portainer.settings.edgeCompute">Cancel</a>
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-primary btn-sm"
|
||||
ng-disabled="state.actionInProgress
|
||||
|| !editProfileForm.$valid
|
||||
|| !formValues.profileFileContent
|
||||
|| !formValues.name"
|
||||
ng-click="updateProfileAsync()"
|
||||
button-spinner="state.actionInProgress"
|
||||
>
|
||||
<span ng-hide="state.actionInProgress">Update Profile</span>
|
||||
<span ng-show="state.actionInProgress">Saving...</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !actions -->
|
||||
</form>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
</div>
|
||||
</div>
|
|
@ -1,88 +0,0 @@
|
|||
import angular from 'angular';
|
||||
import { editor } from '@@/BoxSelector/common-options/build-methods';
|
||||
import { getProfile, updateProfile } from 'Portainer/hostmanagement/fdo/fdo.service';
|
||||
|
||||
angular.module('portainer.app').controller('EditProfileController', EditProfileController);
|
||||
|
||||
/* @ngInject */
|
||||
export default function EditProfileController($scope, $async, $state, $window, Notifications) {
|
||||
$scope.buildMethods = [editor];
|
||||
|
||||
$scope.formValues = {
|
||||
name: '',
|
||||
profileFileContent: '',
|
||||
};
|
||||
|
||||
$scope.state = {
|
||||
profileID: $state.params.id,
|
||||
method: 'editor',
|
||||
actionInProgress: false,
|
||||
isEditorDirty: false,
|
||||
};
|
||||
|
||||
$window.onbeforeunload = () => {
|
||||
if ($scope.state.method === 'editor' && $scope.formValues.profileFileContent && $scope.state.isEditorDirty) {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
$scope.$on('$destroy', function () {
|
||||
$scope.state.isEditorDirty = false;
|
||||
});
|
||||
|
||||
$scope.onChangeFormValues = onChangeFormValues;
|
||||
|
||||
$scope.updateProfileAsync = function () {
|
||||
return $async(async () => {
|
||||
const method = $scope.state.method;
|
||||
|
||||
const name = $scope.formValues.name;
|
||||
const fileContent = $scope.formValues.profileFileContent;
|
||||
|
||||
if (method !== 'editor' && fileContent === '') {
|
||||
$scope.state.formValidationError = 'Profile file content must not be empty';
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.state.actionInProgress = true;
|
||||
|
||||
try {
|
||||
await updateProfile($scope.state.profileID, name, fileContent);
|
||||
Notifications.success('Success', 'Profile successfully updated');
|
||||
$scope.state.isEditorDirty = false;
|
||||
$state.go('portainer.settings.edgeCompute');
|
||||
} catch (err) {
|
||||
Notifications.error('Failure', err, 'Unable to update Profile');
|
||||
} finally {
|
||||
$scope.state.actionInProgress = false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$scope.onChangeFileContent = function onChangeFileContent(value) {
|
||||
$scope.formValues.profileFileContent = value;
|
||||
$scope.state.isEditorDirty = true;
|
||||
};
|
||||
|
||||
function onChangeFormValues(newValues) {
|
||||
$scope.formValues = newValues;
|
||||
}
|
||||
|
||||
async function initView() {
|
||||
return $async(async () => {
|
||||
try {
|
||||
const profile = await getProfile($scope.state.profileID);
|
||||
|
||||
$scope.formValues = {
|
||||
name: profile.name,
|
||||
profileFileContent: profile.fileContent,
|
||||
};
|
||||
$scope.state.isEditorDirty = false;
|
||||
} catch (err) {
|
||||
Notifications.error('Failure', err, 'Unable to retrieve profile details');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
initView();
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
import angular from 'angular';
|
||||
|
||||
import controller from './editProfileController';
|
||||
|
||||
angular.module('portainer.app').component('editProfileView', {
|
||||
templateUrl: './editProfile.html',
|
||||
controller,
|
||||
});
|
|
@ -11,9 +11,3 @@
|
|||
<settings-open-amt on-submit="($ctrl.onSubmitOpenAMT)" settings="($ctrl.settings)"></settings-open-amt>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12" ng-if="$ctrl.settings">
|
||||
<settings-fdo on-submit="($ctrl.onSubmitFDO)" settings="($ctrl.settings)"></settings-fdo>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import _ from 'lodash-es';
|
||||
import angular from 'angular';
|
||||
|
||||
import { configureFDO } from '@/portainer/hostmanagement/fdo/fdo.service';
|
||||
import { configureAMT } from 'Portainer/hostmanagement/open-amt/open-amt.service';
|
||||
|
||||
angular.module('portainer.app').controller('SettingsEdgeComputeController', SettingsEdgeComputeController);
|
||||
|
@ -31,16 +30,6 @@ export default function SettingsEdgeComputeController($q, $async, $state, Notifi
|
|||
}
|
||||
};
|
||||
|
||||
this.onSubmitFDO = async function (formValues) {
|
||||
try {
|
||||
await configureFDO(formValues);
|
||||
Notifications.success('Success', `FDO successfully ${formValues.enabled ? 'enabled' : 'disabled'}`);
|
||||
$state.reload();
|
||||
} catch (err) {
|
||||
Notifications.error('Failure', err, 'Failed applying changes');
|
||||
}
|
||||
};
|
||||
|
||||
function initView() {
|
||||
$async(async () => {
|
||||
try {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue