From 53cddeb2838850c10b055ae4b4880224198551e7 Mon Sep 17 00:00:00 2001 From: Chaim Lev-Ari Date: Tue, 21 Jul 2020 00:08:20 +0300 Subject: [PATCH] feat(aci): provide container details page (#4037) * feat(aci): show basic details * feat(aci): style container details page * fix(aci): fix container ip * feat(aci): provide functions to get single aci resource * feat(aci): show readable data * feat(aci): style container instance --- app/azure/_module.js | 11 ++ .../containerGroupsDatatable.html | 4 +- app/azure/models/container_group.js | 11 +- app/azure/rest/container_group.js | 5 +- app/azure/rest/resource_group.js | 3 +- app/azure/rest/subscription.js | 3 +- app/azure/services/containerGroupService.js | 6 + app/azure/services/resourceGroupService.js | 6 + app/azure/services/subscriptionService.js | 6 + .../containerInstanceDetails.html | 134 ++++++++++++++++++ .../containerInstanceDetailsController.js | 36 +++++ .../container-instance-details/index.js | 6 + 12 files changed, 225 insertions(+), 6 deletions(-) create mode 100644 app/azure/views/containerinstances/container-instance-details/containerInstanceDetails.html create mode 100644 app/azure/views/containerinstances/container-instance-details/containerInstanceDetailsController.js create mode 100644 app/azure/views/containerinstances/container-instance-details/index.js diff --git a/app/azure/_module.js b/app/azure/_module.js index 68fb30f2f..30fd789b9 100644 --- a/app/azure/_module.js +++ b/app/azure/_module.js @@ -38,6 +38,16 @@ angular.module('portainer.azure', ['portainer.app']).config([ }, }; + var containerInstance = { + name: 'azure.containerinstances.container', + url: '/:id', + views: { + 'content@': { + component: 'containerInstanceDetails', + }, + }, + }; + var containerInstanceCreation = { name: 'azure.containerinstances.new', url: '/new/', @@ -62,6 +72,7 @@ angular.module('portainer.azure', ['portainer.app']).config([ $stateRegistryProvider.register(azure); $stateRegistryProvider.register(containerInstances); + $stateRegistryProvider.register(containerInstance); $stateRegistryProvider.register(containerInstanceCreation); $stateRegistryProvider.register(dashboard); }, diff --git a/app/azure/components/datatables/containergroups-datatable/containerGroupsDatatable.html b/app/azure/components/datatables/containergroups-datatable/containerGroupsDatatable.html index a024c5eb0..da68fd7a0 100644 --- a/app/azure/components/datatables/containergroups-datatable/containerGroupsDatatable.html +++ b/app/azure/components/datatables/containergroups-datatable/containerGroupsDatatable.html @@ -65,8 +65,8 @@ {{ item.Location }} - - {{ item.IPAddress }}:{{ p.port }} + + {{ item.IPAddress }}:{{ p.host }} - diff --git a/app/azure/models/container_group.js b/app/azure/models/container_group.js index dfc9adeef..bab1de3b9 100644 --- a/app/azure/models/container_group.js +++ b/app/azure/models/container_group.js @@ -16,11 +16,20 @@ export function ContainerGroupDefaultModel() { } export function ContainerGroupViewModel(data) { + const addressPorts = data.properties.ipAddress.ports; + const container = data.properties.containers.length ? data.properties.containers[0] : {}; + const containerPorts = container ? container.properties.ports : []; + this.Id = data.id; this.Name = data.name; this.Location = data.location; this.IPAddress = data.properties.ipAddress.ip; - this.Ports = data.properties.ipAddress.ports; + this.Ports = addressPorts.length ? addressPorts.map((binding, index) => ({ container: containerPorts[index].port, host: binding.port, protocol: binding.protocol })) : []; + this.Image = container.properties.image || ''; + this.OSType = data.properties.osType; + this.AllocatePublicIP = data.properties.ipAddress.type === 'Public'; + this.CPU = container.properties.resources.requests.cpu; + this.Memory = container.properties.resources.requests.memoryInGB; } export function CreateContainerGroupRequest(model) { diff --git a/app/azure/rest/container_group.js b/app/azure/rest/container_group.js index 4dc7a002d..f347be44e 100644 --- a/app/azure/rest/container_group.js +++ b/app/azure/rest/container_group.js @@ -34,12 +34,15 @@ angular.module('portainer.azure').factory('ContainerGroup', [ containerGroupName: '@containerGroupName', }, }, + get: { + method: 'GET', + }, } ); resource.query = base.query; resource.create = withResourceGroup.create; - + resource.get = withResourceGroup.get; return resource; }, ]); diff --git a/app/azure/rest/resource_group.js b/app/azure/rest/resource_group.js index 644279f3b..f1f9b520a 100644 --- a/app/azure/rest/resource_group.js +++ b/app/azure/rest/resource_group.js @@ -5,13 +5,14 @@ angular.module('portainer.azure').factory('ResourceGroup', [ function ResourceGroupFactory($resource, API_ENDPOINT_ENDPOINTS, EndpointProvider) { 'use strict'; return $resource( - API_ENDPOINT_ENDPOINTS + '/:endpointId/azure/subscriptions/:subscriptionId/resourcegroups', + API_ENDPOINT_ENDPOINTS + '/:endpointId/azure/subscriptions/:subscriptionId/resourcegroups/:resourceGroupName', { endpointId: EndpointProvider.endpointID, 'api-version': '2018-02-01', }, { query: { method: 'GET', params: { subscriptionId: '@subscriptionId' } }, + get: { method: 'GET' }, } ); }, diff --git a/app/azure/rest/subscription.js b/app/azure/rest/subscription.js index 0711d5f92..c5ccea4ca 100644 --- a/app/azure/rest/subscription.js +++ b/app/azure/rest/subscription.js @@ -5,13 +5,14 @@ angular.module('portainer.azure').factory('Subscription', [ function SubscriptionFactory($resource, API_ENDPOINT_ENDPOINTS, EndpointProvider) { 'use strict'; return $resource( - API_ENDPOINT_ENDPOINTS + '/:endpointId/azure/subscriptions', + API_ENDPOINT_ENDPOINTS + '/:endpointId/azure/subscriptions/:id', { endpointId: EndpointProvider.endpointID, 'api-version': '2016-06-01', }, { query: { method: 'GET' }, + get: { method: 'GET', params: { id: '@id' } }, } ); }, diff --git a/app/azure/services/containerGroupService.js b/app/azure/services/containerGroupService.js index c99b98ada..1a8c60265 100644 --- a/app/azure/services/containerGroupService.js +++ b/app/azure/services/containerGroupService.js @@ -24,6 +24,12 @@ angular.module('portainer.azure').factory('ContainerGroupService', [ return deferred.promise; }; + service.containerGroup = containerGroup; + async function containerGroup(subscriptionId, resourceGroupName, containerGroupName) { + const containerGroup = await ContainerGroup.get({ subscriptionId, resourceGroupName, containerGroupName }).$promise; + return new ContainerGroupViewModel(containerGroup); + } + service.create = function (model, subscriptionId, resourceGroupName) { var payload = new CreateContainerGroupRequest(model); return ContainerGroup.create( diff --git a/app/azure/services/resourceGroupService.js b/app/azure/services/resourceGroupService.js index 4110835f4..9f27dc537 100644 --- a/app/azure/services/resourceGroupService.js +++ b/app/azure/services/resourceGroupService.js @@ -24,6 +24,12 @@ angular.module('portainer.azure').factory('ResourceGroupService', [ return deferred.promise; }; + service.resourceGroup = resourceGroup; + async function resourceGroup(subscriptionId, resourceGroupName) { + const group = await ResourceGroup.get({ subscriptionId, resourceGroupName }).$promise; + return new ResourceGroupViewModel(group); + } + return service; }, ]); diff --git a/app/azure/services/subscriptionService.js b/app/azure/services/subscriptionService.js index 3b22ac664..bfbcfeb61 100644 --- a/app/azure/services/subscriptionService.js +++ b/app/azure/services/subscriptionService.js @@ -24,6 +24,12 @@ angular.module('portainer.azure').factory('SubscriptionService', [ return deferred.promise; }; + service.subscription = subscription; + async function subscription(id) { + const subscription = await Subscription.get({ id }).$promise; + return new SubscriptionViewModel(subscription); + } + return service; }, ]); diff --git a/app/azure/views/containerinstances/container-instance-details/containerInstanceDetails.html b/app/azure/views/containerinstances/container-instance-details/containerInstanceDetails.html new file mode 100644 index 000000000..88c854516 --- /dev/null +++ b/app/azure/views/containerinstances/container-instance-details/containerInstanceDetails.html @@ -0,0 +1,134 @@ + + + Container instances > {{ $ctrl.container.Name }} + + +
+
+ + +
+
+ Azure settings +
+ +
+ +
+ +
+
+ + +
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+ Container configuration +
+ +
+ +
+ +
+
+ + +
+ +
+ +
+
+ + +
+ +
+ +
+
+ + +
+
+ +
+ +
+
+ +
+ host + +
+ + + + + +
+ container + +
+ + +
+
+ + +
+
+ +
+
+ +
+ + +
+ +
+ +
+
+ +
+ Container resources +
+ +
+ +
+ +
+
+ + +
+ +
+ +
+
+ +
+
+
+
+
diff --git a/app/azure/views/containerinstances/container-instance-details/containerInstanceDetailsController.js b/app/azure/views/containerinstances/container-instance-details/containerInstanceDetailsController.js new file mode 100644 index 000000000..c723a8b88 --- /dev/null +++ b/app/azure/views/containerinstances/container-instance-details/containerInstanceDetailsController.js @@ -0,0 +1,36 @@ +class ContainerInstanceDetailsController { + /* @ngInject */ + constructor($state, AzureService, ContainerGroupService, Notifications, ResourceGroupService, SubscriptionService) { + Object.assign(this, { $state, AzureService, ContainerGroupService, Notifications, ResourceGroupService, SubscriptionService }); + + this.state = { + loading: false, + }; + + this.container = null; + this.subscription = null; + this.resourceGroup = null; + } + + async $onInit() { + this.state.loading = true; + const { id } = this.$state.params; + const { subscriptionId, resourceGroupId, containerGroupId } = parseId(id); + try { + this.subscription = await this.SubscriptionService.subscription(subscriptionId); + this.container = await this.ContainerGroupService.containerGroup(subscriptionId, resourceGroupId, containerGroupId); + this.resourceGroup = await this.ResourceGroupService.resourceGroup(subscriptionId, resourceGroupId); + } catch (err) { + this.Notifications.error('Failure', err, 'Unable to retrive container instance details'); + } + this.state.loading = false; + } +} + +function parseId(id) { + const [, subscriptionId, resourceGroupId, , containerGroupId] = id.match(/^\/subscriptions\/(.+)\/resourceGroups\/(.+)\/providers\/(.+)\/containerGroups\/(.+)$/); + + return { subscriptionId, resourceGroupId, containerGroupId }; +} + +export default ContainerInstanceDetailsController; diff --git a/app/azure/views/containerinstances/container-instance-details/index.js b/app/azure/views/containerinstances/container-instance-details/index.js new file mode 100644 index 000000000..8e3b3d179 --- /dev/null +++ b/app/azure/views/containerinstances/container-instance-details/index.js @@ -0,0 +1,6 @@ +import ContainerInstanceDetailsController from './containerInstanceDetailsController.js'; + +angular.module('portainer.azure').component('containerInstanceDetails', { + templateUrl: './containerInstanceDetails.html', + controller: ContainerInstanceDetailsController, +});