Line data Source code
1 : /*
2 : * Copyright (C) 2023 Red Hat, Inc.
3 : * SPDX-License-Identifier: LGPL-2.1-or-later
4 : */
5 :
6 113 : import cockpit from "cockpit";
7 : import client from "../client.js";
8 :
9 : import { dialog_open, TextInput, PassInput, SelectRow } from "../dialog.jsx";
10 :
11 113 : const _ = cockpit.gettext;
12 :
13 1 : export function iscsi_discover() {
14 1 : dialog_open({
15 1 : Title: _("Add iSCSI portal"),
16 1 : Fields: [
17 1 : TextInput("address", _("Server address"),
18 0 : { validate: val => val === "" ? _("Server address cannot be empty.") : null, }),
19 1 : TextInput("username", _("Username"), { }),
20 1 : PassInput("password", _("Password"), { })
21 1 : ],
22 1 : Action: {
23 1 : Title: _("Next"),
24 1 : action: (vals, progress_callback) => new Promise((resolve, reject) => {
25 1 : const options = { };
26 0 : if (vals.username || vals.password) {
27 1 : options.username = { t: 's', v: vals.username };
28 1 : options.password = { t: 's', v: vals.password };
29 1 : }
30 :
31 1 : let cancelled = false;
32 1 : client.manager_iscsi.call('DiscoverSendTargets',
33 1 : [vals.address,
34 1 : 0,
35 1 : options
36 1 : ])
37 1 : .then(function (results) {
38 1 : if (!cancelled) {
39 1 : resolve();
40 1 : iscsi_add(vals, results[0]);
41 1 : }
42 1 : })
43 0 : .catch(function (error) {
44 0 : if (cancelled)
45 0 : return;
46 :
47 : // HACK - https://github.com/storaged-project/udisks/issues/26
48 0 : if (error.message.indexOf("initiator failed authorization") != -1)
49 0 : error = {
50 0 : username: true, // make it red without text below
51 0 : password: _("Invalid username or password")
52 0 : };
53 0 : else if (error.message.indexOf("cannot resolve host name") != -1)
54 0 : error = {
55 0 : address: _("Unknown host name")
56 0 : };
57 0 : else if (error.message.indexOf("connection login retries") != -1)
58 0 : error = {
59 0 : address: _("Unable to reach server")
60 0 : };
61 :
62 0 : reject(error);
63 0 : });
64 :
65 0 : progress_callback(null, function () {
66 0 : cancelled = true;
67 0 : reject();
68 0 : });
69 1 : }),
70 1 : }
71 1 : });
72 1 : }
73 :
74 1 : function iscsi_login(target, cred_vals) {
75 1 : const options = {
76 1 : 'node.startup': { t: 's', v: "automatic" }
77 1 : };
78 0 : if (cred_vals.username || cred_vals.password) {
79 1 : options.username = { t: 's', v: cred_vals.username };
80 1 : options.password = { t: 's', v: cred_vals.password };
81 1 : }
82 1 : return client.manager_iscsi.call('Login',
83 1 : [target[0],
84 1 : target[1],
85 1 : target[2],
86 1 : target[3],
87 1 : target[4],
88 1 : options
89 1 : ]);
90 1 : }
91 :
92 1 : function iscsi_add(discover_vals, nodes) {
93 1 : dialog_open({
94 1 : Title: cockpit.format(_("Available targets on $0"),
95 1 : discover_vals.address),
96 1 : Fields: [
97 1 : SelectRow("target", [_("Name"), _("Address"), _("Port")],
98 1 : {
99 1 : choices: nodes.map(n => ({
100 1 : columns: [n[0], n[2], n[3]],
101 1 : value: n
102 1 : }))
103 1 : })
104 1 : ],
105 1 : Action: {
106 1 : Title: _("Add"),
107 1 : action: function (vals) {
108 1 : return iscsi_login(vals.target, discover_vals)
109 1 : .catch(err => {
110 1 : if (err.message.indexOf("authorization") != -1)
111 0 : iscsi_add_with_creds(discover_vals, vals);
112 : else
113 0 : return Promise.reject(err);
114 1 : });
115 1 : }
116 1 : }
117 1 : });
118 1 : }
119 :
120 1 : function iscsi_add_with_creds(discover_vals, login_vals) {
121 1 : dialog_open({
122 1 : Title: _("Authentication required"),
123 1 : Fields: [
124 1 : TextInput("username", _("Username"),
125 1 : { value: discover_vals.username }),
126 1 : PassInput("password", _("Password"),
127 1 : { value: discover_vals.password })
128 1 : ],
129 1 : Action: {
130 1 : Title: _("Add"),
131 1 : action: function (vals) {
132 1 : return iscsi_login(login_vals.target, vals)
133 0 : .catch(err => {
134 : // HACK - https://github.com/storaged-project/udisks/issues/26
135 0 : if (err.message.indexOf("authorization") != -1)
136 0 : err = {
137 0 : username: true, // makes it red without text below
138 0 : password: _("Invalid username or password")
139 0 : };
140 0 : return Promise.reject(err);
141 0 : });
142 1 : }
143 1 : }
144 1 : });
145 1 : }
146 :
147 1 : export function iscsi_change_name() {
148 1 : return client.manager_iscsi.call('GetInitiatorName')
149 1 : .then(function (results) {
150 1 : const name = results[0];
151 1 : dialog_open({
152 1 : Title: _("Change iSCSI initiator name"),
153 1 : Fields: [
154 1 : TextInput("name", _("Name"), { value: name })
155 1 : ],
156 1 : Action: {
157 1 : Title: _("Change"),
158 1 : action: function (vals) {
159 1 : return client.manager_iscsi.call('SetInitiatorName',
160 1 : [vals.name,
161 1 : { }
162 1 : ]);
163 1 : }
164 1 : }
165 1 : });
166 1 : });
167 1 : }
|