Skip to content

Commit

Permalink
WIP - show more warnings when connecting to remote machines
Browse files Browse the repository at this point in the history
  • Loading branch information
mvollmer committed Sep 5, 2024
1 parent 4bbac21 commit 3499f26
Show file tree
Hide file tree
Showing 13 changed files with 387 additions and 132 deletions.
12 changes: 12 additions & 0 deletions doc/man/cockpit.conf.xml
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,18 @@ IdleTimeout=15
<para>When not specified, there is no idle timeout by default.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>WarnBeforeConnecting</option></term>
<listitem>
<para>Whether to warn before connecting to remote hosts from the Shell. Defaults to true</para>
<informalexample>
<programlisting language="ini">
[Session]
WarnBeforeConnecting=false
</programlisting>
</informalexample>
</listitem>
</varlistentry>
</variablelist>
</refsect1>

Expand Down
10 changes: 10 additions & 0 deletions pkg/shell/base_index.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,16 @@ function Frames(index, setupIdleResetTimers) {

/* Need to create a new frame */
if (!frame) {
/* Never create new frames for machines that are not
connected yet. That would open a channel to them (for
loading the URL), which woould trigger the bridge to
attempt a log in. We want all logins to happen in a
single place (in hosts.jsx) so that we can get the
options right, and show a warning dialog.
*/
if (host != "localhost" && machine.state !== "connected")
return null;

new_frame = true;
frame = document.createElement("iframe");
frame.setAttribute("class", "container-frame");
Expand Down
102 changes: 91 additions & 11 deletions pkg/shell/hosts.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { Tooltip } from "@patternfly/react-core/dist/esm/components/Tooltip";

import 'polyfills';
import { CockpitNav, CockpitNavItem } from "./nav.jsx";
import { HostModal } from "./hosts_dialog.jsx";
import { HostModal, try2Connect, codes } from "./hosts_dialog.jsx";
import { useLoggedInUser } from "hooks";

const _ = cockpit.gettext;
Expand Down Expand Up @@ -75,20 +75,35 @@ export class CockpitHosts extends React.Component {
current_key: props.machine.key,
show_modal: false,
edit_machine: null,
switch_machine: null,
error_options: null,
problem: null,
just_connect: false,
};

this.toggleMenu = this.toggleMenu.bind(this);
this.filterHosts = this.filterHosts.bind(this);
this.onAddNewHost = this.onAddNewHost.bind(this);
this.onEditHosts = this.onEditHosts.bind(this);
this.onHostEdit = this.onHostEdit.bind(this);
this.onHostSwitch = this.onHostSwitch.bind(this);
this.onRemove = this.onRemove.bind(this);
}

componentDidMount() {
cockpit.user().then(user => {
this.setState({ current_user: user.name || "" });
}).catch(exc => console.log(exc));

window.trigger_connection_flow = machine => {
if (!this.state.show_modal)
this.onHostSwitch(machine, true);
};
this.props.index.navigate(null, true);
}

componentWillUnmount() {
window.trigger_connection_flow = null;
}

static getDerivedStateFromProps(nextProps, prevState) {
Expand Down Expand Up @@ -124,6 +139,46 @@ export class CockpitHosts extends React.Component {
this.setState({ show_modal: true, edit_machine: machine });
}

onHostSwitch(machine, just_connect) {
if (machine.state == "connected" || machine.address == "localhost") {
if (!just_connect) {
const addr = this.props.hostAddr({ host: machine.address }, true);
this.props.jump(addr);
}
} else if (machine.state != "connecting") {
if (machine.problem && codes[machine.problem]) {
this.setState({
show_modal: true,
switch_machine: machine,
problem: machine.problem,
just_connect,
});
} else if (!window.sessionStorage.getItem("connection-warning-shown"))
this.setState({ show_modal: true, switch_machine: machine, just_connect });
else {
try2Connect(this.props.machines, machine.connection_string)
.then(() => {
const parts = this.props.machines.split_connection_string(machine.connection_string);
const addr = this.props.hostAddr({ host: parts.address }, true);
this.props.loader.connect(parts.address);
if (just_connect) {
this.props.index.navigate();
} else {
this.props.jump(addr);
}
})
.catch(err => {
this.setState({ show_modal: true,
switch_machine: machine,
error_options: err,
problem: err.problem,
just_connect
});
});
}
}
}

onEditHosts() {
this.setState(s => { return { editing: !s.editing } });
}
Expand Down Expand Up @@ -180,7 +235,7 @@ export class CockpitHosts extends React.Component {
header={(m.user ? m.user : this.state.current_user) + " @"}
status={m.state === "failed" ? { type: "error", title: _("Connection error") } : null}
className={m.state}
jump={this.props.jump}
jump={() => this.onHostSwitch(m)}
actions={<>
<Tooltip content={_("Edit")} position="right">
<Button isDisabled={m.address === "localhost"} className="nav-action" hidden={!editing} onClick={e => this.onHostEdit(e, m)} key={m.label + "edit"} variant="secondary"><EditIcon /></Button>
Expand Down Expand Up @@ -242,18 +297,41 @@ export class CockpitHosts extends React.Component {
</div>
{this.state.show_modal &&
<HostModal machines_ins={this.props.machines}
onClose={() => this.setState({ show_modal: false, edit_machine: null })}
address={this.state.edit_machine ? this.state.edit_machine.address : null}
caller_callback={this.state.edit_machine
? (new_connection_string) => {
const parts = this.props.machines.split_connection_string(new_connection_string);
if (this.state.edit_machine == this.props.machine && parts.address != this.state.edit_machine.address) {
const addr = this.props.hostAddr({ host: parts.address }, true);
onClose={() => this.setState({
show_modal: false,
edit_machine: null,
switch_machine: null,
error_options: null,
problem: null,
})}
address={this.state.edit_machine?.address || this.state.switch_machine?.address}
template={this.state.switch_machine
? (this.state.problem
? codes[this.state.problem] || "change-port"
: "connect")
: null}
error_options={this.state.error_options}
caller_callback={(new_connection_string) => {
const parts = this.props.machines.split_connection_string(new_connection_string);
const addr = this.props.hostAddr({ host: parts.address }, true);
if (this.state.edit_machine) {
if (this.state.edit_machine == this.props.machine &&
parts.address != this.state.edit_machine.address) {
this.props.loader.connect(parts.address);
this.props.jump(addr);
}
} else if (this.state.switch_machine) {
this.props.loader.connect(parts.address);
this.props.index.frames.remove(this.state.switch_machine);
if (this.state.just_connect) {
this.props.index.navigate();
} else {
this.props.jump(addr);
}
return Promise.resolve();
}
: null } />
return Promise.resolve();
}}
/>
}
</>
);
Expand All @@ -263,6 +341,8 @@ export class CockpitHosts extends React.Component {
CockpitHosts.propTypes = {
machine: PropTypes.object.isRequired,
machines: PropTypes.object.isRequired,
index: PropTypes.object.isRequired,
loader: PropTypes.object.isRequired,
selector: PropTypes.string.isRequired,
hostAddr: PropTypes.func.isRequired,
jump: PropTypes.func.isRequired,
Expand Down
Loading

0 comments on commit 3499f26

Please sign in to comment.