mirror of
https://github.com/cuigh/swirl
synced 2024-12-28 14:51:57 +00:00
Correct handling host and ingress networks when editing service
This commit is contained in:
parent
63cc555e21
commit
70837391d1
@ -5,6 +5,7 @@
|
|||||||
> As this version contains some incompatible modifications, it is recommended to redeploy instead of upgrading directly.
|
> As this version contains some incompatible modifications, it is recommended to redeploy instead of upgrading directly.
|
||||||
|
|
||||||
* feat: Refactor UI with vue3.
|
* feat: Refactor UI with vue3.
|
||||||
|
* feat: Add support to agent. Swirl can connect to any container even in swarm mode now.
|
||||||
* feat: Switch to official MongoDB driver.
|
* feat: Switch to official MongoDB driver.
|
||||||
* feat: Allow set chart margins.
|
* feat: Allow set chart margins.
|
||||||
* fix: Some args are incorrect when generating service command line.
|
* fix: Some args are incorrect when generating service command line.
|
||||||
|
@ -56,26 +56,31 @@ func (b *serviceBiz) Find(name string, status bool) (service *Service, raw strin
|
|||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
service = newService(&s)
|
service = newService(&s)
|
||||||
//err = b.fillNetworks(service, &s)
|
err = b.fillNetworks(service)
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *serviceBiz) fillNetworks(service *Service, s *swarm.Service) error {
|
func (b *serviceBiz) fillNetworks(service *Service) error {
|
||||||
if len(s.Endpoint.VirtualIPs) == 0 {
|
if len(service.Endpoint.VIPs) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var ids = make([]string, len(s.Endpoint.VirtualIPs))
|
var ids = make([]string, len(service.Endpoint.VIPs))
|
||||||
for i, vip := range s.Endpoint.VirtualIPs {
|
for i, vip := range service.Endpoint.VIPs {
|
||||||
ids[i] = vip.NetworkID
|
ids[i] = vip.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
names, err := b.d.NetworkNames(context.TODO(), ids...)
|
names, err := b.d.NetworkNames(context.TODO(), ids...)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
for i, vip := range s.Endpoint.VirtualIPs {
|
for i := range service.Endpoint.VIPs {
|
||||||
ids[i] = names[vip.NetworkID] + ":" + vip.NetworkID
|
vip := &service.Endpoint.VIPs[i]
|
||||||
|
vip.Name = names[vip.ID]
|
||||||
|
// ingress network cannot be explicitly attached.
|
||||||
|
if vip.Name != "ingress" {
|
||||||
|
service.Networks = append(service.Networks, vip.Name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
service.Networks = ids
|
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -215,7 +220,7 @@ type Service struct {
|
|||||||
Env data.Options `json:"env,omitempty"`
|
Env data.Options `json:"env,omitempty"`
|
||||||
Labels data.Options `json:"labels,omitempty"`
|
Labels data.Options `json:"labels,omitempty"`
|
||||||
ContainerLabels data.Options `json:"containerLabels,omitempty"`
|
ContainerLabels data.Options `json:"containerLabels,omitempty"`
|
||||||
Networks []string `json:"networks,omitempty"`
|
Networks []string `json:"networks,omitempty"` // only for edit
|
||||||
Mounts []Mount `json:"mounts,omitempty"`
|
Mounts []Mount `json:"mounts,omitempty"`
|
||||||
Update struct {
|
Update struct {
|
||||||
State string `json:"state,omitempty"`
|
State string `json:"state,omitempty"`
|
||||||
@ -548,11 +553,6 @@ func newService(s *swarm.Service) *Service {
|
|||||||
service.Update.Message = s.UpdateStatus.Message
|
service.Update.Message = s.UpdateStatus.Message
|
||||||
}
|
}
|
||||||
|
|
||||||
// Networks
|
|
||||||
for _, n := range s.Spec.TaskTemplate.Networks {
|
|
||||||
service.Networks = append(service.Networks, n.Target)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Endpoint
|
// Endpoint
|
||||||
service.Endpoint.Mode = s.Endpoint.Spec.Mode
|
service.Endpoint.Mode = s.Endpoint.Spec.Mode
|
||||||
for _, vip := range s.Endpoint.VirtualIPs {
|
for _, vip := range s.Endpoint.VirtualIPs {
|
||||||
|
98
compose.yml
98
compose.yml
@ -1,16 +1,16 @@
|
|||||||
version: '3'
|
version: '3.8'
|
||||||
|
|
||||||
services:
|
services:
|
||||||
swirl:
|
swirl:
|
||||||
image: cuigh/swirl
|
image: cuigh/swirl
|
||||||
environment:
|
environment:
|
||||||
DB_ADDRESS: mongodb://mongo:27017/swirl
|
DB_ADDRESS: mongodb://<database_address>
|
||||||
DOCKER_ENDPOINT: tcp://swirl_manager_agent:2375
|
DOCKER_ENDPOINT: tcp://swirl_manager_agent:2375
|
||||||
AGENTS: swirl_manager_agent,swirl_worker_agent
|
AGENTS: swirl_manager_agent,swirl_worker_agent
|
||||||
ports:
|
|
||||||
- "8001:8001"
|
|
||||||
networks:
|
networks:
|
||||||
- net
|
- net
|
||||||
|
ports:
|
||||||
|
- "8001:8001"
|
||||||
deploy:
|
deploy:
|
||||||
replicas: 2
|
replicas: 2
|
||||||
placement:
|
placement:
|
||||||
@ -18,10 +18,10 @@ services:
|
|||||||
|
|
||||||
manager_agent:
|
manager_agent:
|
||||||
image: cuigh/socat
|
image: cuigh/socat
|
||||||
volumes:
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
networks:
|
networks:
|
||||||
- net
|
- net
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
deploy:
|
deploy:
|
||||||
mode: global
|
mode: global
|
||||||
placement:
|
placement:
|
||||||
@ -29,53 +29,63 @@ services:
|
|||||||
|
|
||||||
worker_agent:
|
worker_agent:
|
||||||
image: cuigh/socat
|
image: cuigh/socat
|
||||||
volumes:
|
|
||||||
- /var/run/docker.sock:/var/run/docker.sock
|
|
||||||
networks:
|
networks:
|
||||||
- net
|
- net
|
||||||
|
volumes:
|
||||||
|
- /var/run/docker.sock:/var/run/docker.sock
|
||||||
deploy:
|
deploy:
|
||||||
mode: global
|
mode: global
|
||||||
placement:
|
placement:
|
||||||
constraints: [ node.role == worker ]
|
constraints: [ node.role == worker ]
|
||||||
|
|
||||||
# prometheus:
|
# prometheus:
|
||||||
# image: prom/prometheus
|
# image: prom/prometheus
|
||||||
# volumes:
|
# networks:
|
||||||
# - prometheus:/prometheus
|
# - net
|
||||||
# networks:
|
# volumes:
|
||||||
# - net
|
# - prometheus:/prometheus
|
||||||
# deploy:
|
# configs:
|
||||||
# replicas: 1
|
# - source: prometheus.yml
|
||||||
# placement:
|
# target: /etc/prometheus/prometheus.yml
|
||||||
# constraints: [ node.labels.app.prometheus == true ]
|
# deploy:
|
||||||
|
# replicas: 1
|
||||||
# cadvisor:
|
|
||||||
# image: gcr.io/cadvisor/cadvisor
|
|
||||||
# volumes:
|
|
||||||
# - /:/rootfs:ro
|
|
||||||
# - /sys:/sys:ro
|
|
||||||
# - /var/lib/docker:/var/lib/docker:ro
|
|
||||||
# - /var/run:/var/run:ro
|
|
||||||
# - /var/run/docker.sock:/var/run/docker.sock:ro
|
|
||||||
# networks:
|
|
||||||
# - net
|
|
||||||
# deploy:
|
|
||||||
# mode: global
|
|
||||||
|
|
||||||
mongo:
|
|
||||||
image: mongo
|
|
||||||
volumes:
|
|
||||||
- mongo:/data/db
|
|
||||||
networks:
|
|
||||||
- net
|
|
||||||
deploy:
|
|
||||||
replicas: 1
|
|
||||||
# placement:
|
# placement:
|
||||||
# constraints: [ node.labels.app.mongo == true ]
|
# constraints: [ node.labels.app.prometheus == true ]
|
||||||
|
|
||||||
volumes:
|
# cadvisor:
|
||||||
prometheus:
|
# image: gcr.io/cadvisor/cadvisor
|
||||||
mongo:
|
# networks:
|
||||||
|
# - net
|
||||||
|
# volumes:
|
||||||
|
# - /:/rootfs:ro
|
||||||
|
# - /dev/disk/:/dev/disk:ro
|
||||||
|
# - /sys:/sys:ro
|
||||||
|
# - /var/run:/var/run:ro
|
||||||
|
# - /var/lib/docker:/var/lib/docker:ro
|
||||||
|
# privileged: true
|
||||||
|
# deploy:
|
||||||
|
# mode: global
|
||||||
|
#
|
||||||
|
# node:
|
||||||
|
# image: quay.io/prometheus/node-exporter
|
||||||
|
# command:
|
||||||
|
# - '--path.rootfs=/host'
|
||||||
|
# networks:
|
||||||
|
# - host
|
||||||
|
# pid: host
|
||||||
|
# volumes:
|
||||||
|
# - /:/host:ro,rslave
|
||||||
|
# deploy:
|
||||||
|
# mode: global
|
||||||
|
|
||||||
|
#volumes:
|
||||||
|
# prometheus:
|
||||||
|
|
||||||
|
#configs:
|
||||||
|
# prometheus.yml:
|
||||||
|
# external: true
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
|
# host:
|
||||||
|
# external: true
|
||||||
net:
|
net:
|
@ -38,6 +38,40 @@ func (d *Dao) SessionUpdateExpiry(ctx context.Context, id string, expiry time.Ti
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Dao) SessionUpdateDirty(ctx context.Context, userID string, roleID string) (err error) {
|
||||||
|
contains := func(arr []string, str string) bool {
|
||||||
|
for _, s := range arr {
|
||||||
|
if s == str {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
buf []byte
|
||||||
|
now = time.Now()
|
||||||
|
)
|
||||||
|
return d.db.Update(func(tx *bolt.Tx) (err error) {
|
||||||
|
b := tx.Bucket([]byte(Session))
|
||||||
|
return b.ForEach(func(k, v []byte) error {
|
||||||
|
session := &model.Session{}
|
||||||
|
if err = decode(v, session); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if (userID != "" && session.UserID == userID) || (roleID != "" && contains(session.Roles, roleID)) {
|
||||||
|
session.Dirty = true
|
||||||
|
session.UpdatedAt = now
|
||||||
|
if buf, err = encode(session); err == nil {
|
||||||
|
err = b.Put(k, buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// SessionPrune cleans up expired logs.
|
// SessionPrune cleans up expired logs.
|
||||||
func (d *Dao) SessionPrune() {
|
func (d *Dao) SessionPrune() {
|
||||||
err := d.db.Update(func(tx *bolt.Tx) (err error) {
|
err := d.db.Update(func(tx *bolt.Tx) (err error) {
|
||||||
|
@ -37,6 +37,7 @@ type Interface interface {
|
|||||||
SessionCreate(ctx context.Context, session *model.Session) error
|
SessionCreate(ctx context.Context, session *model.Session) error
|
||||||
SessionUpdate(ctx context.Context, session *model.Session) error
|
SessionUpdate(ctx context.Context, session *model.Session) error
|
||||||
SessionUpdateExpiry(ctx context.Context, id string, expiry time.Time) (err error)
|
SessionUpdateExpiry(ctx context.Context, id string, expiry time.Time) (err error)
|
||||||
|
SessionUpdateDirty(ctx context.Context, userID string, roleID string) (err error)
|
||||||
|
|
||||||
RegistryGet(ctx context.Context, id string) (*model.Registry, error)
|
RegistryGet(ctx context.Context, id string) (*model.Registry, error)
|
||||||
RegistryGetByURL(ctx context.Context, url string) (registry *model.Registry, err error)
|
RegistryGetByURL(ctx context.Context, url string) (registry *model.Registry, err error)
|
||||||
|
@ -36,3 +36,21 @@ func (d *Dao) SessionUpdateExpiry(ctx context.Context, id string, expiry time.Ti
|
|||||||
}
|
}
|
||||||
return d.update(ctx, Session, id, update)
|
return d.update(ctx, Session, id, update)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *Dao) SessionUpdateDirty(ctx context.Context, userID string, roleID string) (err error) {
|
||||||
|
filter := bson.M{}
|
||||||
|
if userID != "" {
|
||||||
|
filter["userId"] = userID
|
||||||
|
} else if roleID != "" {
|
||||||
|
filter["roles"] = roleID
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
update := bson.M{
|
||||||
|
"dirty": true,
|
||||||
|
"updated_by": time.Now(),
|
||||||
|
}
|
||||||
|
_, err = d.db.Collection(Session).UpdateMany(ctx, filter, update)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
@ -4,8 +4,10 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/cuigh/auxo/app/container"
|
"github.com/cuigh/auxo/app/container"
|
||||||
|
"github.com/cuigh/auxo/cache"
|
||||||
"github.com/cuigh/auxo/errors"
|
"github.com/cuigh/auxo/errors"
|
||||||
"github.com/cuigh/auxo/log"
|
"github.com/cuigh/auxo/log"
|
||||||
"github.com/cuigh/auxo/util/lazy"
|
"github.com/cuigh/auxo/util/lazy"
|
||||||
@ -21,16 +23,21 @@ func newVersion(v uint64) swarm.Version {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Docker struct {
|
type Docker struct {
|
||||||
c *client.Client
|
c *client.Client
|
||||||
locker sync.Mutex
|
locker sync.Mutex
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
agents sync.Map
|
nodes cache.Value
|
||||||
|
agents sync.Map
|
||||||
|
networks sync.Map
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDocker() *Docker {
|
func NewDocker() *Docker {
|
||||||
return &Docker{
|
d := &Docker{
|
||||||
logger: log.Get("docker"),
|
logger: log.Get("docker"),
|
||||||
|
nodes: cache.Value{TTL: 30 * time.Minute},
|
||||||
}
|
}
|
||||||
|
d.nodes.Load = d.loadCache
|
||||||
|
return d
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Docker) call(fn func(c *client.Client) error) error {
|
func (d *Docker) call(fn func(c *client.Client) error) error {
|
||||||
|
@ -71,16 +71,32 @@ func (d *Docker) NetworkInspect(ctx context.Context, name string) (network types
|
|||||||
|
|
||||||
// NetworkNames return network names by id list.
|
// NetworkNames return network names by id list.
|
||||||
func (d *Docker) NetworkNames(ctx context.Context, ids ...string) (names map[string]string, err error) {
|
func (d *Docker) NetworkNames(ctx context.Context, ids ...string) (names map[string]string, err error) {
|
||||||
var c *client.Client
|
var (
|
||||||
if c, err = d.client(); err == nil {
|
c *client.Client
|
||||||
names = make(map[string]string)
|
network types.NetworkResource
|
||||||
for _, id := range ids {
|
lookup = func(id string) (n types.NetworkResource, e error) {
|
||||||
var n types.NetworkResource
|
if c == nil {
|
||||||
n, err = c.NetworkInspect(ctx, id, types.NetworkInspectOptions{})
|
if c, e = d.client(); e != nil {
|
||||||
if err != nil {
|
return
|
||||||
break
|
}
|
||||||
}
|
}
|
||||||
names[id] = n.Name
|
n, e = c.NetworkInspect(ctx, id, types.NetworkInspectOptions{})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
names = make(map[string]string)
|
||||||
|
for _, id := range ids {
|
||||||
|
name, ok := d.networks.Load(id)
|
||||||
|
if ok {
|
||||||
|
names[id] = name.(string)
|
||||||
|
} else {
|
||||||
|
network, err = lookup(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
names[id] = network.Name
|
||||||
|
d.networks.Store(id, network.Name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -3,9 +3,7 @@ package docker
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"sort"
|
"sort"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/cuigh/auxo/cache"
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
"github.com/docker/docker/api/types/swarm"
|
"github.com/docker/docker/api/types/swarm"
|
||||||
"github.com/docker/docker/client"
|
"github.com/docker/docker/client"
|
||||||
@ -63,13 +61,9 @@ func (d *Docker) NodeInspect(ctx context.Context, id string) (node swarm.Node, r
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *Docker) NodeMap() (map[string]*Node, error) {
|
func (d *Docker) NodeMap() (map[string]*Node, error) {
|
||||||
v := cache.Value{
|
nodes, err := d.nodes.Get(true)
|
||||||
TTL: 30 * time.Minute,
|
|
||||||
Load: func() (interface{}, error) { return d.loadCache() },
|
|
||||||
}
|
|
||||||
value, err := v.Get(true)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return value.(map[string]*Node), nil
|
return nodes.(map[string]*Node), nil
|
||||||
}
|
}
|
||||||
|
@ -27,32 +27,22 @@ import {
|
|||||||
NIcon,
|
NIcon,
|
||||||
NButton,
|
NButton,
|
||||||
} from "naive-ui";
|
} from "naive-ui";
|
||||||
import { ref, onMounted, PropType } from "vue";
|
import { ref, onMounted } from "vue";
|
||||||
import { CloseOutline, MenuOutline } from "@vicons/ionicons5";
|
import { CloseOutline, MenuOutline } from "@vicons/ionicons5";
|
||||||
import { useResizeObserver } from '@vueuse/core'
|
import { useResizeObserver } from '@vueuse/core'
|
||||||
import { ChartInfo } from "@/api/chart";
|
import { ChartInfo } from "@/api/dashboard";
|
||||||
import { createChart } from "./chart";
|
import { createChart } from "./chart";
|
||||||
import type { Chart } from "./chart";
|
import type { Chart } from "./chart";
|
||||||
|
|
||||||
// TS:
|
interface Props {
|
||||||
// interface Props {
|
info: ChartInfo;
|
||||||
// msg?: string
|
data?: any;
|
||||||
// labels?: string[]
|
}
|
||||||
// }
|
|
||||||
// const props = withDefaults(defineProps<Props>(), {
|
|
||||||
// msg: 'hello',
|
|
||||||
// labels: () => ['one', 'two']
|
|
||||||
// })
|
|
||||||
|
|
||||||
const props = defineProps({
|
// const props = withDefaults(defineProps<Props>(), {
|
||||||
info: {
|
// data: () => null,
|
||||||
type: Object as PropType<ChartInfo>,
|
// })
|
||||||
required: true,
|
const props = defineProps<Props>()
|
||||||
},
|
|
||||||
data: {
|
|
||||||
type: Object,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
const emits = defineEmits(['remove'])
|
const emits = defineEmits(['remove'])
|
||||||
|
|
||||||
const container = ref()
|
const container = ref()
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import * as echarts from "echarts";
|
import * as echarts from "echarts";
|
||||||
import { ChartInfo } from "@/api/chart";
|
import { ChartInfo } from "@/api/dashboard";
|
||||||
import { store } from "@/store";
|
import { store } from "@/store";
|
||||||
|
|
||||||
export abstract class Chart {
|
export abstract class Chart {
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
<n-form-item-gi :label="t('objects.network', 2)" span="2" path="networks">
|
<n-form-item-gi :label="t('objects.network', 2)" span="2" path="networks">
|
||||||
<n-checkbox-group v-model:value="model.networks">
|
<n-checkbox-group v-model:value="model.networks">
|
||||||
<n-space item-style="display: flex;">
|
<n-space item-style="display: flex;">
|
||||||
<n-checkbox :value="n.id" :label="n.name" v-for="n of networks" />
|
<n-checkbox :value="n.name" :label="n.name" v-for="n of networks" />
|
||||||
</n-space>
|
</n-space>
|
||||||
</n-checkbox-group>
|
</n-checkbox-group>
|
||||||
</n-form-item-gi>
|
</n-form-item-gi>
|
||||||
@ -653,22 +653,22 @@ function newFile() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function fetchData() {
|
async function fetchData() {
|
||||||
const name = route.params.name as string || ''
|
const name = route.params.name as string
|
||||||
if (name) {
|
|
||||||
let r = await serviceApi.find(name);
|
name && serviceApi.find(name, true).then(r => {
|
||||||
model.value = r.data?.service as Service;
|
model.value = r.data?.service as Service;
|
||||||
}
|
});
|
||||||
|
|
||||||
let nr = await networkApi.search();
|
let results = await Promise.all([
|
||||||
networks.value = nr.data as Network[];
|
networkApi.search(),
|
||||||
|
configApi.search({ pageIndex: 1, pageSize: 1000 }),
|
||||||
let cr = await configApi.search({ pageIndex: 1, pageSize: 1000 });
|
secretApi.search({ pageIndex: 1, pageSize: 1000 }),
|
||||||
configFiles.value = cr.data?.items.map(c => {
|
])
|
||||||
|
networks.value = results[0].data?.filter(n => n.name != 'ingress') as Network[];
|
||||||
|
configFiles.value = results[1].data?.items.map(c => {
|
||||||
return { label: c.name, value: `${c.id}:${c.name}` }
|
return { label: c.name, value: `${c.id}:${c.name}` }
|
||||||
})
|
})
|
||||||
|
secretFiles.value = results[2].data?.items.map(c => {
|
||||||
let sr = await secretApi.search({ pageIndex: 1, pageSize: 1000 });
|
|
||||||
secretFiles.value = sr.data?.items.map(c => {
|
|
||||||
return { label: c.name, value: `${c.id}:${c.name}` }
|
return { label: c.name, value: `${c.id}:${c.name}` }
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -462,7 +462,7 @@
|
|||||||
round
|
round
|
||||||
size="small"
|
size="small"
|
||||||
v-for="n in t.networks"
|
v-for="n in t.networks"
|
||||||
>{{ n.name + ": " + n.ips.join(',') }}</n-tag>
|
>{{ isEmpty(n.ips) ? n.name : (n.name + ": " + n.ips?.join(',')) }}</n-tag>
|
||||||
</n-space>
|
</n-space>
|
||||||
</td>
|
</td>
|
||||||
<td>{{ t.updatedAt }}</td>
|
<td>{{ t.updatedAt }}</td>
|
||||||
@ -508,7 +508,6 @@ import serviceApi from "@/api/service";
|
|||||||
import type { Service } from "@/api/service";
|
import type { Service } from "@/api/service";
|
||||||
import taskApi from "@/api/task";
|
import taskApi from "@/api/task";
|
||||||
import type { Task } from "@/api/task";
|
import type { Task } from "@/api/task";
|
||||||
import networkApi from "@/api/network";
|
|
||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
import { router } from "@/router/router";
|
import { router } from "@/router/router";
|
||||||
import { isEmpty } from "@/utils";
|
import { isEmpty } from "@/utils";
|
||||||
@ -703,17 +702,11 @@ async function fetchData() {
|
|||||||
let results = await Promise.all([
|
let results = await Promise.all([
|
||||||
serviceApi.find(name, true),
|
serviceApi.find(name, true),
|
||||||
taskApi.search({ service: name, pageIndex: 1, pageSize: 100 }),
|
taskApi.search({ service: name, pageIndex: 1, pageSize: 100 }),
|
||||||
networkApi.search(),
|
|
||||||
])
|
])
|
||||||
|
|
||||||
service.value = results[0].data?.service as Service
|
service.value = results[0].data?.service as Service
|
||||||
raw.value = results[0].data?.raw as string;
|
raw.value = results[0].data?.raw as string;
|
||||||
tasks.value = results[1].data?.items as Task[];
|
tasks.value = results[1].data?.items as Task[];
|
||||||
if (service.value.endpoint.vips && service.value.endpoint.vips.length > 0) {
|
|
||||||
let networks = new Map<string, string>();
|
|
||||||
results[2].data?.forEach(n => networks.set(n.id, n.name))
|
|
||||||
service.value.endpoint.vips.forEach(vip => vip.name = networks.get(vip.id) as string)
|
|
||||||
}
|
|
||||||
cli.value = generateCli(service.value)
|
cli.value = generateCli(service.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user