Skip to content

Commit

Permalink
Merge pull request #109 from SelfhostedPro/port_labels
Browse files Browse the repository at this point in the history
Port labels
  • Loading branch information
SelfhostedPro authored Sep 24, 2020
2 parents 01dce88 + 8005419 commit 389be0c
Show file tree
Hide file tree
Showing 9 changed files with 188 additions and 51 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Yacht is a container management UI with a focus on templates and 1-click deploym
## Installation:
Currently only linux has been verified as working but we are open to the idea of supporting windows eventually as well.

**Keep in mind, this is a pre-alpha so the risk of data loss is real and it may not be stable**
**Keep in mind, this is an alpha so the risk of data loss is real and it may not be stable**

Once docker is installed you'll simply run the following commands to get started:
```
Expand Down
6 changes: 5 additions & 1 deletion backend/api/actions/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ def deploy_app(template: schemas.DeployForm):
template.image,
conv_restart2data(template.restart_policy),
conv_ports2data(template.ports),
conv_portlabels2data(template.ports),
conv_volumes2data(template.volumes),
conv_env2data(template.env),
conv_sysctls2data(template.sysctls),
Expand All @@ -85,8 +86,10 @@ def deploy_app(template: schemas.DeployForm):

return schemas.DeployLogs(logs=launch.logs())

def Merge(dict1, dict2):
return(dict2.update(dict1))

def launch_app(name, image, restart_policy, ports, volumes, env, sysctls, caps):
def launch_app(name, image, restart_policy, ports, portlabels, volumes, env, sysctls, caps):
dclient = docker.from_env()
lauch = dclient.containers.run(
name=name,
Expand All @@ -96,6 +99,7 @@ def launch_app(name, image, restart_policy, ports, volumes, env, sysctls, caps):
volumes=volumes,
environment=env,
sysctls=sysctls,
labels=portlabels,
cap_add=caps,
detach=True
)
Expand Down
63 changes: 57 additions & 6 deletions backend/api/db/crud/templates.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,33 @@ def add_template(db: Session, template: models.containers.Template):
else:
print('Invalid filetype')
raise
for entry in loaded_file:

if type(loaded_file) == list:
for entry in loaded_file:
if entry.get('ports'):
ports = conv_ports2dict(entry.get('ports', []))
sysctls = conv_sysctls2dict(entry.get('sysctls', []))

# Optional use classmethod from_dict
template_content = models.containers.TemplateItem(
type=int(entry['type']),
title=entry['title'],
platform=entry['platform'],
description=entry.get('description', ''),
name=entry.get('name', entry['title'].lower()),
logo=entry.get('logo', ''), # default logo here!
image=entry.get('image', ''),
notes=entry.get('note', ''),
categories=entry.get('categories', ''),
restart_policy=entry.get('restart_policy'),
ports=ports,
volumes=entry.get('volumes', []),
env=entry.get('env', []),
sysctls=sysctls,
cap_add=entry.get('cap_add', [])
)
_template.items.append(template_content)
elif type(loaded_file) == dict:
entry = loaded_file
ports = conv_ports2dict(entry.get('ports', []))
sysctls = conv_sysctls2dict(entry.get('sysctls', []))

Expand Down Expand Up @@ -112,12 +137,38 @@ def refresh_template(db: Session, template_id: id):
else:
print('Invalid filetype')
raise
for entry in loaded_file:

if type(loaded_file) == list:
for entry in loaded_file:

if entry.get('ports'):
ports = conv_ports2dict(entry.get('ports', []))
sysctls = conv_sysctls2dict(entry.get('sysctls', []))

item = models.TemplateItem(
type=int(entry['type']),
title=entry['title'],
platform=entry['platform'],
description=entry.get('description', ''),
name=entry.get('name', entry['title'].lower()),
logo=entry.get('logo', ''), # default logo here!
image=entry.get('image', ''),
notes=entry.get('note', ''),
categories=entry.get('categories', ''),
restart_policy=entry.get('restart_policy'),
ports=ports,
volumes=entry.get('volumes', []),
env=entry.get('env', []),
sysctls=sysctls,
cap_add=entry.get('cap_add', [])
)
items.append(item)
elif type(loaded_file) == dict:
entry = loaded_file
ports = conv_ports2dict(entry.get('ports', []))
sysctls = conv_sysctls2dict(entry.get('sysctls', []))

item = models.TemplateItem(
# Optional use classmethod from_dict
template_content = models.containers.TemplateItem(
type=int(entry['type']),
title=entry['title'],
platform=entry['platform'],
Expand All @@ -134,7 +185,7 @@ def refresh_template(db: Session, template_id: id):
sysctls=sysctls,
cap_add=entry.get('cap_add', [])
)
items.append(item)
items.append(template_content)
except Exception as exc:
print('Template update failed. ERR_001', exc)
raise
Expand Down
1 change: 1 addition & 0 deletions backend/api/db/schemas/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@


class PortsSchema(BaseModel):
label: Optional[str]
cport: str
hport: Optional[str]
proto: str
Expand Down
56 changes: 42 additions & 14 deletions backend/api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,20 +43,38 @@ def get_db():


def conv_ports2dict(data: List[str]) -> List[Dict[str, str]]:
delim = ':'
portlst = []
for port_data in data:
if not re.match(REGEXP_PORT_ASSIGN, port_data, flags=re.IGNORECASE):
raise ValueError('Malformed port assignment.')

hport, cport = None, port_data
if delim in cport:
hport, cport = cport.split(delim, 1)
if not hport:
hport = None
cport, proto = cport.split('/', 1)
portlst.append({'cport': cport, 'hport': hport, 'proto': proto})
return portlst
if type(data[0]) == dict:
delim = ':'
portlst = []
for port_data in data:
for label, port in port_data.items():
if not re.match(REGEXP_PORT_ASSIGN, port, flags=re.IGNORECASE):
raise ValueError('Malformed port assignment.')

hport, cport = None, port
if delim in cport:
hport, cport = cport.split(delim, 1)
if not hport:
hport = None
cport, proto = cport.split('/', 1)
portlst.append({'cport': cport, 'hport': hport, 'proto': proto, 'label': label})
return portlst

elif type(data) == list:
delim = ':'
portlst = []
for port_data in data:
if not re.match(REGEXP_PORT_ASSIGN, port_data, flags=re.IGNORECASE):
raise ValueError('Malformed port assignment.')

hport, cport = None, port_data
if delim in cport:
hport, cport = cport.split(delim, 1)
if not hport:
hport = None
cport, proto = cport.split('/', 1)
portlst.append({'cport': cport, 'hport': hport, 'proto': proto})
return portlst

# Input Format:
# [
Expand Down Expand Up @@ -108,6 +126,16 @@ def conv_ports2data(data):
ports.update({str(cport)+'/'+proto: hport for d in data})
return ports

def conv_portlabels2data(data):
labels = {}
for d in data:
if d.label and d.hport:
labels.update({ 'local.yacht.port.'+d.hport: d.label })
print(data)
elif d.label:
print("in order to have a label the hostport must be set")
return None
return labels
# Input Format:
# [
# {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,15 @@
<template v-slot:default>
<thead>
<tr>
<th class="text-center"> Label </th>
<th class="text-center">Container Port</th>
<th class="text-center">Host IP</th>
<th class="text-center">Host Port</th>
</tr>
</thead>
<tbody>
<tr v-for="(port, index) in convPorts(app.ports)" :key="index">
<td>{{app.Config.Labels[`local.yacht.port.${port.hport}`]}}</td>
<td>{{ port.cport }}</td>
<td>{{ port.hip }}</td>
<td>
Expand Down
16 changes: 16 additions & 0 deletions frontend/src/components/applications/ApplicationsForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,22 @@
leave-active-class="animated fadeOutLeft fast-anim"
>
<v-row v-for="(item, index) in form.ports" :key="index">
<v-col>
<ValidationProvider
name="Label"
rules=""
v-slot="{ errors, valid }"
>
<v-text-field
type="string"
label="Label"
placeholder="webui"
v-model="item['label']"
:error-messages="errors"
:success="valid"
></v-text-field>
</ValidationProvider>
</v-col>
<v-col>
<ValidationProvider
name="Container"
Expand Down
58 changes: 36 additions & 22 deletions frontend/src/components/applications/ApplicationsList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -90,28 +90,42 @@
</template>
<template v-slot:item.ports="{ item }">
<ins v-for="(port, index) in convPorts(item.ports)" :key="index">
<v-chip
class="mx-1"
v-if="port.hip == '0.0.0.0'"
color="indigo darken-2"
label
small
:href="'http://' + host_ip + ':' + port.hport"
target="_blank"
><v-icon small class="mr-1">mdi-link-variant</v-icon
>{{ port.hport }}</v-chip
>
<v-chip
class="ma-1"
v-else
color="indigo darken-2"
label
small
:href="'http://' + port.hip + ':' + port.hport"
target="_blank"
><v-icon small class="mr-1">mdi-link-variant</v-icon
>{{ port.hport }}</v-chip
>
<v-tooltip top transition="scale-transition">
<template v-slot:activator="{ on, attrs }">
<v-chip
v-on="on"
v-bind="attrs"
class="mx-1"
v-if="port.hip == '0.0.0.0'"
color="indigo darken-2"
label
small
:href="'http://' + host_ip + ':' + port.hport"
target="_blank"
><v-icon small class="mr-1">mdi-link-variant</v-icon
>{{
item.Config.Labels[`local.yacht.port.${port.hport}`] ||
port.hport
}}</v-chip
>
<v-chip
v-on="on"
v-bind="attrs"
class="ma-1"
v-else
color="indigo darken-2"
label
small
:href="'http://' + port.hip + ':' + port.hport"
target="_blank"
><v-icon small class="mr-1">mdi-link-variant</v-icon
>{{ item.Config.Labels || port.hport }}</v-chip
>
</template>
<span>
{{ port.hport }}
</span>
</v-tooltip>
</ins>
</template>
<template v-slot:item.image="{ item }">
Expand Down
Loading

0 comments on commit 389be0c

Please sign in to comment.