Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add version information panel (#4312) #4376

Merged
merged 5 commits into from
Oct 6, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions server/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,15 @@ func (s *Server) Version(context.Context, *empty.Empty) (*version.VersionMessage
}
}
if s.kustomizeVersion == "" {
kustomizeVersion, err := kustomize.Version()
kustomizeVersion, err := kustomize.Version(true)
if err == nil {
s.kustomizeVersion = kustomizeVersion
} else {
s.kustomizeVersion = err.Error()
}

}
if s.helmVersion == "" {
helmVersion, err := helm.Version()
helmVersion, err := helm.Version(true)
if err == nil {
s.helmVersion = helmVersion
} else {
Expand Down
2 changes: 2 additions & 0 deletions ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"raw-loader": "^0.5.1",
"react": "^16.8.3",
"react-autocomplete": "^1.8.1",
"react-copy-to-clipboard": "^5.0.2",
"react-diff-view": "^2.1.4",
"react-dom": "^16.8.3",
"react-form": "2.16.0",
Expand Down Expand Up @@ -87,6 +88,7 @@
"@babel/preset-typescript": "^7.7.2",
"@beyonk/google-fonts-webpack-plugin": "^1.5.0",
"@types/jest": "^24.0.13",
"@types/react-copy-to-clipboard": "^4.3.0",
"@types/react-test-renderer": "^16.8.3",
"add": "^2.0.6",
"babel-jest": "^24.9.0",
Expand Down
25 changes: 12 additions & 13 deletions ui/src/app/app.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {DataLoader, Layout, NavigationManager, Notifications, NotificationsManager, PageContext, Popup, PopupManager, PopupProps, Tooltip} from 'argo-ui';
import {DataLoader, Layout, NavigationManager, Notifications, NotificationsManager, PageContext, Popup, PopupManager, PopupProps} from 'argo-ui';
import {createBrowserHistory} from 'history';
import * as PropTypes from 'prop-types';
import * as React from 'react';
Expand All @@ -14,6 +14,8 @@ import {services} from './shared/services';
import requests from './shared/services/requests';
import {hashCode} from './shared/utils';
import userInfo from './user-info';
import {VersionButton} from './version-info/components/version-info-button';
import {VersionPanel} from './version-info/components/version-info-panel';

services.viewPreferences.init();
const bases = document.getElementsByTagName('base');
Expand Down Expand Up @@ -52,7 +54,7 @@ const navItems = [
}
];

const versionInfo = services.version.version();
const versionLoader = services.version.version();

async function isExpiredSSO() {
try {
Expand Down Expand Up @@ -92,7 +94,7 @@ requests.onError.subscribe(async err => {
}
});

export class App extends React.Component<{}, {popupProps: PopupProps; error: Error}> {
export class App extends React.Component<{}, {popupProps: PopupProps; showVersionPanel: boolean; error: Error}> {
public static childContextTypes = {
history: PropTypes.object,
apis: PropTypes.object
Expand All @@ -108,7 +110,7 @@ export class App extends React.Component<{}, {popupProps: PopupProps; error: Err

constructor(props: {}) {
super(props);
this.state = {popupProps: null, error: null};
this.state = {popupProps: null, error: null, showVersionPanel: false};
this.popupManager = new PopupManager();
this.notificationsManager = new NotificationsManager();
this.navigationManager = new NavigationManager(history);
Expand Down Expand Up @@ -185,15 +187,7 @@ export class App extends React.Component<{}, {popupProps: PopupProps; error: Err
) : (
<Layout
navItems={navItems}
version={() => (
<DataLoader load={() => versionInfo}>
{msg => (
<Tooltip content={msg.Version}>
<span style={{whiteSpace: 'nowrap'}}>{msg.Version}</span>
</Tooltip>
)}
</DataLoader>
)}>
version={() => <VersionButton version={versionLoader} onClick={() => this.toggleVersionPanel(true)} />}>
<route.component {...routeProps} />
</Layout>
)
Expand All @@ -219,11 +213,16 @@ export class App extends React.Component<{}, {popupProps: PopupProps; error: Err
</Provider>
</PageContext.Provider>
<Notifications notifications={this.notificationsManager.notifications} />
<VersionPanel version={versionLoader} isShown={this.state.showVersionPanel} onClose={() => this.toggleVersionPanel(false)} />
</React.Fragment>
);
}

public getChildContext() {
return {history, apis: {popup: this.popupManager, notifications: this.notificationsManager, navigation: this.navigationManager}};
}

public toggleVersionPanel = (isShown: boolean) => {
this.setState({showVersionPanel: isShown});
};
}
9 changes: 9 additions & 0 deletions ui/src/app/shared/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,15 @@ export interface ApplicationSyncWindowState {

export interface VersionMessage {
Version: string;
BuildDate: string;
GoVersion: string;
Compiler: string;
Platform: string;
KsonnetVersion: string;
KustomizeVersion: string;
HelmVersion: string;
KubectlVersion: string;
JsonnetVersion: string;
}

export interface Token {
Expand Down
32 changes: 32 additions & 0 deletions ui/src/app/version-info/components/version-info-button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {DataLoader, Tooltip} from 'argo-ui';
import * as React from 'react';
import {VersionMessage} from '../../shared/models';

import './version-info.scss';

interface VersionButtonProps {
onClick: () => void;
version: Promise<VersionMessage>;
}

export class VersionButton extends React.Component<VersionButtonProps> {
constructor(props: VersionButtonProps) {
super(props);
}

public render() {
return (
<DataLoader load={() => this.props.version}>
{version => (
<React.Fragment>
<Tooltip content={version.Version}>
<span className='version-info-button' onClick={this.props.onClick}>
{version.Version}
</span>
</Tooltip>
</React.Fragment>
)}
</DataLoader>
);
}
}
103 changes: 103 additions & 0 deletions ui/src/app/version-info/components/version-info-panel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import {DataLoader, SlidingPanel, Tooltip} from 'argo-ui';
import * as React from 'react';
import * as CopyToClipboard from 'react-copy-to-clipboard';
import {VersionMessage} from '../../shared/models';

import './version-info.scss';

interface VersionPanelProps {
isShown: boolean;
onClose: () => void;
version: Promise<VersionMessage>;
}

export class VersionPanel extends React.Component<VersionPanelProps, {justCopied: boolean}> {
private readonly header = 'Argo CD Server Version';

constructor(props: VersionPanelProps) {
super(props);
this.state = {justCopied: false};
}

public render() {
return (
<DataLoader load={() => this.props.version}>
{version => {
return (
<SlidingPanel header={this.header} isShown={this.props.isShown} onClose={() => this.props.onClose()} hasCloseButton={true} isNarrow={true}>
<div className='version-info-table argo-table-list'>
{/* <div className='argo-table-list__head'>
tetchel marked this conversation as resolved.
Show resolved Hide resolved
<div className='row'>
<div className='columns small-4'>Tool</div>
<div className='columns small-4'>Version</div>
</div>
</div> */}
{this.buildVersionTable(version)}
</div>
<div className='version-copy-btn-container'>
<Tooltip content='Copy all version info as JSON'>
<CopyToClipboard text={JSON.stringify(version, undefined, 4)} onCopy={() => this.onCopy()}>
tetchel marked this conversation as resolved.
Show resolved Hide resolved
<button className='argo-button argo-button--base'>
<i className={'fa ' + (this.state.justCopied ? 'fa-check' : 'fa-copy')} />
Copy JSON
</button>
</CopyToClipboard>
</Tooltip>
</div>
</SlidingPanel>
);
}}
</DataLoader>
);
}

/**
* Formats the version data and renders the table rows.
*/
private buildVersionTable(version: VersionMessage): JSX.Element {
// match the order/format of `argocd version`
// but leave out 'version' from the titles; that's implied by us being in the version info panel.
// These key/values are rendered to the user as written in this object
const formattedVersion = {
'Argo CD': version.Version,
'Build Date': version.BuildDate,
// 'Git Commit':
tetchel marked this conversation as resolved.
Show resolved Hide resolved
// 'Git Tree State':
tetchel marked this conversation as resolved.
Show resolved Hide resolved
'Go': version.GoVersion,
'Compiler': version.Compiler,
'Platform': version.Platform,
'ksonnet': version.KsonnetVersion,
'kustomize': version.KustomizeVersion,
'Helm': version.HelmVersion,
'kubectl': version.KubectlVersion
};

return (
<React.Fragment>
{Object.entries(formattedVersion).map(([key, value]) => {
return (
<div className='argo-table-list__row' key={key}>
<div className='row'>
<div className='columns small-4' title={key}>
<strong>{key}</strong>
</div>
<div className='columns'>
<Tooltip content={value}>
<span>{value}</span>
</Tooltip>
</div>
</div>
</div>
);
})}
</React.Fragment>
);
}

private onCopy(): void {
this.setState({justCopied: true});
setTimeout(() => {
this.setState({justCopied: false});
}, 500);
}
}
24 changes: 24 additions & 0 deletions ui/src/app/version-info/components/version-info.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@import 'node_modules/argo-ui/src/styles/config';
tetchel marked this conversation as resolved.
Show resolved Hide resolved

.version-info-button {
white-space: nowrap;
cursor: pointer;

&:hover, &:focus {
text-decoration: underline;
}
}

.version-copy-btn-container {
margin-top: 15px; // half of the panel's padding
tetchel marked this conversation as resolved.
Show resolved Hide resolved
display: flex;
flex-direction: row-reverse;

& button {
& i {
text-align: center;
margin-right: 0.5em;
min-width: 1rem;
}
}
}
29 changes: 28 additions & 1 deletion ui/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1246,6 +1246,13 @@
dependencies:
"@types/react" "*"

"@types/react-copy-to-clipboard@^4.3.0":
version "4.3.0"
resolved "https://registry.yarnpkg.com/@types/react-copy-to-clipboard/-/react-copy-to-clipboard-4.3.0.tgz#8e07becb4f11cfced4bd36038cb5bdf5c2658be5"
integrity sha512-iideNPRyroENqsOFh1i2Dv3zkviYS9r/9qD9Uh3Z9NNoAAqqa2x53i7iGndGNnJFIo20wIu7Hgh77tx1io8bgw==
dependencies:
"@types/react" "*"

"@types/[email protected]":
version "16.8.2"
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.8.2.tgz#9bd7d33f908b243ff0692846ef36c81d4941ad12"
Expand Down Expand Up @@ -2759,6 +2766,13 @@ copy-descriptor@^0.1.0:
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=

copy-to-clipboard@^3:
version "3.3.1"
resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz#115aa1a9998ffab6196f93076ad6da3b913662ae"
integrity sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==
dependencies:
toggle-selection "^1.0.6"

copy-webpack-plugin@^4.3.1:
version "4.6.0"
resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-4.6.0.tgz#e7f40dd8a68477d405dd1b7a854aae324b158bae"
Expand Down Expand Up @@ -7171,7 +7185,7 @@ prompts@^2.0.1:
kleur "^3.0.2"
sisteransi "^1.0.0"

prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2:
version "15.7.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
Expand Down Expand Up @@ -7338,6 +7352,14 @@ react-autocomplete@^1.8.1:
dom-scroll-into-view "1.0.1"
prop-types "^15.5.10"

react-copy-to-clipboard@^5.0.2:
version "5.0.2"
resolved "https://registry.yarnpkg.com/react-copy-to-clipboard/-/react-copy-to-clipboard-5.0.2.tgz#d82a437e081e68dfca3761fbd57dbf2abdda1316"
integrity sha512-/2t5mLMMPuN5GmdXo6TebFa8IoFxZ+KTDDqYhcDm0PhkgEzSxVvIX26G20s1EB02A4h2UZgwtfymZ3lGJm0OLg==
dependencies:
copy-to-clipboard "^3"
prop-types "^15.5.8"

react-deep-force-update@^2.1.1:
version "2.1.3"
resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-2.1.3.tgz#740612322e617bcced38f61794a4af75dc3d98e7"
Expand Down Expand Up @@ -8903,6 +8925,11 @@ to-single-quotes@^2.0.0:
resolved "https://registry.yarnpkg.com/to-single-quotes/-/to-single-quotes-2.0.1.tgz#7cc29151f0f5f2c41946f119f5932fe554170125"
integrity sha1-fMKRUfD18sQZRvEZ9ZMv5VQXASU=

toggle-selection@^1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32"
integrity sha1-bkWxJj8gF/oKzH2J14sVuL932jI=

[email protected]:
version "1.0.0"
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
Expand Down
12 changes: 10 additions & 2 deletions util/helm/helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,16 @@ func (h *helm) Dispose() {
h.cmd.Close()
}

func Version() (string, error) {
cmd := exec.Command("helm", "version", "--client")
func Version(shortForm bool) (string, error) {
executable := "helm"
cmdArgs := []string{"version", "--client"}
if shortForm {
cmdArgs = append(cmdArgs, "--short")
}
cmd := exec.Command(executable, cmdArgs...)
// example version output:
// long: "version.BuildInfo{Version:\"v3.3.1\", GitCommit:\"249e5215cde0c3fa72e27eb7a30e8d55c9696144\", GitTreeState:\"clean\", GoVersion:\"go1.14.7\"}"
// short: "v3.3.1+g249e521"
version, err := executil.RunWithRedactor(cmd, redactor)
if err != nil {
return "", fmt.Errorf("could not get helm version: %s", err)
Expand Down
2 changes: 1 addition & 1 deletion util/helm/helm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ func TestHelmArgCleaner(t *testing.T) {
}

func TestVersion(t *testing.T) {
ver, err := Version()
ver, err := Version(false)
assert.NoError(t, err)
assert.NotEmpty(t, ver)
}
Expand Down
Loading