diff --git a/deploy-board/deploy_board/settings.py b/deploy-board/deploy_board/settings.py index 130ec5f91e..3521925257 100644 --- a/deploy-board/deploy_board/settings.py +++ b/deploy-board/deploy_board/settings.py @@ -304,15 +304,15 @@ TELETRAAN_TRANSFER_OWNERSHIP_URL = os.getenv("TELETRAAN_TRANSFER_OWNERSHIP_URL", None) TELETRAAN_RESOURCE_OWNERSHIP_WIKI_URL = os.getenv("TELETRAAN_RESOURCE_OWNERSHIP_WIKI_URL", None) TELETRAAN_PROJECT_URL_FORMAT = os.getenv("TELETRAAN_PROJECT_URL_FORMAT", None) -RODIMUS_CLUSTER_REPLACEMENT_WIKI_URL = os.getenv("RODIMUS_CLUSTER_REPLACEMENT_WIKI_URL", None) -RODIMUS_AUTO_CLUSTER_REFRESH_WIKI_URL = os.getenv("RODIMUS_AUTO_CLUSTER_REFRESH_WIKI_URL", None) # use Rodimus if present -RODIMUS_SERVICE_URL = os.getenv("RODIMUS_SERVICE_URL", None) -RODIMUS_SERVICE_VERSION = os.getenv("RODIMUS_SERVICE_VERSION", None) -RODIMUS_SERVICE_PROXY_HTTP = os.getenv("RODIMUS_SERVICE_PROXY_HTTP", None) -RODIMUS_SERVICE_PROXY_HTTPS = os.getenv("RODIMUS_SERVICE_PROXY_HTTPS", None) -RODIMUS_SERVICE_USE_BEARER = os.getenv("RODIMUS_SERVICE_USE_BEARER", "true").lower() != "false" # default is True +RODIMUS_SERVICE_URL = os.getenv("TELETRAAN_RODIMUS_SERVICE_URL", None) +RODIMUS_SERVICE_VERSION = os.getenv("TELETRAAN_RODIMUS_SERVICE_VERSION", None) +RODIMUS_SERVICE_PROXY_HTTP = os.getenv("TELETRAAN_RODIMUS_SERVICE_PROXY_HTTP", None) +RODIMUS_SERVICE_PROXY_HTTPS = os.getenv("TELETRAAN_RODIMUS_SERVICE_PROXY_HTTPS", None) +RODIMUS_SERVICE_USE_BEARER = os.getenv("TELETRAAN_RODIMUS_SERVICE_USE_BEARER", "true").lower() != "false" # default is True +RODIMUS_CLUSTER_REPLACEMENT_WIKI_URL = os.getenv("TELETRAAN_RODIMUS_CLUSTER_REPLACEMENT_WIKI_URL", None) +RODIMUS_AUTO_CLUSTER_REFRESH_WIKI_URL = os.getenv("TELETRAAN_RODIMUS_AUTO_CLUSTER_REFRESH_WIKI_URL", None) if IS_PINTEREST: # use knox if present diff --git a/deploy-board/deploy_board/static/js/components/clusterconfigcomponents.js b/deploy-board/deploy_board/static/js/components/clusterconfigcomponents.js index 88cb60df78..18a737d699 100644 --- a/deploy-board/deploy_board/static/js/components/clusterconfigcomponents.js +++ b/deploy-board/deploy_board/static/js/components/clusterconfigcomponents.js @@ -83,24 +83,21 @@ Vue.component('baseimage-select', { warningText: '', } }, - props: ['imageNames', 'baseImages', 'selectedImageName', 'selectedBaseImage', 'pinImage', 'pinImageEnabled'], + props: ['imageNames', 'baseImages', 'selectedImageName', 'selectedBaseImage', 'pinImage', 'pinImageEnabled', 'accountOwnerId'], methods: { helpClick: function () { this.$emit('help-clicked') }, - tryShowWarning: function (baseImageId, pinImage) { + tryShowWarning: function (baseImageId, pinImage, accountOwnerId) { if (!pinImage) { this.showWarning = false; } else { - const ONE_DAY = 1000 * 60 * 60 * 24; - let baseImage = this.baseImages.find(i => i.value == baseImageId); - let age = Math.round((Date.now() - new Date(baseImage.publishDate)) / ONE_DAY); - if (age > 180) { - this.warningText = `The base image configured is over 180 days old (${age} days). Please consider update or opt-in Auto Update (Unpin image).`; - this.showWarning = true; - } else { - this.showWarning = false; - } + const baseImage = this.baseImages.find(i => i.value === baseImageId); + const warnings = this.createWarningMessages(baseImage, accountOwnerId); + this.showWarning = warnings.length > 0; + this.warningText = '\n' + warnings.map( + (item, index) => `${index + 1}. ${item}` + ).join('\n'); } }, pinImageClick: function (pin) { @@ -110,12 +107,44 @@ Vue.component('baseimage-select', { } else { this.showWarning = false; } + }, + + createWarningMessages: function(baseImage, accountOwnerId) { + const messages = []; + const oneDay = 1000 * 60 * 60 * 24; + const imageCreationDate = new Date(baseImage.publishDate); + let age = Math.round((Date.now() - imageCreationDate) / oneDay); + if (age > 180) { + messages.push( + `The base image configured is over 180 days old (${age} days). ` + + "Please consider update or opt-in Auto Update (Unpin image)." + ); + } + + const sharedImagesCreationDate = new Date("2024-03-15"); + const primaryAccount = '998131032990'; + if (accountOwnerId && accountOwnerId !== primaryAccount + && imageCreationDate < sharedImagesCreationDate) { + const options = { day: 'numeric', month: 'long', year: 'numeric' }; + const formattedDate = sharedImagesCreationDate.toLocaleDateString('en-GB', options); + messages.push( + "The base image has configured in primary account and may not works in " + + `the sub account, please use base images after ${formattedDate} ` + + "for sub accounts."); + } + return messages; } }, watch: { selectedBaseImage: function (baseImageId) { - this.tryShowWarning(baseImageId, this.pinImage); + this.tryShowWarning(baseImageId, this.pinImage, this.accountOwnerId); + }, + accountOwnerId: function (newAccountOwnerId) { + this.tryShowWarning(this.selectedBaseImage, this.pinImage, newAccountOwnerId); } + }, + mounted() { + this.tryShowWarning(this.selectedBaseImage, this.pinImage, this.accountOwnerId); } }); @@ -189,6 +218,11 @@ Vue.component('aws-user-data', { acc[entry.name] = entry.value; return acc; }, {}); + + // hide link for cmp_base profiles + if (userDataObj['pinfo_role'] === 'cmp_base') { + return ' '; + } const hieraPaths = this.hierapaths.trim().split("\n").reduce( (acc, line) => acc.set(line, [ ...new Set(line.matchAll(/(?<=%{::)[a-z0-9_]+(?=})/gi).map(val => val[0])) @@ -196,7 +230,7 @@ Vue.component('aws-user-data', { new Map() ); - const matchingPuppetPath = hieraPaths.keys().find(line => + const matchingPuppetPath = hieraPaths.keys().find(line => hieraPaths.get(line).every(variable => !!userDataObj[variable]) ); const variables = hieraPaths.get(matchingPuppetPath); diff --git a/deploy-board/deploy_board/templates/accounts/account_details.html b/deploy-board/deploy_board/templates/accounts/account_details.html new file mode 100644 index 0000000000..24082d9e6f --- /dev/null +++ b/deploy-board/deploy_board/templates/accounts/account_details.html @@ -0,0 +1,46 @@ +{% extends 'accounts/accounts_base.html' %} + +{% block breadcrumb-items %} + +{% endblock %} + +{% block main %} +
+
+

Account Details

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
ID{{ account.id }}
Owner ID {{ account.data.ownerId }}
Name{{ account.name }}
Cloud Provider{{ account.cloudProvider }}
Cell{{ account.cell }}
Description{{ account.description }}
+
+
+ +{% endblock %} diff --git a/deploy-board/deploy_board/templates/accounts/accounts.html b/deploy-board/deploy_board/templates/accounts/accounts.html index ecfa992c32..37b6c8ccb1 100644 --- a/deploy-board/deploy_board/templates/accounts/accounts.html +++ b/deploy-board/deploy_board/templates/accounts/accounts.html @@ -21,6 +21,7 @@

Account Details

Name Cell Provider + @@ -31,6 +32,7 @@

Account Details

{{ account.name }} {{ account.cell }} {{ account.cloudProvider }} + Details {% endfor %} diff --git a/deploy-board/deploy_board/templates/configs/new_capacity_adv.html b/deploy-board/deploy_board/templates/configs/new_capacity_adv.html index fea43a870a..45e7ec52e9 100644 --- a/deploy-board/deploy_board/templates/configs/new_capacity_adv.html +++ b/deploy-board/deploy_board/templates/configs/new_capacity_adv.html @@ -50,7 +50,7 @@

Capacity

- @@ -153,7 +153,8 @@

Capacity

confirmDialogId: "createHostGroup", currentProvider: info.defaultProvider, currentAccountId: info.defaultAccountId, - currentCell: info.defaultCell, + currentAccountOwnerId: getAccountOwnerId(info.defaultAccountId), + currentCell: getDefaultCell(info.defaultAccountId), currentArch: info.defaultArch, hostTypeHelpData:[], hostTypeOptions: info.hostTypes.map( @@ -165,7 +166,6 @@

Capacity

isDisabled: item.retired || item.blessed_status === "DECOMMISSIONING" } }), - cellValue: info.defaultCell, archValue: info.defaultArch, imageNameValue: info.defaultBaseImage, imageNames: mapImageNameToOptions(info.baseImageNames), @@ -186,14 +186,7 @@

Capacity

value: o, text: o } }), - cells: info.cells.map( - function (item) { - return { - value: item.name, - text: item.name, - isSelected: item.name == info.defaultCell - } - }), + cells: getUiCells(info.defaultAccountId), arches: info.arches.map( function (item) { return { @@ -308,11 +301,12 @@

Capacity

} }, accountChange: function (value) { - capacitySetting.currentAccountId = value; + this.currentAccountId = value; + this.currentAccountOwnerId = getAccountOwnerId(value); + this.cells = getUiCells(value); + this.cellChange(getDefaultCell(value)); }, cellChange: function(value) { - capacitySetting.currentCell = value; - capacitySetting.cellValue = value; capacitySetting.currentCell = value; // grab all the image names for this cell var scope = this; @@ -328,51 +322,59 @@

Capacity

xhr.setRequestHeader("X-CSRFToken", csrftoken); }, success: function (data) { - capacitySetting.imageNames = mapImageNameToOptions(data); - scope.imageNameChange(data[0]); + capacitySetting.imageNames = data ? mapImageNameToOptions(data) : []; + scope.imageNameChange(data && data.length > 0 ? data[0] : null); }, error: function (data) { globalNotificationBanner.error = data } }); + + const securityZonesUrl = + `${location.protocol}//${location.host}/clouds/securityzones/${provider}/${cell}` + + `?accountId=${this.currentAccountId}` // grab all security zone for this cell $.ajax({ type: 'GET', - url: location.protocol + '//' + location.host + '/clouds/securityzones/' + provider + '/' + cell, + url: securityZonesUrl, dataType: "json", beforeSend: function (xhr) { var csrftoken = getCookie('csrftoken'); xhr.setRequestHeader("X-CSRFToken", csrftoken); }, success: function (data) { - capacitySetting.securityZones = data.map( + capacitySetting.securityZones = data ? data.map( function (item) { return { value: item.abstract_name, text: item.abstract_name, isSelected: item.id === data[0].id } - }); - capacitySetting.selectedSecurityZoneValue = data[0].abstract_name; + }) : []; + capacitySetting.selectedSecurityZoneValue = data && data.length > 0 ? data[0].abstract_name : null; }, error: function (data) { globalNotificationBanner.error = data } }); + + const placementsUrl = + `${location.protocol}//${location.host}/clouds/placements/${provider}/${cell}` + + `?accountId=${this.currentAccountId}` // grab all placement for this cell $.ajax({ type: 'GET', - url: location.protocol + '//' + location.host + '/clouds/placements/' + provider + '/' + cell, + url: placementsUrl, dataType: "json", beforeSend: function (xhr) { var csrftoken = getCookie('csrftoken'); xhr.setRequestHeader("X-CSRFToken", csrftoken); }, success: function (data) { - var placements = getDefaultPlacement({'placements': data}); + var placements = data ? getDefaultPlacement({'placements': data}) : null; - capacitySetting.placements = placements.getFullList(false, null); + capacitySetting.placements = placements ? placements.getFullList(false, null) : null; }, error: function (data) { globalNotificationBanner.error = data @@ -439,6 +441,13 @@

Capacity

imageNameChange: function (value) { var cell = capacitySetting.currentCell; capacitySetting.imageNameValue = value; + if (!value) { + capacitySetting.baseImages = []; + capacitySetting.baseImageValue = null; + capacitySetting.pinImage = null; + capacitySetting.pinImageEnabled = false; + return; + } //Grab all images for this image name $.ajax({ type: 'GET', @@ -648,7 +657,7 @@

Capacity

}, updateStatefulStatus: function(value) { this.selectedStatefulStatus = value - } + }, }, watch: { placements: function(){ @@ -663,8 +672,48 @@

Capacity

localStorage.setItem("accessRole", accessRoleObj.value); } } -}) +}); + + +function getUiCells(accountId) { + const account = getAccount(accountId); + if (account && account.cells) { + return account.cells + .map(uiCell); + } + return info.cells + .map(uiCell); +} + +function getDefaultCell(accountId) { + const account = getAccount(accountId); + + if (account && account.cells) { + if (!account.cells.some(cell => cell.name === info.defaultCell)) { + return account.cells[0].name; + } + } + return info.defaultCell; +} + +function uiCell(item) { + return { + value: item.name, + text: item.name, + isSelected: item.name === info.defaultCell + }; +} + +function getAccount(accountId) { + return info.accounts != null ? + info.accounts.find(function (o) { return o.id === accountId }) + : null; +} +function getAccountOwnerId(accountId) { + const account = getAccount(accountId); + return account ? account.ownerId : null; +} $(document).ready(function () { $('.single-select-search').chosen({ diff --git a/deploy-board/deploy_board/templates/deploys/deploy_details.tmpl b/deploy-board/deploy_board/templates/deploys/deploy_details.tmpl index 4435fd48ff..baeffed351 100644 --- a/deploy-board/deploy_board/templates/deploys/deploy_details.tmpl +++ b/deploy-board/deploy_board/templates/deploys/deploy_details.tmpl @@ -83,6 +83,24 @@ {% include "builds/build_details.tmpl" %} + {% if deploy_accounts %} + + Account + + {% for account in deploy_accounts %} + {% if account.legacy_name %} +
+ {{ account.legacy_name }} +
+ {% else %} + + {{ account.data.ownerId }} / {{ account.name }} + + {% endif %} + {% endfor %} + + + {% endif %}