mirror of
https://github.com/portainer/portainer.git
synced 2025-08-02 20:35:25 +02:00
refactor(azure): remove Azure ACI endpoint support (#3803)
* feat(templates): remove template management features (#3719) * feat(api): remove template management features * feat(templates): remove template management features * refactor(azure): remove Azure ACI endpoint support
This commit is contained in:
parent
6b41b5ec5d
commit
493de20540
65 changed files with 47 additions and 1791 deletions
|
@ -1,51 +0,0 @@
|
|||
angular.module('portainer.azure', ['portainer.app']).config([
|
||||
'$stateRegistryProvider',
|
||||
function ($stateRegistryProvider) {
|
||||
'use strict';
|
||||
|
||||
var azure = {
|
||||
name: 'azure',
|
||||
url: '/azure',
|
||||
parent: 'root',
|
||||
abstract: true,
|
||||
};
|
||||
|
||||
var containerInstances = {
|
||||
name: 'azure.containerinstances',
|
||||
url: '/containerinstances',
|
||||
views: {
|
||||
'content@': {
|
||||
templateUrl: './views/containerinstances/containerinstances.html',
|
||||
controller: 'AzureContainerInstancesController',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
var containerInstanceCreation = {
|
||||
name: 'azure.containerinstances.new',
|
||||
url: '/new/',
|
||||
views: {
|
||||
'content@': {
|
||||
templateUrl: './views/containerinstances/create/createcontainerinstance.html',
|
||||
controller: 'AzureCreateContainerInstanceController',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
var dashboard = {
|
||||
name: 'azure.dashboard',
|
||||
url: '/dashboard',
|
||||
views: {
|
||||
'content@': {
|
||||
templateUrl: './views/dashboard/dashboard.html',
|
||||
controller: 'AzureDashboardController',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
$stateRegistryProvider.register(azure);
|
||||
$stateRegistryProvider.register(containerInstances);
|
||||
$stateRegistryProvider.register(containerInstanceCreation);
|
||||
$stateRegistryProvider.register(dashboard);
|
||||
},
|
||||
]);
|
|
@ -1,8 +0,0 @@
|
|||
angular.module('portainer.azure').component('azureEndpointConfig', {
|
||||
bindings: {
|
||||
applicationId: '=',
|
||||
tenantId: '=',
|
||||
authenticationKey: '=',
|
||||
},
|
||||
templateUrl: './azureEndpointConfig.html',
|
||||
});
|
|
@ -1,36 +0,0 @@
|
|||
<div>
|
||||
<div class="col-sm-12 form-section-title">
|
||||
Azure configuration
|
||||
</div>
|
||||
<!-- applicationId-input -->
|
||||
<div class="form-group">
|
||||
<label for="azure_credential_appid" class="col-sm-3 col-lg-2 control-label text-left">Application ID</label>
|
||||
<div class="col-sm-9 col-lg-10">
|
||||
<input type="text" class="form-control" name="azure_credential_appid" ng-model="$ctrl.applicationId" placeholder="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" required />
|
||||
</div>
|
||||
</div>
|
||||
<!-- !applicationId-input -->
|
||||
<!-- tenantId-input -->
|
||||
<div class="form-group">
|
||||
<label for="azure_credential_tenantid" class="col-sm-3 col-lg-2 control-label text-left">Tenant ID</label>
|
||||
<div class="col-sm-9 col-lg-10">
|
||||
<input type="text" class="form-control" name="azure_credential_tenantid" ng-model="$ctrl.tenantId" placeholder="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" required />
|
||||
</div>
|
||||
</div>
|
||||
<!-- !tenantId-input -->
|
||||
<!-- authenticationkey-input -->
|
||||
<div class="form-group">
|
||||
<label for="azure_credential_authkey" class="col-sm-3 col-lg-2 control-label text-left">Authentication key</label>
|
||||
<div class="col-sm-9 col-lg-10">
|
||||
<input
|
||||
type="text"
|
||||
class="form-control"
|
||||
name="azure_credential_authkey"
|
||||
ng-model="$ctrl.authenticationKey"
|
||||
placeholder="cOrXoK/1D35w8YQ8nH1/8ZGwzz45JIYD5jxHKXEQknk="
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !authenticationkey-input -->
|
||||
</div>
|
|
@ -1,3 +0,0 @@
|
|||
angular.module('portainer.azure').component('azureSidebarContent', {
|
||||
templateUrl: './azureSidebarContent.html',
|
||||
});
|
|
@ -1,6 +0,0 @@
|
|||
<li class="sidebar-list">
|
||||
<a ui-sref="azure.dashboard" ui-sref-active="active">Dashboard <span class="menu-icon fa fa-tachometer-alt fa-fw"></span></a>
|
||||
</li>
|
||||
<li class="sidebar-list">
|
||||
<a ui-sref="azure.containerinstances" ui-sref-active="active">Container instances <span class="menu-icon fa fa-server fa-fw"></span></a>
|
||||
</li>
|
|
@ -1,105 +0,0 @@
|
|||
<div class="datatable">
|
||||
<rd-widget>
|
||||
<rd-widget-body classes="no-padding">
|
||||
<div class="toolBar">
|
||||
<div class="toolBarTitle"> <i class="fa" ng-class="$ctrl.titleIcon" aria-hidden="true" style="margin-right: 2px;"></i> {{ $ctrl.titleText }} </div>
|
||||
</div>
|
||||
<div class="actionBar">
|
||||
<button type="button" class="btn btn-sm btn-danger" ng-disabled="$ctrl.state.selectedItemCount === 0" ng-click="$ctrl.removeAction($ctrl.state.selectedItems)">
|
||||
<i class="fa fa-trash-alt space-right" aria-hidden="true"></i>Remove
|
||||
</button>
|
||||
<button type="button" class="btn btn-sm btn-primary" ui-sref="azure.containerinstances.new">
|
||||
<i class="fa fa-plus space-right" aria-hidden="true"></i>Add container
|
||||
</button>
|
||||
</div>
|
||||
<div class="searchBar">
|
||||
<i class="fa fa-search searchIcon" aria-hidden="true"></i>
|
||||
<input
|
||||
type="text"
|
||||
class="searchInput"
|
||||
ng-model="$ctrl.state.textFilter"
|
||||
ng-change="$ctrl.onTextFilterChange()"
|
||||
placeholder="Search..."
|
||||
auto-focus
|
||||
ng-model-options="{ debounce: 300 }"
|
||||
/>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover table-filters nowrap-cells">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<span class="md-checkbox">
|
||||
<input id="select_all" type="checkbox" ng-model="$ctrl.state.selectAll" ng-change="$ctrl.selectAll()" />
|
||||
<label for="select_all"></label>
|
||||
</span>
|
||||
<a ng-click="$ctrl.changeOrderBy('Name')">
|
||||
Name
|
||||
<i class="fa fa-sort-alpha-down" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Name' && !$ctrl.state.reverseOrder"></i>
|
||||
<i class="fa fa-sort-alpha-up" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Name' && $ctrl.state.reverseOrder"></i>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
<a ng-click="$ctrl.changeOrderBy('Location')">
|
||||
Location
|
||||
<i class="fa fa-sort-alpha-down" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Location' && !$ctrl.state.reverseOrder"></i>
|
||||
<i class="fa fa-sort-alpha-up" aria-hidden="true" ng-if="$ctrl.state.orderBy === 'Location' && $ctrl.state.reverseOrder"></i>
|
||||
</a>
|
||||
</th>
|
||||
<th>
|
||||
Published Ports
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr
|
||||
dir-paginate="item in ($ctrl.state.filteredDataSet = ($ctrl.dataset | filter:$ctrl.state.textFilter | orderBy:$ctrl.state.orderBy:$ctrl.state.reverseOrder | itemsPerPage: $ctrl.state.paginatedItemLimit))"
|
||||
ng-class="{ active: item.Checked }"
|
||||
>
|
||||
<td>
|
||||
<span class="md-checkbox">
|
||||
<input id="select_{{ $index }}" type="checkbox" ng-model="item.Checked" ng-click="$ctrl.selectItem(item, $event)" />
|
||||
<label for="select_{{ $index }}"></label>
|
||||
</span>
|
||||
<a ui-sref="azure.containerinstances.container({ id: item.Id })">{{ item.Name | truncate: 50 }}</a>
|
||||
</td>
|
||||
<td>{{ item.Location }}</td>
|
||||
<td>
|
||||
<a ng-if="item.Ports.length > 0" ng-repeat="p in item.Ports" class="image-tag" ng-href="http://{{ item.IPAddress }}:{{ p.port }}" target="_blank">
|
||||
<i class="fa fa-external-link-alt" aria-hidden="true"></i> :{{ p.port }}
|
||||
</a>
|
||||
<span ng-if="item.Ports.length == 0">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-if="!$ctrl.dataset">
|
||||
<td colspan="3" class="text-center text-muted">Loading...</td>
|
||||
</tr>
|
||||
<tr ng-if="$ctrl.state.filteredDataSet.length === 0">
|
||||
<td colspan="3" class="text-center text-muted">No container available.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="footer" ng-if="$ctrl.dataset">
|
||||
<div class="infoBar" ng-if="$ctrl.state.selectedItemCount !== 0"> {{ $ctrl.state.selectedItemCount }} item(s) selected </div>
|
||||
<div class="paginationControls">
|
||||
<form class="form-inline">
|
||||
<span class="limitSelector">
|
||||
<span style="margin-right: 5px;">
|
||||
Items per page
|
||||
</span>
|
||||
<select class="form-control" ng-model="$ctrl.state.paginatedItemLimit" ng-change="$ctrl.changePaginationLimit()">
|
||||
<option value="0">All</option>
|
||||
<option value="10">10</option>
|
||||
<option value="25">25</option>
|
||||
<option value="50">50</option>
|
||||
<option value="100">100</option>
|
||||
</select>
|
||||
</span>
|
||||
<dir-pagination-controls max-size="5"></dir-pagination-controls>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
</div>
|
|
@ -1,13 +0,0 @@
|
|||
angular.module('portainer.azure').component('containergroupsDatatable', {
|
||||
templateUrl: './containerGroupsDatatable.html',
|
||||
controller: 'GenericDatatableController',
|
||||
bindings: {
|
||||
title: '@',
|
||||
titleIcon: '@',
|
||||
dataset: '<',
|
||||
tableKey: '@',
|
||||
orderBy: '@',
|
||||
reverseOrder: '<',
|
||||
removeAction: '<',
|
||||
},
|
||||
});
|
|
@ -1,66 +0,0 @@
|
|||
export function ContainerGroupDefaultModel() {
|
||||
this.Location = '';
|
||||
this.OSType = 'Linux';
|
||||
this.Name = '';
|
||||
this.Image = '';
|
||||
this.AllocatePublicIP = true;
|
||||
this.Ports = [
|
||||
{
|
||||
container: 80,
|
||||
host: 80,
|
||||
protocol: 'TCP',
|
||||
},
|
||||
];
|
||||
this.CPU = 1;
|
||||
this.Memory = 1;
|
||||
}
|
||||
|
||||
export function ContainerGroupViewModel(data) {
|
||||
this.Id = data.id;
|
||||
this.Name = data.name;
|
||||
this.Location = data.location;
|
||||
this.IPAddress = data.properties.ipAddress.ip;
|
||||
this.Ports = data.properties.ipAddress.ports;
|
||||
}
|
||||
|
||||
export function CreateContainerGroupRequest(model) {
|
||||
this.location = model.Location;
|
||||
|
||||
var containerPorts = [];
|
||||
var addressPorts = [];
|
||||
for (var i = 0; i < model.Ports.length; i++) {
|
||||
var binding = model.Ports[i];
|
||||
|
||||
containerPorts.push({
|
||||
port: binding.container,
|
||||
});
|
||||
|
||||
addressPorts.push({
|
||||
port: binding.host,
|
||||
protocol: binding.protocol,
|
||||
});
|
||||
}
|
||||
|
||||
this.properties = {
|
||||
osType: model.OSType,
|
||||
containers: [
|
||||
{
|
||||
name: model.Name,
|
||||
properties: {
|
||||
image: model.Image,
|
||||
ports: containerPorts,
|
||||
resources: {
|
||||
requests: {
|
||||
cpu: model.CPU,
|
||||
memoryInGB: model.Memory,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
ipAddress: {
|
||||
type: model.AllocatePublicIP ? 'Public' : 'Private',
|
||||
ports: addressPorts,
|
||||
},
|
||||
};
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
export function LocationViewModel(data) {
|
||||
this.Id = data.id;
|
||||
this.SubscriptionId = data.subscriptionId;
|
||||
this.DisplayName = data.displayName;
|
||||
this.Name = data.name;
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
import _ from 'lodash-es';
|
||||
|
||||
export function ContainerInstanceProviderViewModel(data) {
|
||||
this.Id = data.id;
|
||||
this.Namespace = data.namespace;
|
||||
|
||||
var containerGroupType = _.find(data.resourceTypes, { resourceType: 'containerGroups' });
|
||||
this.Locations = containerGroupType.locations;
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
export function ResourceGroupViewModel(data, subscriptionId) {
|
||||
this.Id = data.id;
|
||||
this.SubscriptionId = subscriptionId;
|
||||
this.Name = data.name;
|
||||
this.Location = data.location;
|
||||
}
|
|
@ -1,4 +0,0 @@
|
|||
export function SubscriptionViewModel(data) {
|
||||
this.Id = data.subscriptionId;
|
||||
this.Name = data.displayName;
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
angular.module('portainer.azure').factory('Azure', [
|
||||
'$http',
|
||||
'API_ENDPOINT_ENDPOINTS',
|
||||
'EndpointProvider',
|
||||
function AzureFactory($http, API_ENDPOINT_ENDPOINTS, EndpointProvider) {
|
||||
'use strict';
|
||||
|
||||
var service = {};
|
||||
|
||||
service.delete = function (id, apiVersion) {
|
||||
var url = API_ENDPOINT_ENDPOINTS + '/' + EndpointProvider.endpointID() + '/azure' + id + '?api-version=' + apiVersion;
|
||||
return $http({
|
||||
method: 'DELETE',
|
||||
url: url,
|
||||
});
|
||||
};
|
||||
|
||||
return service;
|
||||
},
|
||||
]);
|
|
@ -1,45 +0,0 @@
|
|||
angular.module('portainer.azure').factory('ContainerGroup', [
|
||||
'$resource',
|
||||
'API_ENDPOINT_ENDPOINTS',
|
||||
'EndpointProvider',
|
||||
function ContainerGroupFactory($resource, API_ENDPOINT_ENDPOINTS, EndpointProvider) {
|
||||
'use strict';
|
||||
|
||||
var resource = {};
|
||||
|
||||
var base = $resource(
|
||||
API_ENDPOINT_ENDPOINTS + '/:endpointId/azure/subscriptions/:subscriptionId/providers/Microsoft.ContainerInstance/containerGroups',
|
||||
{
|
||||
endpointId: EndpointProvider.endpointID,
|
||||
'api-version': '2018-04-01',
|
||||
},
|
||||
{
|
||||
query: { method: 'GET', params: { subscriptionId: '@subscriptionId' } },
|
||||
}
|
||||
);
|
||||
|
||||
var withResourceGroup = $resource(
|
||||
API_ENDPOINT_ENDPOINTS +
|
||||
'/:endpointId/azure/subscriptions/:subscriptionId/resourceGroups/:resourceGroupName/providers/Microsoft.ContainerInstance/containerGroups/:containerGroupName',
|
||||
{
|
||||
endpointId: EndpointProvider.endpointID,
|
||||
'api-version': '2018-04-01',
|
||||
},
|
||||
{
|
||||
create: {
|
||||
method: 'PUT',
|
||||
params: {
|
||||
subscriptionId: '@subscriptionId',
|
||||
resourceGroupName: '@resourceGroupName',
|
||||
containerGroupName: '@containerGroupName',
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
resource.query = base.query;
|
||||
resource.create = withResourceGroup.create;
|
||||
|
||||
return resource;
|
||||
},
|
||||
]);
|
|
@ -1,18 +0,0 @@
|
|||
angular.module('portainer.azure').factory('Location', [
|
||||
'$resource',
|
||||
'API_ENDPOINT_ENDPOINTS',
|
||||
'EndpointProvider',
|
||||
function LocationFactory($resource, API_ENDPOINT_ENDPOINTS, EndpointProvider) {
|
||||
'use strict';
|
||||
return $resource(
|
||||
API_ENDPOINT_ENDPOINTS + '/:endpointId/azure/subscriptions/:subscriptionId/locations',
|
||||
{
|
||||
endpointId: EndpointProvider.endpointID,
|
||||
'api-version': '2016-06-01',
|
||||
},
|
||||
{
|
||||
query: { method: 'GET', params: { subscriptionId: '@subscriptionId' } },
|
||||
}
|
||||
);
|
||||
},
|
||||
]);
|
|
@ -1,18 +0,0 @@
|
|||
angular.module('portainer.azure').factory('Provider', [
|
||||
'$resource',
|
||||
'API_ENDPOINT_ENDPOINTS',
|
||||
'EndpointProvider',
|
||||
function ProviderFactory($resource, API_ENDPOINT_ENDPOINTS, EndpointProvider) {
|
||||
'use strict';
|
||||
return $resource(
|
||||
API_ENDPOINT_ENDPOINTS + '/:endpointId/azure/subscriptions/:subscriptionId/providers/:providerNamespace',
|
||||
{
|
||||
endpointId: EndpointProvider.endpointID,
|
||||
'api-version': '2018-02-01',
|
||||
},
|
||||
{
|
||||
get: { method: 'GET', params: { subscriptionId: '@subscriptionId', providerNamespace: '@providerNamespace' } },
|
||||
}
|
||||
);
|
||||
},
|
||||
]);
|
|
@ -1,18 +0,0 @@
|
|||
angular.module('portainer.azure').factory('ResourceGroup', [
|
||||
'$resource',
|
||||
'API_ENDPOINT_ENDPOINTS',
|
||||
'EndpointProvider',
|
||||
function ResourceGroupFactory($resource, API_ENDPOINT_ENDPOINTS, EndpointProvider) {
|
||||
'use strict';
|
||||
return $resource(
|
||||
API_ENDPOINT_ENDPOINTS + '/:endpointId/azure/subscriptions/:subscriptionId/resourcegroups',
|
||||
{
|
||||
endpointId: EndpointProvider.endpointID,
|
||||
'api-version': '2018-02-01',
|
||||
},
|
||||
{
|
||||
query: { method: 'GET', params: { subscriptionId: '@subscriptionId' } },
|
||||
}
|
||||
);
|
||||
},
|
||||
]);
|
|
@ -1,18 +0,0 @@
|
|||
angular.module('portainer.azure').factory('Subscription', [
|
||||
'$resource',
|
||||
'API_ENDPOINT_ENDPOINTS',
|
||||
'EndpointProvider',
|
||||
function SubscriptionFactory($resource, API_ENDPOINT_ENDPOINTS, EndpointProvider) {
|
||||
'use strict';
|
||||
return $resource(
|
||||
API_ENDPOINT_ENDPOINTS + '/:endpointId/azure/subscriptions',
|
||||
{
|
||||
endpointId: EndpointProvider.endpointID,
|
||||
'api-version': '2016-06-01',
|
||||
},
|
||||
{
|
||||
query: { method: 'GET' },
|
||||
}
|
||||
);
|
||||
},
|
||||
]);
|
|
@ -1,72 +0,0 @@
|
|||
angular.module('portainer.azure').factory('AzureService', [
|
||||
'$q',
|
||||
'Azure',
|
||||
'SubscriptionService',
|
||||
'ResourceGroupService',
|
||||
'ContainerGroupService',
|
||||
'ProviderService',
|
||||
function AzureServiceFactory($q, Azure, SubscriptionService, ResourceGroupService, ContainerGroupService, ProviderService) {
|
||||
'use strict';
|
||||
var service = {};
|
||||
|
||||
service.deleteContainerGroup = function (id) {
|
||||
return Azure.delete(id, '2018-04-01');
|
||||
};
|
||||
|
||||
service.createContainerGroup = function (model, subscriptionId, resourceGroupName) {
|
||||
return ContainerGroupService.create(model, subscriptionId, resourceGroupName);
|
||||
};
|
||||
|
||||
service.subscriptions = function () {
|
||||
return SubscriptionService.subscriptions();
|
||||
};
|
||||
|
||||
service.containerInstanceProvider = function (subscriptions) {
|
||||
return retrieveResourcesForEachSubscription(subscriptions, ProviderService.containerInstanceProvider);
|
||||
};
|
||||
|
||||
service.resourceGroups = function (subscriptions) {
|
||||
return retrieveResourcesForEachSubscription(subscriptions, ResourceGroupService.resourceGroups);
|
||||
};
|
||||
|
||||
service.containerGroups = function (subscriptions) {
|
||||
return retrieveResourcesForEachSubscription(subscriptions, ContainerGroupService.containerGroups);
|
||||
};
|
||||
|
||||
service.aggregate = function (resourcesBySubcription) {
|
||||
var aggregatedResources = [];
|
||||
Object.keys(resourcesBySubcription).forEach(function (key) {
|
||||
aggregatedResources = aggregatedResources.concat(resourcesBySubcription[key]);
|
||||
});
|
||||
return aggregatedResources;
|
||||
};
|
||||
|
||||
function retrieveResourcesForEachSubscription(subscriptions, resourceQuery) {
|
||||
var deferred = $q.defer();
|
||||
|
||||
var resources = {};
|
||||
|
||||
var resourceQueries = [];
|
||||
for (var i = 0; i < subscriptions.length; i++) {
|
||||
var subscription = subscriptions[i];
|
||||
resourceQueries.push(resourceQuery(subscription.Id));
|
||||
}
|
||||
|
||||
$q.all(resourceQueries)
|
||||
.then(function success(data) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
var result = data[i];
|
||||
resources[subscriptions[i].Id] = result;
|
||||
}
|
||||
deferred.resolve(resources);
|
||||
})
|
||||
.catch(function error(err) {
|
||||
deferred.reject({ msg: 'Unable to retrieve resources', err: err });
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
return service;
|
||||
},
|
||||
]);
|
|
@ -1,41 +0,0 @@
|
|||
import { ContainerGroupViewModel, CreateContainerGroupRequest } from '../models/container_group';
|
||||
|
||||
angular.module('portainer.azure').factory('ContainerGroupService', [
|
||||
'$q',
|
||||
'ContainerGroup',
|
||||
function ContainerGroupServiceFactory($q, ContainerGroup) {
|
||||
'use strict';
|
||||
var service = {};
|
||||
|
||||
service.containerGroups = function (subscriptionId) {
|
||||
var deferred = $q.defer();
|
||||
|
||||
ContainerGroup.query({ subscriptionId: subscriptionId })
|
||||
.$promise.then(function success(data) {
|
||||
var containerGroups = data.value.map(function (item) {
|
||||
return new ContainerGroupViewModel(item);
|
||||
});
|
||||
deferred.resolve(containerGroups);
|
||||
})
|
||||
.catch(function error(err) {
|
||||
deferred.reject({ msg: 'Unable to retrieve container groups', err: err });
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
service.create = function (model, subscriptionId, resourceGroupName) {
|
||||
var payload = new CreateContainerGroupRequest(model);
|
||||
return ContainerGroup.create(
|
||||
{
|
||||
subscriptionId: subscriptionId,
|
||||
resourceGroupName: resourceGroupName,
|
||||
containerGroupName: model.Name,
|
||||
},
|
||||
payload
|
||||
).$promise;
|
||||
};
|
||||
|
||||
return service;
|
||||
},
|
||||
]);
|
|
@ -1,29 +0,0 @@
|
|||
import { LocationViewModel } from '../models/location';
|
||||
|
||||
angular.module('portainer.azure').factory('LocationService', [
|
||||
'$q',
|
||||
'Location',
|
||||
function LocationServiceFactory($q, Location) {
|
||||
'use strict';
|
||||
var service = {};
|
||||
|
||||
service.locations = function (subscriptionId) {
|
||||
var deferred = $q.defer();
|
||||
|
||||
Location.query({ subscriptionId: subscriptionId })
|
||||
.$promise.then(function success(data) {
|
||||
var locations = data.value.map(function (item) {
|
||||
return new LocationViewModel(item);
|
||||
});
|
||||
deferred.resolve(locations);
|
||||
})
|
||||
.catch(function error(err) {
|
||||
deferred.reject({ msg: 'Unable to retrieve locations', err: err });
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
return service;
|
||||
},
|
||||
]);
|
|
@ -1,27 +0,0 @@
|
|||
import { ContainerInstanceProviderViewModel } from '../models/provider';
|
||||
|
||||
angular.module('portainer.azure').factory('ProviderService', [
|
||||
'$q',
|
||||
'Provider',
|
||||
function ProviderServiceFactory($q, Provider) {
|
||||
'use strict';
|
||||
var service = {};
|
||||
|
||||
service.containerInstanceProvider = function (subscriptionId) {
|
||||
var deferred = $q.defer();
|
||||
|
||||
Provider.get({ subscriptionId: subscriptionId, providerNamespace: 'Microsoft.ContainerInstance' })
|
||||
.$promise.then(function success(data) {
|
||||
var provider = new ContainerInstanceProviderViewModel(data);
|
||||
deferred.resolve(provider);
|
||||
})
|
||||
.catch(function error(err) {
|
||||
deferred.reject({ msg: 'Unable to retrieve provider', err: err });
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
return service;
|
||||
},
|
||||
]);
|
|
@ -1,29 +0,0 @@
|
|||
import { ResourceGroupViewModel } from '../models/resource_group';
|
||||
|
||||
angular.module('portainer.azure').factory('ResourceGroupService', [
|
||||
'$q',
|
||||
'ResourceGroup',
|
||||
function ResourceGroupServiceFactory($q, ResourceGroup) {
|
||||
'use strict';
|
||||
var service = {};
|
||||
|
||||
service.resourceGroups = function (subscriptionId) {
|
||||
var deferred = $q.defer();
|
||||
|
||||
ResourceGroup.query({ subscriptionId: subscriptionId })
|
||||
.$promise.then(function success(data) {
|
||||
var resourceGroups = data.value.map(function (item) {
|
||||
return new ResourceGroupViewModel(item, subscriptionId);
|
||||
});
|
||||
deferred.resolve(resourceGroups);
|
||||
})
|
||||
.catch(function error(err) {
|
||||
deferred.reject({ msg: 'Unable to retrieve resource groups', err: err });
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
return service;
|
||||
},
|
||||
]);
|
|
@ -1,29 +0,0 @@
|
|||
import { SubscriptionViewModel } from '../models/subscription';
|
||||
|
||||
angular.module('portainer.azure').factory('SubscriptionService', [
|
||||
'$q',
|
||||
'Subscription',
|
||||
function SubscriptionServiceFactory($q, Subscription) {
|
||||
'use strict';
|
||||
var service = {};
|
||||
|
||||
service.subscriptions = function () {
|
||||
var deferred = $q.defer();
|
||||
|
||||
Subscription.query({})
|
||||
.$promise.then(function success(data) {
|
||||
var subscriptions = data.value.map(function (item) {
|
||||
return new SubscriptionViewModel(item);
|
||||
});
|
||||
deferred.resolve(subscriptions);
|
||||
})
|
||||
.catch(function error(err) {
|
||||
deferred.reject({ msg: 'Unable to retrieve subscriptions', err: err });
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
return service;
|
||||
},
|
||||
]);
|
|
@ -1,44 +0,0 @@
|
|||
angular.module('portainer.azure').controller('AzureContainerInstancesController', [
|
||||
'$scope',
|
||||
'$state',
|
||||
'AzureService',
|
||||
'Notifications',
|
||||
function ($scope, $state, AzureService, Notifications) {
|
||||
function initView() {
|
||||
AzureService.subscriptions()
|
||||
.then(function success(data) {
|
||||
var subscriptions = data;
|
||||
return AzureService.containerGroups(subscriptions);
|
||||
})
|
||||
.then(function success(data) {
|
||||
$scope.containerGroups = AzureService.aggregate(data);
|
||||
})
|
||||
.catch(function error(err) {
|
||||
Notifications.error('Failure', err, 'Unable to load container groups');
|
||||
});
|
||||
}
|
||||
|
||||
$scope.deleteAction = function (selectedItems) {
|
||||
var actionCount = selectedItems.length;
|
||||
angular.forEach(selectedItems, function (item) {
|
||||
AzureService.deleteContainerGroup(item.Id)
|
||||
.then(function success() {
|
||||
Notifications.success('Container group successfully removed', item.Name);
|
||||
var index = $scope.containerGroups.indexOf(item);
|
||||
$scope.containerGroups.splice(index, 1);
|
||||
})
|
||||
.catch(function error(err) {
|
||||
Notifications.error('Failure', err, 'Unable to remove container group');
|
||||
})
|
||||
.finally(function final() {
|
||||
--actionCount;
|
||||
if (actionCount === 0) {
|
||||
$state.reload();
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
initView();
|
||||
},
|
||||
]);
|
|
@ -1,21 +0,0 @@
|
|||
<rd-header>
|
||||
<rd-header-title title-text="Container list">
|
||||
<a data-toggle="tooltip" title="Refresh" ui-sref="azure.containerinstances" ui-sref-opts="{reload: true}">
|
||||
<i class="fa fa-sync" aria-hidden="true"></i>
|
||||
</a>
|
||||
</rd-header-title>
|
||||
<rd-header-content>Container instances</rd-header-content>
|
||||
</rd-header>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<containergroups-datatable
|
||||
title-text="Containers"
|
||||
title-icon="fa-server"
|
||||
dataset="containerGroups"
|
||||
table-key="containergroups"
|
||||
order-by="Name"
|
||||
remove-action="deleteAction"
|
||||
></containergroups-datatable>
|
||||
</div>
|
||||
</div>
|
|
@ -1,93 +0,0 @@
|
|||
import { ContainerGroupDefaultModel } from '../../../models/container_group';
|
||||
|
||||
angular.module('portainer.azure').controller('AzureCreateContainerInstanceController', [
|
||||
'$q',
|
||||
'$scope',
|
||||
'$state',
|
||||
'AzureService',
|
||||
'Notifications',
|
||||
function ($q, $scope, $state, AzureService, Notifications) {
|
||||
var allResourceGroups = [];
|
||||
var allProviders = [];
|
||||
|
||||
$scope.state = {
|
||||
actionInProgress: false,
|
||||
selectedSubscription: null,
|
||||
selectedResourceGroup: null,
|
||||
};
|
||||
|
||||
$scope.changeSubscription = function () {
|
||||
var selectedSubscription = $scope.state.selectedSubscription;
|
||||
updateResourceGroupsAndLocations(selectedSubscription, allResourceGroups, allProviders);
|
||||
};
|
||||
|
||||
$scope.addPortBinding = function () {
|
||||
$scope.model.Ports.push({ host: '', container: '', protocol: 'TCP' });
|
||||
};
|
||||
|
||||
$scope.removePortBinding = function (index) {
|
||||
$scope.model.Ports.splice(index, 1);
|
||||
};
|
||||
|
||||
$scope.create = function () {
|
||||
var model = $scope.model;
|
||||
var subscriptionId = $scope.state.selectedSubscription.Id;
|
||||
var resourceGroupName = $scope.state.selectedResourceGroup.Name;
|
||||
|
||||
$scope.state.actionInProgress = true;
|
||||
AzureService.createContainerGroup(model, subscriptionId, resourceGroupName)
|
||||
.then(function success() {
|
||||
Notifications.success('Container successfully created', model.Name);
|
||||
$state.go('azure.containerinstances');
|
||||
})
|
||||
.catch(function error(err) {
|
||||
Notifications.error('Failure', err, 'Unable to create container');
|
||||
})
|
||||
.finally(function final() {
|
||||
$scope.state.actionInProgress = false;
|
||||
});
|
||||
};
|
||||
|
||||
function updateResourceGroupsAndLocations(subscription, resourceGroups, providers) {
|
||||
$scope.state.selectedResourceGroup = resourceGroups[subscription.Id][0];
|
||||
$scope.resourceGroups = resourceGroups[subscription.Id];
|
||||
|
||||
var currentSubLocations = providers[subscription.Id].Locations;
|
||||
$scope.model.Location = currentSubLocations[0];
|
||||
$scope.locations = currentSubLocations;
|
||||
}
|
||||
|
||||
function initView() {
|
||||
var model = new ContainerGroupDefaultModel();
|
||||
|
||||
AzureService.subscriptions()
|
||||
.then(function success(data) {
|
||||
var subscriptions = data;
|
||||
$scope.state.selectedSubscription = subscriptions[0];
|
||||
$scope.subscriptions = subscriptions;
|
||||
|
||||
return $q.all({
|
||||
resourceGroups: AzureService.resourceGroups(subscriptions),
|
||||
containerInstancesProviders: AzureService.containerInstanceProvider(subscriptions),
|
||||
});
|
||||
})
|
||||
.then(function success(data) {
|
||||
var resourceGroups = data.resourceGroups;
|
||||
allResourceGroups = resourceGroups;
|
||||
|
||||
var containerInstancesProviders = data.containerInstancesProviders;
|
||||
allProviders = containerInstancesProviders;
|
||||
|
||||
$scope.model = model;
|
||||
|
||||
var selectedSubscription = $scope.state.selectedSubscription;
|
||||
updateResourceGroupsAndLocations(selectedSubscription, resourceGroups, containerInstancesProviders);
|
||||
})
|
||||
.catch(function error(err) {
|
||||
Notifications.error('Failure', err, 'Unable to retrieve Azure resources');
|
||||
});
|
||||
}
|
||||
|
||||
initView();
|
||||
},
|
||||
]);
|
|
@ -1,167 +0,0 @@
|
|||
<rd-header>
|
||||
<rd-header-title title-text="Create container instance"></rd-header-title>
|
||||
<rd-header-content> <a ui-sref="azure.containerinstances">Container instances</a> > Add container </rd-header-content>
|
||||
</rd-header>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-12">
|
||||
<rd-widget>
|
||||
<rd-widget-body>
|
||||
<form class="form-horizontal" autocomplete="off">
|
||||
<div class="col-sm-12 form-section-title">
|
||||
Azure settings
|
||||
</div>
|
||||
<!-- subscription-input -->
|
||||
<div class="form-group">
|
||||
<label for="azure_subscription" class="col-sm-1 control-label text-left">Subscription</label>
|
||||
<div class="col-sm-11">
|
||||
<select
|
||||
class="form-control"
|
||||
name="azure_subscription"
|
||||
ng-model="state.selectedSubscription"
|
||||
ng-options="subscription.Name for subscription in subscriptions"
|
||||
ng-change="changeSubscription()"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !subscription-input -->
|
||||
<!-- resourcegroup-input -->
|
||||
<div class="form-group">
|
||||
<label for="azure_resourcegroup" class="col-sm-1 control-label text-left">Resource group</label>
|
||||
<div class="col-sm-11">
|
||||
<select
|
||||
class="form-control"
|
||||
name="azure_resourcegroup"
|
||||
ng-model="state.selectedResourceGroup"
|
||||
ng-options="resourceGroup.Name for resourceGroup in resourceGroups"
|
||||
></select>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !resourcegroup-input -->
|
||||
<!-- location-input -->
|
||||
<div class="form-group">
|
||||
<label for="azure_location" class="col-sm-1 control-label text-left">Location</label>
|
||||
<div class="col-sm-11">
|
||||
<select class="form-control" name="azure_location" ng-model="model.Location" ng-options="location for location in locations"></select>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !location-input -->
|
||||
<div class="col-sm-12 form-section-title">
|
||||
Container configuration
|
||||
</div>
|
||||
<!-- name-input -->
|
||||
<div class="form-group">
|
||||
<label for="container_name" class="col-sm-1 control-label text-left">Name</label>
|
||||
<div class="col-sm-11">
|
||||
<input type="text" class="form-control" ng-model="model.Name" name="container_name" placeholder="e.g. myContainer" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- !name-input -->
|
||||
<!-- image-input -->
|
||||
<div class="form-group">
|
||||
<label for="image_name" class="col-sm-1 control-label text-left">Image</label>
|
||||
<div class="col-sm-11">
|
||||
<input type="text" class="form-control" ng-model="model.Image" name="image_name" placeholder="e.g. nginx:alpine" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- !image-input -->
|
||||
<!-- os-input -->
|
||||
<div class="form-group">
|
||||
<label for="container_os" class="col-sm-1 control-label text-left">OS</label>
|
||||
<div class="col-sm-11">
|
||||
<select class="form-control" ng-model="model.OSType" name="container_os">
|
||||
<option value="Linux">Linux</option>
|
||||
<option value="Windows">Windows</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !os-input -->
|
||||
<!-- port-mapping -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<label class="control-label text-left">Port mapping</label>
|
||||
<span class="label label-default interactive" style="margin-left: 10px;" ng-click="addPortBinding()">
|
||||
<i class="fa fa-plus-circle" aria-hidden="true"></i> map additional port
|
||||
</span>
|
||||
</div>
|
||||
<!-- port-mapping-input-list -->
|
||||
<div class="col-sm-12 form-inline" style="margin-top: 10px;">
|
||||
<div ng-repeat="binding in model.Ports" style="margin-top: 2px;">
|
||||
<!-- host-port -->
|
||||
<div class="input-group col-sm-4 input-group-sm">
|
||||
<span class="input-group-addon">host</span>
|
||||
<input type="text" class="form-control" ng-model="binding.host" placeholder="e.g. 80" />
|
||||
</div>
|
||||
<!-- !host-port -->
|
||||
<span style="margin: 0 10px 0 10px;">
|
||||
<i class="fa fa-long-arrow-alt-right" aria-hidden="true"></i>
|
||||
</span>
|
||||
<!-- container-port -->
|
||||
<div class="input-group col-sm-4 input-group-sm">
|
||||
<span class="input-group-addon">container</span>
|
||||
<input type="text" class="form-control" ng-model="binding.container" placeholder="e.g. 80" />
|
||||
</div>
|
||||
<!-- !container-port -->
|
||||
<!-- protocol-actions -->
|
||||
<div class="input-group col-sm-3 input-group-sm">
|
||||
<div class="btn-group btn-group-sm">
|
||||
<label class="btn btn-primary" ng-model="binding.protocol" uib-btn-radio="'TCP'">TCP</label>
|
||||
<label class="btn btn-primary" ng-model="binding.protocol" uib-btn-radio="'UDP'">UDP</label>
|
||||
</div>
|
||||
<button class="btn btn-sm btn-danger" type="button" ng-click="removePortBinding($index)">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
<!-- !protocol-actions -->
|
||||
</div>
|
||||
</div>
|
||||
<!-- !port-mapping-input-list -->
|
||||
</div>
|
||||
<!-- !port-mapping -->
|
||||
<!-- public-ip -->
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<label for="public_ip" class="control-label text-left">
|
||||
Allocate public IP address
|
||||
</label>
|
||||
<label class="switch" style="margin-left: 20px;"> <input type="checkbox" name="public_ip" ng-model="model.AllocatePublicIP" /><i></i> </label>
|
||||
</div>
|
||||
</div>
|
||||
<!-- public-ip -->
|
||||
<div class="col-sm-12 form-section-title">
|
||||
Container resources
|
||||
</div>
|
||||
<!-- cpu-input -->
|
||||
<div class="form-group">
|
||||
<label for="container_cpu" class="col-sm-1 control-label text-left">CPU</label>
|
||||
<div class="col-sm-11">
|
||||
<input type="number" class="form-control" ng-model="model.CPU" name="container_cpu" placeholder="1" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- !cpu-input -->
|
||||
<!-- memory-input -->
|
||||
<div class="form-group">
|
||||
<label for="container_memory" class="col-sm-1 control-label text-left">Memory</label>
|
||||
<div class="col-sm-11">
|
||||
<input type="number" class="form-control" ng-model="model.Memory" name="container_memory" placeholder="1" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- !memory-input -->
|
||||
<!-- actions -->
|
||||
<div class="col-sm-12 form-section-title">
|
||||
Actions
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<button type="button" class="btn btn-primary btn-sm" ng-disabled="state.actionInProgress" ng-click="create()" button-spinner="state.actionInProgress">
|
||||
<span ng-hide="state.actionInProgress">Deploy the container</span>
|
||||
<span ng-show="state.actionInProgress">Deployment in progress...</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- !actions -->
|
||||
</form>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
</div>
|
||||
</div>
|
|
@ -1,33 +0,0 @@
|
|||
<rd-header>
|
||||
<rd-header-title title-text="Home"></rd-header-title>
|
||||
<rd-header-content>Dashboard</rd-header-content>
|
||||
</rd-header>
|
||||
|
||||
<div class="row" ng-if="subscriptions">
|
||||
<div class="col-sm-12 col-md-6">
|
||||
<a ui-sref="azure.subscriptions">
|
||||
<rd-widget>
|
||||
<rd-widget-body>
|
||||
<div class="widget-icon blue pull-left">
|
||||
<i class="fa fa-th-list"></i>
|
||||
</div>
|
||||
<div class="title">{{ subscriptions.length }}</div>
|
||||
<div class="comment">Subscriptions</div>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-sm-12 col-md-6" ng-if="resourceGroups">
|
||||
<a ui-sref="azure.resourceGroups">
|
||||
<rd-widget>
|
||||
<rd-widget-body>
|
||||
<div class="widget-icon blue pull-left">
|
||||
<i class="fa fa-th-list"></i>
|
||||
</div>
|
||||
<div class="title">{{ resourceGroups.length }}</div>
|
||||
<div class="comment">Resource groups</div>
|
||||
</rd-widget-body>
|
||||
</rd-widget>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
|
@ -1,23 +0,0 @@
|
|||
angular.module('portainer.azure').controller('AzureDashboardController', [
|
||||
'$scope',
|
||||
'AzureService',
|
||||
'Notifications',
|
||||
function ($scope, AzureService, Notifications) {
|
||||
function initView() {
|
||||
AzureService.subscriptions()
|
||||
.then(function success(data) {
|
||||
var subscriptions = data;
|
||||
$scope.subscriptions = subscriptions;
|
||||
return AzureService.resourceGroups(subscriptions);
|
||||
})
|
||||
.then(function success(data) {
|
||||
$scope.resourceGroups = AzureService.aggregate(data);
|
||||
})
|
||||
.catch(function error(err) {
|
||||
Notifications.error('Failure', err, 'Unable to load dashboard data');
|
||||
});
|
||||
}
|
||||
|
||||
initView();
|
||||
},
|
||||
]);
|
Loading…
Add table
Add a link
Reference in a new issue