Compare commits

...

1 Commits

Author SHA1 Message Date
xAt0mZ
bb3bc0737a wip 2021-02-03 21:50:47 +01:00
8 changed files with 98 additions and 19 deletions

View File

@@ -1,7 +1,14 @@
<div>
<code-editor identifier="application-details-yaml" read-only="true" value="$ctrl.data"></code-editor>
<code-editor identifier="application-details-yaml" value="ctrl.data" on-change="(ctrl.onEditorChange)" yml="true"></code-editor>
<div style="margin: 15px;">
<span class="btn btn-primary btn-sm" ng-click="$ctrl.copyYAML()"><i class="fa fa-copy space-right" aria-hidden="true"></i>Copy to clipboard</span>
<button class="btn btn-primary btn-sm" ng-click="ctrl.copyYAML()">
<span><i class="fa fa-copy space-right" aria-hidden="true"></i>Copy to clipboard</span>
</button>
<span id="copyNotificationYAML" style="margin-left: 7px; display: none; color: #23ae89;" class="small"> <i class="fa fa-check" aria-hidden="true"></i> copied </span>
<button ng-if="ctrl.updateVisible" ng-disabled="ctrl.updateDisabled" type="button" class="btn btn-primary btn-sm" ng-click="ctrl.updateAction()"
button-spinner="ctrl.state.actionInProgress">
<span ng-show="!ctrl.state.actionInProgress">Update {{ctrl.resourceType}}</span>
<span ng-show="ctrl.state.actionInProgress">Update in progress...</span>
</button>
</div>
</div>

View File

@@ -1,8 +1,14 @@
angular.module('portainer.kubernetes').component('kubernetesYamlInspector', {
templateUrl: './yamlInspector.html',
controller: 'KubernetesYamlInspectorController',
controllerAs: 'ctrl',
bindings: {
key: '@',
data: '<',
onEditorChange: '<',
resourceType: '@',
updateVisible: '<',
updateDisabled: '<',
updateAction: '<'
},
});

View File

@@ -0,0 +1,10 @@
import _ from 'lodash-es';
import * as YAML from 'js-yaml';
class KubernetesYamlHelper {
static parse(yaml) {
return YAML.loadAll(yaml);
}
}
export default KubernetesYamlHelper;

View File

@@ -360,14 +360,26 @@ class KubernetesApplicationService {
}
}
// accept either formValues or applications as parameters
// depending on partial value
// true = KubernetesApplication
// false = KubernetesApplicationFormValues
patch(oldValues, newValues, partial = false) {
// this function accepts Yaml as parameters
async patchFromYamlAsync(oldApp, newApp) {
const apiService = this._getApplicationApiService(oldApp);
}
/**
* PATCH accepts different payloads depending on the options passed as 3rd parameter
* @param {KubernetesApplicationFormValue|KubernetesApplication|Yaml} oldValues Data of application before changes
* @param {KubernetesApplicationFormValue|KubernetesApplication|Yaml} newValues Data of application after changes
* @param {{partial=false, fromYaml=false}} options Options change the source format
*/
patch(oldValues, newValues, {partial = false, fromYaml = false}) {
if (partial) {
return this.$async(this.patchPartialAsync, oldValues, newValues);
}
if (fromYaml) {
return this.$async(this.patchFromYamlAsync, oldValues, newValues);
}
return this.$async(this.patchAsync, oldValues, newValues);
}
/* #endregion */

View File

@@ -177,7 +177,15 @@
<uib-tab index="3" ng-if="ctrl.application.Yaml" select="ctrl.showEditor()" classes="btn-sm">
<uib-tab-heading> <i class="fa fa-code space-right" aria-hidden="true"></i> YAML </uib-tab-heading>
<div style="padding-right: 25px;" ng-if="ctrl.state.showEditorTab">
<kubernetes-yaml-inspector key="application-yaml" data="ctrl.application.Yaml"></kubernetes-yaml-inspector>
<kubernetes-yaml-inspector
key="application-yaml"
data="ctrl.application.Yaml"
resource-type="application"
update-action="ctrl.updateFromYaml"
on-editor-change="(ctrl.onEditorChange)"
update-visible="ctrl.yamlUpdateVisible()"
update-disabled="ctrl.yamlUpdateDisabled()"
></kubernetes-yaml-inspector>
</div>
</uib-tab>
</uib-tabset>
@@ -190,7 +198,7 @@
<div class="col-sm-12">
<rd-widget>
<rd-widget-body>
<div ng-if="!ctrl.isExternalApplication() && !ctrl.isSystemNamespace()" style="margin-bottom: 15px;">
<div ng-if="ctrl.canEditApplication()" style="margin-bottom: 15px;">
<button type="button" class="btn btn-sm btn-primary" ui-sref="kubernetes.applications.application.edit" style="margin-left: 0;">
<i class="fa fa-file-code space-right" aria-hidden="true"></i>Edit this application
</button>

View File

@@ -1,12 +1,13 @@
import angular from 'angular';
import * as _ from 'lodash-es';
import * as JsonPatch from 'fast-json-patch';
import _ from 'lodash-es';
import JsonPatch from 'fast-json-patch';
import { KubernetesApplicationDataAccessPolicies, KubernetesApplicationDeploymentTypes, KubernetesApplicationTypes } from 'Kubernetes/models/application/models';
import KubernetesEventHelper from 'Kubernetes/helpers/eventHelper';
import KubernetesApplicationHelper from 'Kubernetes/helpers/application';
import { KubernetesServiceTypes } from 'Kubernetes/models/service/models';
import { KubernetesPodNodeAffinityNodeSelectorRequirementOperators } from 'Kubernetes/pod/models';
import { KubernetesPodContainerTypes } from 'Kubernetes/pod/models/index';
import KubernetesYamlHelper from 'Kubernetes/helpers/yamlHelper';
function computeTolerations(nodes, application) {
const pod = application.Pods[0];
@@ -101,6 +102,7 @@ class KubernetesApplicationController {
Notifications,
LocalStorage,
ModalService,
Authentication,
KubernetesApplicationService,
KubernetesEventService,
KubernetesStackService,
@@ -114,6 +116,7 @@ class KubernetesApplicationController {
this.Notifications = Notifications;
this.LocalStorage = LocalStorage;
this.ModalService = ModalService;
this.Authentication = Authentication;
this.KubernetesApplicationService = KubernetesApplicationService;
this.KubernetesEventService = KubernetesEventService;
@@ -138,6 +141,8 @@ class KubernetesApplicationController {
this.redeployApplicationAsync = this.redeployApplicationAsync.bind(this);
this.rollbackApplicationAsync = this.rollbackApplicationAsync.bind(this);
this.copyLoadBalancerIP = this.copyLoadBalancerIP.bind(this);
this.updateFromYaml = this.updateFromYaml.bind(this);
this.onEditorChange = this.onEditorChange.bind(this);
}
selectTab(index) {
@@ -255,6 +260,35 @@ class KubernetesApplicationController {
return this.$async(this.updateApplicationAsync);
}
updateFromYaml() {
return this.$async(async() => {
});
}
onEditorChange(cm) {
console.log('oneditor change')
console.log(cm)
this.formValues.Yaml = cm.getValue();
}
yamlUpdateVisible() {
return this.canEditApplication() && this.state.isAdmin;
}
yamlUpdateDisabled() {
if (!this.application.Yaml || !this.formValues.Yaml) {
return true
}
const oldApp = KubernetesYamlHelper.parse(this.application.Yaml);
const newApp = KubernetesYamlHelper.parse(this.formValues.Yaml);
const payload = JsonPatch.compare(oldApp, newApp);
return !payload.length;
}
canEditApplication() {
return !this.isExternalApplication() && !this.isSystemNamespace()
}
/**
* EVENTS
*/
@@ -335,6 +369,7 @@ class KubernetesApplicationController {
placementWarning: false,
expandedNote: false,
useIngress: false,
isAdmin: this.Authentication.isAdmin(),
};
this.state.activeTab = this.LocalStorage.getActiveTab('application');
@@ -342,6 +377,7 @@ class KubernetesApplicationController {
this.formValues = {
Note: '',
SelectedRevision: undefined,
Yaml: '',
};
await this.getApplication();

View File

@@ -75,7 +75,7 @@
"bootstrap": "^3.4.0",
"chardet": "^1.3.0",
"chart.js": "~2.6.0",
"codemirror": "~5.30.0",
"codemirror": "~5.59.2",
"fast-json-patch": "^3.0.0-1",
"filesize": "~3.3.0",
"filesize-parser": "^1.5.0",

View File

@@ -2657,10 +2657,10 @@ code-point-at@^1.0.0:
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
codemirror@~5.30.0:
version "5.30.0"
resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.30.0.tgz#86e57dd5ea5535acbcf9c720797b4cefe05b5a70"
integrity sha512-pfJV/7fLAUUenuGK3iANkQu1AxNLuWpeF7HV6YFDjSBMp53F8FTa2F6oPs9NKAHFweT2m08usmXUIA+7sohdew==
codemirror@~5.59.2:
version "5.59.2"
resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.59.2.tgz#ee674d3a4a8d241af38d52afc482625ba7393922"
integrity sha512-/D5PcsKyzthtSy2NNKCyJi3b+htRkoKv3idswR/tR6UAvMNKA7SrmyZy6fOONJxSRs1JlUWEDAbxqfdArbK8iA==
coffee-script@^1.10.0:
version "1.12.7"
@@ -6606,9 +6606,9 @@ js-tokens@^3.0.2:
integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls=
js-yaml@^3.13.0, js-yaml@^3.13.1, js-yaml@^3.14.0, js-yaml@^3.3.0, js-yaml@^3.5.1, js-yaml@~3.13.1, js-yaml@~3.7.0:
version "3.14.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482"
integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==
version "3.14.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537"
integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"