cli: allow creating ADSL connections with 'nmcli connection add' (rh #1264089)

https://bugzilla.redhat.com/show_bug.cgi?id=1264089
This commit is contained in:
Jiří Klimeš 2015-09-18 12:05:49 +02:00
parent 5502d8691a
commit 290c1626b9
3 changed files with 171 additions and 1 deletions

View file

@ -390,6 +390,10 @@ usage_connection_add (void)
" olpc-mesh: ssid <SSID>\n"
" [channel <1-13>]\n"
" [dhcp-anycast <MAC address>]\n\n"
" adsl: username <username>\n"
" protocol pppoa|pppoe|ipoatm\n"
" [password <password>]\n"
" [encapsulation vcmux|llc]\n\n"
" SLAVE_OPTIONS:\n"
" bridge: [priority <0-63>]\n"
" [path-cost <1-65535>]\n"
@ -3022,6 +3026,29 @@ check_infiniband_mode (char **mode, GError **error)
return check_valid_enumeration (mode, modes, "mode", _("InfiniBand transport mode"), error);
}
/* Checks ADSL protocol */
static gboolean
check_adsl_protocol (char **protocol, GError **error)
{
const char *protos[] = { NM_SETTING_ADSL_PROTOCOL_PPPOA,
NM_SETTING_ADSL_PROTOCOL_PPPOE,
NM_SETTING_ADSL_PROTOCOL_IPOATM,
NULL };
return check_valid_enumeration (protocol, protos, "protocol", _("ADSL protocol"), error);
}
/* Checks ADSL encapsulation */
static gboolean
check_adsl_encapsulation (char **encapsulation, GError **error)
{
const char *modes[] = { NM_SETTING_ADSL_ENCAPSULATION_VCMUX,
NM_SETTING_ADSL_ENCAPSULATION_LLC,
NULL };
return check_valid_enumeration (encapsulation, modes, "encapsulation", _("ADSL encapsulation"), error);
}
static gboolean
check_and_convert_vlan_flags (const char *flags, guint32 *flags_int, GError **error)
{
@ -4027,6 +4054,33 @@ do_questionnaire_olpc (char **channel, char **dhcp_anycast)
}
}
#define PROMPT_ADSL_ENCAP "(" NM_SETTING_ADSL_ENCAPSULATION_VCMUX "/" NM_SETTING_ADSL_ENCAPSULATION_LLC ") [none]: "
static void
do_questionnaire_adsl (char **password, char **encapsulation)
{
gboolean once_more;
GError *error = NULL;
/* Ask for optional 'adsl' arguments. */
if (!want_provide_opt_args (_("ADSL"), 2))
return;
if (!*password)
*password = nmc_readline (_("Password [none]: "));
if (!*encapsulation) {
do {
*encapsulation = nmc_readline (_("ADSL encapsulation %s"), PROMPT_ADSL_ENCAP);
once_more = !check_adsl_encapsulation (encapsulation, &error);
if (once_more) {
g_print ("%s\n", error->message);
g_clear_error (&error);
g_free (*encapsulation);
}
} while (once_more);
}
}
static gboolean
split_address (char* str, char **ip, char **rest)
{
@ -4385,6 +4439,7 @@ complete_connection_by_type (NMConnection *connection,
NMSettingBridgePort *s_bridge_port;
NMSettingVpn *s_vpn;
NMSettingOlpcMesh *s_olpc_mesh;
NMSettingAdsl *s_adsl;
const char *slave_type;
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
@ -5429,6 +5484,74 @@ cleanup_olpc:
if (!success)
return FALSE;
} else if (!strcmp (con_type, NM_SETTING_ADSL_SETTING_NAME)) {
/* Build up the settings required for 'adsl' */
gboolean success = FALSE;
char *username_ask = NULL;
const char *username = NULL;
char *protocol_ask = NULL;
const char *protocol = NULL;
const char *password_c = NULL;
char *password = NULL;
const char *encapsulation_c = NULL;
char *encapsulation = NULL;
nmc_arg_t exp_args[] = { {"username", TRUE, &username, !ask},
{"protocol", TRUE, &protocol, !ask},
{"password", TRUE, &password_c, FALSE},
{"encapsulation", TRUE, &encapsulation_c, FALSE},
{NULL} };
if (!nmc_parse_args (exp_args, FALSE, &argc, &argv, error))
return FALSE;
if (!username && ask)
username = username_ask = nmc_readline (_("Username: "));
if (!username) {
g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("Error: 'username' is required."));
goto cleanup_adsl;
}
#define PROMPT_ADSL_PROTO "(" NM_SETTING_ADSL_PROTOCOL_PPPOA "/" NM_SETTING_ADSL_PROTOCOL_PPPOE "/" NM_SETTING_ADSL_PROTOCOL_IPOATM "): "
if (!protocol && ask)
protocol = protocol_ask = nmc_readline (_("Protocol %s"), PROMPT_ADSL_PROTO);
if (!protocol) {
g_set_error_literal (error, NMCLI_ERROR, NMC_RESULT_ERROR_USER_INPUT,
_("Error: 'protocol' is required."));
goto cleanup_adsl;
}
if (!check_adsl_protocol (&protocol_ask, error))
goto cleanup_adsl;
/* Also ask for all optional arguments if '--ask' is specified. */
password = g_strdup (password_c);
encapsulation = g_strdup (encapsulation_c);
if (ask)
do_questionnaire_adsl (&password, &encapsulation);
if (!check_adsl_encapsulation (&encapsulation, error))
goto cleanup_adsl;
/* Add ADSL setting */
s_adsl = (NMSettingAdsl *) nm_setting_adsl_new ();
nm_connection_add_setting (connection, NM_SETTING (s_adsl));
g_object_set (s_adsl,
NM_SETTING_ADSL_USERNAME, username,
NM_SETTING_ADSL_PROTOCOL, protocol,
NM_SETTING_ADSL_PASSWORD, password,
NM_SETTING_ADSL_ENCAPSULATION, encapsulation,
NULL);
success = TRUE;
cleanup_adsl:
g_free (username_ask);
g_free (password);
g_free (protocol_ask);
g_free (encapsulation);
if (!success)
return FALSE;
} else if (!strcmp (con_type, NM_SETTING_GENERIC_SETTING_NAME)) {
/* Add 'generic' setting */
s_generic = (NMSettingGeneric *) nm_setting_generic_new ();
@ -5812,6 +5935,20 @@ gen_func_bond_mon_mode (const char *text, int state)
return nmc_rl_gen_func_basic (text, state, words);
}
static char *
gen_func_adsl_proto (const char *text, int state)
{
const char *words[] = { "pppoe", "pppoa", "ipoatm", NULL };
return nmc_rl_gen_func_basic (text, state, words);
}
static char *
gen_func_adsl_encap (const char *text, int state)
{
const char *words[] = { "vcmux", "llc", NULL };
return nmc_rl_gen_func_basic (text, state, words);
}
static char *
gen_func_master_ifnames (const char *text, int state)
{
@ -5898,6 +6035,10 @@ nmcli_con_add_tab_completion (const char *text, int start, int end)
generator_func = gen_func_bond_mode;
else if (g_str_has_suffix (rl_prompt, PROMPT_BOND_MON_MODE))
generator_func = gen_func_bond_mon_mode;
else if (g_str_has_suffix (rl_prompt, PROMPT_ADSL_PROTO))
generator_func = gen_func_adsl_proto;
else if (g_str_has_suffix (rl_prompt, PROMPT_ADSL_ENCAP))
generator_func = gen_func_adsl_encap;
if (generator_func)
match_array = rl_completion_matches (text, generator_func);

View file

@ -387,7 +387,7 @@ _nmcli_compl_ARGS()
# user friendly. Only complete them, if the current word already starts with an "8".
_nmcli_list "802-3-ethernet 802-11-wireless 802-11-olpc-mesh"
else
_nmcli_list "ethernet wifi wimax gsm cdma infiniband bluetooth vpn olpc-mesh vlan bond bridge team pppoe"
_nmcli_list "ethernet wifi wimax gsm cdma infiniband bluetooth vpn olpc-mesh vlan bond bridge team pppoe adsl"
fi
return 0
fi
@ -563,6 +563,18 @@ _nmcli_compl_ARGS()
return 0
fi
;;
encapsulation)
if [[ "${#words[@]}" -eq 2 ]]; then
_nmcli_list "vcmux llc"
return 0
fi
;;
protocol)
if [[ "${#words[@]}" -eq 2 ]]; then
_nmcli_list "pppoa pppoe ipoatm"
return 0
fi
;;
*)
return 1
;;
@ -1054,6 +1066,11 @@ _nmcli()
OPTIONS_TYPED=(username password service mtu mac)
OPTIONS_MANDATORY=(username)
;;
a|ad|ads|adsl)
OPTIONS_TYPE=adsl
OPTIONS_TYPED=(username password protocol encapsulation)
OPTIONS_MANDATORY=(username protocol)
;;
*)
# for an unknown connection type, we stop completion here
return 0

View file

@ -639,6 +639,18 @@ The value can be prefixed with \fBifname/\fP, \fBuuid/\fP or \fBid/\fP to disamb
.RE
.RS
.TP
.B adsl:
.IP "\fIusername <username>\fP" 42
\(en ADSL user name
.IP "\fIprotocol pppoa|pppoe|ipoatm\fP" 42
\(en ADSL protocol
.IP "\fI[password <password>]\fP" 42
\(en ADSL password
.IP "\fI[encapsulation vcmux|llc]\fP" 42
\(en ADSL encapsulation
.RE
.RS
.TP
.B SLAVE_OPTIONS:
.RE
.RS