Skip to content

Commit 16765fc

Browse files
authored
Remove Host.ssh_host field (#413)
Having two separate fields for a label/hostname never made much sense. In our database, we don't have any cases were the label and ssh_host fields are set to different values. In most cases only ssh_host is set. Remove the ssh_host field, only keep the label field for the hostname. A data migration step copies the ssh_host value to the label field. As a side benefit, this will ensure that all infrastructure hosts are displayed with their hostname instead of ISD-AS,IP in the admin panel. In the api/topology json, the host name is still called `ssh_host`. We can rename this later, combined with other API breaking changes.
1 parent 8762b04 commit 16765fc

File tree

8 files changed

+73
-60
lines changed

8 files changed

+73
-60
lines changed

scionlab/admin.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ def get_readonly_fields(self, request, obj):
197197

198198
class HostAdminForm(_CreateUpdateModelForm):
199199
class Meta:
200-
fields = ('AS', 'internal_ip', 'public_ip', 'bind_ip', 'label', 'ssh_host')
200+
fields = ('AS', 'internal_ip', 'public_ip', 'bind_ip', 'label')
201201

202202
secret = forms.CharField(required=False, widget=forms.TextInput(attrs={'size': '32'}))
203203

@@ -208,7 +208,6 @@ def create(self):
208208
public_ip=self.cleaned_data['public_ip'],
209209
bind_ip=self.cleaned_data['bind_ip'],
210210
label=self.cleaned_data['label'],
211-
ssh_host=self.cleaned_data['ssh_host'],
212211
secret=self.cleaned_data['secret']
213212
)
214213

@@ -218,7 +217,6 @@ def update(self):
218217
public_ip=self.cleaned_data['public_ip'],
219218
bind_ip=self.cleaned_data['bind_ip'],
220219
label=self.cleaned_data['label'],
221-
ssh_host=self.cleaned_data['ssh_host'],
222220
secret=self.cleaned_data['secret']
223221
)
224222

@@ -749,10 +747,10 @@ class HostAdmin(HostAdminMixin, admin.ModelAdmin):
749747
form = HostAdminForm
750748
readonly_fields = ['uid', 'get_scionlab_config_cmd']
751749
list_display = ('__str__', 'AS',
752-
'internal_ip', 'public_ip', 'bind_ip', 'ssh_host',
750+
'internal_ip', 'public_ip', 'bind_ip',
753751
'latest_config_deployed', 'get_scionlab_config_cmd', 'get_config_link')
754752
list_filter = ('AS__isd', 'AS', )
755-
search_fields = ('AS__as_id', 'label', 'ssh_host')
753+
search_fields = ('AS__as_id', 'label')
756754
ordering = ['AS']
757755

758756
def get_urls(self):

scionlab/fixtures/testdata.yaml

Lines changed: 15 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -3580,8 +3580,7 @@
35803580
internal_ip: 127.0.0.1
35813581
public_ip: 192.0.2.11
35823582
bind_ip: null
3583-
label: null
3584-
ssh_host: 192.0.2.11
3583+
label: scionlab-1101-parapet
35853584
uid: f470d0cceccc409c83393ac000e8d793
35863585
secret: 2a3f2ee1b4a847d0b637872f2a7fa960
35873586
config_version: 8
@@ -3594,8 +3593,7 @@
35943593
internal_ip: 127.0.0.1
35953594
public_ip: 192.0.2.12
35963595
bind_ip: null
3597-
label: null
3598-
ssh_host: 192.0.2.12
3596+
label: scionlab-1102-dishwasher
35993597
uid: f3ec4ddfecef4d9887509b660bd8805d
36003598
secret: 15e18bd011f946caa12280280f0c330b
36013599
config_version: 7
@@ -3608,8 +3606,7 @@
36083606
internal_ip: 127.0.0.1
36093607
public_ip: 192.0.2.13
36103608
bind_ip: null
3611-
label: null
3612-
ssh_host: 192.0.2.13
3609+
label: scionlab-1103-waxier
36133610
uid: daedabbf07aa4253ae55dc5f9e0ddab9
36143611
secret: 19f3ea1f089343f082ab1a7a49c3caa4
36153612
config_version: 7
@@ -3622,8 +3619,7 @@
36223619
internal_ip: 127.0.0.1
36233620
public_ip: 192.0.2.17
36243621
bind_ip: null
3625-
label: null
3626-
ssh_host: 192.0.2.17
3622+
label: scionlab-1107-reals
36273623
uid: b61daa99565446389397cbcd08d62f84
36283624
secret: feef3b3f455e42c288803a1638b101f4
36293625
config_version: 10
@@ -3636,8 +3632,7 @@
36363632
internal_ip: 127.0.0.1
36373633
public_ip: 172.31.0.110
36383634
bind_ip: null
3639-
label: null
3640-
ssh_host: 172.31.0.110
3635+
label: scionlab-1301-cytoplasm
36413636
uid: 747dc3fb869d466a81ea316f9a46ebb7
36423637
secret: 0367e2079ff14e509bbe2d338b35164a
36433638
config_version: 11
@@ -3650,8 +3645,7 @@
36503645
internal_ip: 127.0.0.1
36513646
public_ip: 192.0.2.32
36523647
bind_ip: null
3653-
label: null
3654-
ssh_host: 192.0.2.32
3648+
label: scionlab-1302-paperhanger
36553649
uid: 53922dccbb7144b987f2e4681e09f85b
36563650
secret: 03fb466f164f4c99a7bb5b383099ba45
36573651
config_version: 7
@@ -3664,8 +3658,7 @@
36643658
internal_ip: 127.0.0.1
36653659
public_ip: 172.31.0.111
36663660
bind_ip: null
3667-
label: null
3668-
ssh_host: 172.31.0.111
3661+
label: scionlab-1303-premiere
36693662
uid: b5150aeb217c42bb94f369fafbde9424
36703663
secret: 7a66690be29048edb0960a4ca217d658
36713664
config_version: 8
@@ -3678,8 +3671,7 @@
36783671
internal_ip: 127.0.0.1
36793672
public_ip: 192.0.2.34
36803673
bind_ip: null
3681-
label: null
3682-
ssh_host: 192.0.2.34
3674+
label: scionlab-1304-beneficence
36833675
uid: 2197a3cb85114c57a6598df981dd38b6
36843676
secret: e13e26ce78d24442be170ccf23821cf8
36853677
config_version: 7
@@ -3692,8 +3684,7 @@
36923684
internal_ip: 127.0.0.1
36933685
public_ip: 172.31.0.112
36943686
bind_ip: null
3695-
label: null
3696-
ssh_host: 172.31.0.112
3687+
label: scionlab-1305-adulterers
36973688
uid: 6c9a16b969e443e1a940943efcb42f38
36983689
secret: 9315d60785f649bd81ceb24fb5a041d0
36993690
config_version: 7
@@ -3706,8 +3697,7 @@
37063697
internal_ip: 127.0.0.1
37073698
public_ip: 172.31.0.113
37083699
bind_ip: null
3709-
label: null
3710-
ssh_host: 172.31.0.113
3700+
label: scionlab-1401-orphaning
37113701
uid: d158f36aa95c41ce9dca957496887da4
37123702
secret: f0c384207d0f4890acb704921ec84528
37133703
config_version: 9
@@ -3720,8 +3710,7 @@
37203710
internal_ip: 127.0.0.1
37213711
public_ip: 192.0.2.42
37223712
bind_ip: null
3723-
label: null
3724-
ssh_host: 192.0.2.42
3713+
label: scionlab-1402-trawling
37253714
uid: f40257382e764dbf901e7628e092ce9c
37263715
secret: 3f3baf772ccb458db0e8384a9117d8d8
37273716
config_version: 8
@@ -3734,8 +3723,7 @@
37343723
internal_ip: 127.0.0.1
37353724
public_ip: 192.0.2.43
37363725
bind_ip: null
3737-
label: null
3738-
ssh_host: 192.0.2.43
3726+
label: scionlab-1403-inputting
37393727
uid: ac36de474a9741528c81101176f41616
37403728
secret: 92a9b0452ccc46b286b85bb262d1c5c6
37413729
config_version: 8
@@ -3748,8 +3736,7 @@
37483736
internal_ip: 127.0.0.1
37493737
public_ip: 192.0.2.44
37503738
bind_ip: null
3751-
label: null
3752-
ssh_host: 192.0.2.44
3739+
label: scionlab-1404-memorable
37533740
uid: e5ced7199cce4bd68d449b7cc1308faf
37543741
secret: 3e8963578bb747a4bd0cc361346458e9
37553742
config_version: 9
@@ -3762,8 +3749,7 @@
37623749
internal_ip: 127.0.0.1
37633750
public_ip: 172.31.0.114
37643751
bind_ip: null
3765-
label: null
3766-
ssh_host: 172.31.0.114
3752+
label: scionlab-1405-cauterise
37673753
uid: c6d63a630ada49129549bacd10fee2a3
37683754
secret: 5941ffa7a7c240b3aef1433d8e2b369f
37693755
config_version: 9
@@ -3776,8 +3762,7 @@
37763762
internal_ip: 127.0.0.1
37773763
public_ip: 192.0.2.46
37783764
bind_ip: null
3779-
label: null
3780-
ssh_host: 192.0.2.46
3765+
label: scionlab-1406-replenishes
37813766
uid: cb92022181bd4e26ba3a280193a5f352
37823767
secret: 1ee81564f8cf484d9310234e6cb1981e
37833768
config_version: 7
@@ -3791,7 +3776,6 @@
37913776
public_ip: null
37923777
bind_ip: null
37933778
label: null
3794-
ssh_host: null
37953779
uid: 8882e778031c4df79fadcc272632aa6c
37963780
secret: a2be4b0d3326420fbd4f7ae0d536166f
37973781
config_version: 6
@@ -3805,7 +3789,6 @@
38053789
public_ip: null
38063790
bind_ip: null
38073791
label: null
3808-
ssh_host: null
38093792
uid: 4781698deccd4d318ee5e9d54642c9c0
38103793
secret: 55c32d2364954c39a7c891366812a552
38113794
config_version: 5
@@ -3819,7 +3802,6 @@
38193802
public_ip: null
38203803
bind_ip: null
38213804
label: null
3822-
ssh_host: null
38233805
uid: e31440806a4248469345b8c8e6e79580
38243806
secret: e3bbb8648a0a4331b2d1d93807d44819
38253807
config_version: 5
@@ -3833,7 +3815,6 @@
38333815
public_ip: null
38343816
bind_ip: null
38353817
label: null
3836-
ssh_host: null
38373818
uid: 3bc8312ec6984acf89db4c11f7e1dc6d
38383819
secret: ec00adb395bf4d1d8b99ce40774be4d0
38393820
config_version: 6
@@ -3847,7 +3828,6 @@
38473828
public_ip: null
38483829
bind_ip: null
38493830
label: null
3850-
ssh_host: null
38513831
uid: feda4b58f8a041209bb6acce636c9a9e
38523832
secret: 9f932da7782a45dc991045baee592e01
38533833
config_version: 5

scionlab/fixtures/testtopo.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import pathlib
16+
import random
17+
import string
1518
from collections import namedtuple
1619
from scionlab.models.core import ISD, AS, Link, Host, Service
1720
from scionlab.models.user_as import AttachmentPoint
@@ -124,6 +127,7 @@ def create_testtopo():
124127
create_links()
125128
create_vpn()
126129
create_extraservices()
130+
name_hosts()
127131

128132

129133
def create_isds():
@@ -156,6 +160,18 @@ def create_extraservices():
156160
Service.objects.create(host=host, type=as_serv[1])
157161

158162

163+
def name_hosts():
164+
# assign random hostnames, loosely following the scionlab host naming convention
165+
hosts = Host.objects.filter(AS__owner=None)
166+
words = pathlib.Path('/usr/share/dict/words').read_text().split('\n')
167+
words = [w for w in words if all(c in string.ascii_lowercase for c in w)]
168+
names = random.sample(words, len(hosts))
169+
for host, name in zip(hosts, names):
170+
as_short_id = host.AS.as_id.split(':')[-1]
171+
host.label = 'scionlab-%s-%s' % (as_short_id, name)
172+
host.save()
173+
174+
159175
def _create_as(isd_id, as_id, label, public_ip, is_core=False, is_ap=False):
160176
isd = ISD.objects.get(isd_id=isd_id)
161177
as_ = AS.objects.create_with_default_services(
@@ -167,11 +183,6 @@ def _create_as(isd_id, as_id, label, public_ip, is_core=False, is_ap=False):
167183
init_certificates=False # Defer certificates generation
168184
)
169185

170-
# This is also used in the integration tests for some ASes.
171-
for host in as_.hosts.iterator():
172-
host.ssh_host = host.public_ip
173-
host.save()
174-
175186
if is_ap:
176187
AttachmentPoint.objects.create(AS=as_)
177188

scionlab/management/commands/export_zonefile.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@ def handle(self, *args, **options):
4747

4848
# Infrastructure
4949
# all hosts belonging to an AS without an owner
50-
for infra in Host.objects.filter(AS__owner=None).exclude(ssh_host=None):
51-
record_dict[infra.ssh_host] = infra.scion_address()
50+
for infra in Host.objects.filter(AS__owner=None).exclude(label=None):
51+
record_dict[infra.label] = infra.scion_address()
5252

5353
# write zonefile
5454
zone_file = ':Z: %s %s [\n' % (options['zone'], options['context'])
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Generated by Django 3.2.5 on 2022-02-09 05:18
2+
3+
from django.db import migrations, models
4+
5+
6+
def copy_ssh_host_to_label(apps, schema_editor):
7+
Host = apps.get_model("scionlab", "Host")
8+
Host.objects.filter(label=None).exclude(ssh_host=None).update(label=models.F('ssh_host'))
9+
10+
11+
class Migration(migrations.Migration):
12+
13+
dependencies = [
14+
('scionlab', '0006_bump_version_cs_hosts'),
15+
]
16+
17+
operations = [
18+
migrations.RunPython(copy_ssh_host_to_label, # forward
19+
lambda a, b: None), # backward
20+
migrations.RemoveField(
21+
model_name='host',
22+
name='ssh_host',
23+
),
24+
migrations.AlterField(
25+
model_name='host',
26+
name='label',
27+
field=models.CharField(blank=True, help_text='Hostname. For managed hosts, this should correspond to the hostname used in the ansible inventory.', max_length=255, null=True),
28+
),
29+
]

scionlab/models/core.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -491,13 +491,12 @@ class Host(models.Model):
491491
blank=True,
492492
help_text="Default bind IP for border router interfaces running on this host."
493493
)
494-
label = models.CharField(max_length=_MAX_LEN_DEFAULT, null=True, blank=True)
495-
496-
ssh_host = models.CharField(
494+
label = models.CharField(
497495
max_length=_MAX_LEN_DEFAULT,
498496
null=True,
499497
blank=True,
500-
help_text="Hostname or IP for management access via SSH. Configured in run/ssh_config."
498+
help_text="Hostname. For managed hosts, this should correspond to the hostname "
499+
"used in the ansible inventory."
501500
)
502501

503502
uid = models.CharField(max_length=_MAX_LEN_DEFAULT, unique=True, editable=False,
@@ -537,7 +536,6 @@ def update(self,
537536
public_ip=_placeholder,
538537
bind_ip=_placeholder,
539538
label=_placeholder,
540-
ssh_host=_placeholder,
541539
secret=_placeholder):
542540
"""
543541
Update the specified fields of this host instance, and immediately `save`.
@@ -547,7 +545,6 @@ def update(self,
547545
:param str public_ip: optional, default public IP for border router interfaces on this host
548546
:param str bind_ip: optional, default bind IP for border router interfaces on this host
549547
:param str label: optional
550-
:param str ssh_host: optional, hostname/IP for management access via SSH
551548
:param str secret: optional, a secret to authenticate the host. If `None` is given, a new
552549
random secret is generated.
553550
"""
@@ -565,8 +562,6 @@ def update(self,
565562
self.bind_ip = bind_ip or None
566563
if label is not _placeholder:
567564
self.label = label or None
568-
if ssh_host is not _placeholder:
569-
self.ssh_host = ssh_host or None
570565
if secret is not _placeholder:
571566
self.secret = secret or uuid.uuid4().hex
572567

scionlab/views/topology.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ def json_service(s):
135135
return {
136136
'type': service_type,
137137
'metrics_port': s.metrics_port,
138-
'ssh_host': s.host.ssh_host,
138+
'ssh_host': s.host.label, # TODO(matzf) rename this field to host or hostname
139139
}
140140

141141
def json_as(as_):

scripts/import_topo.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def create_as(ia, data):
9494
def create_hosts(as_, hosts):
9595
for name, data in hosts.items():
9696
as_short_id = as_.as_id.split(':')[-1]
97-
ssh_host = 'scionlab-%s-%s' % (as_short_id, name)
97+
hostname = 'scionlab-%s-%s' % (as_short_id, name)
9898

9999
internal_ip = data['address']
100100
public_ip = data.get('public', None)
@@ -103,7 +103,7 @@ def create_hosts(as_, hosts):
103103
public_ip=public_ip,
104104
bind_ip=None,
105105
internal_ip=internal_ip,
106-
ssh_host=ssh_host,
106+
label=hostname,
107107
)
108108

109109
service_host = as_.hosts.first()
@@ -114,8 +114,8 @@ def create_links(links):
114114
for link, data in links.items():
115115
a, b = link.split('--')
116116
try:
117-
host_a = Host.objects.filter(ssh_host__endswith=a).get()
118-
host_b = Host.objects.filter(ssh_host__endswith=b).get()
117+
host_a = Host.objects.filter(label__endswith=a).get()
118+
host_b = Host.objects.filter(label__endswith=b).get()
119119
except Host.DoesNotExist as e:
120120
print("Skipping link", a, b, ":", e)
121121
continue

0 commit comments

Comments
 (0)