generated from layer5io/layer5-repo-template
-
Notifications
You must be signed in to change notification settings - Fork 95
/
host.go
163 lines (143 loc) · 4.73 KB
/
host.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package v1beta1
import (
"encoding/json"
"fmt"
"sync"
"time"
"github.com/google/uuid"
"github.com/layer5io/meshkit/database"
"github.com/layer5io/meshkit/utils/kubernetes"
"gorm.io/gorm"
)
var hostCreationLock sync.Mutex //Each entity will perform a check and if the host already doesn't exist, it will create a host. This lock will make sure that there are no race conditions.
type Host struct {
ID uuid.UUID `json:"-"`
Hostname string `json:"hostname"`
Port int `json:"port,omitempty"`
Metadata string `json:"metadata,omitempty"`
CreatedAt time.Time `json:"-"`
UpdatedAt time.Time `json:"-"`
IHost IHost `json:"-" gorm:"-"`
}
type MeshModelHostsWithEntitySummary struct {
ID uuid.UUID `json:"id"`
Hostname string `json:"hostname"`
Port int `json:"port"`
Summary EntitySummary `json:"summary"`
}
type EntitySummary struct {
Models int64 `json:"models"`
Components int64 `json:"components"`
Relationships int64 `json:"relationships"`
Policies int64 `json:"policies"`
}
type MesheryHostSummaryDB struct {
HostID uuid.UUID `json:"-" gorm:"id"`
Hostname string `json:"-" gorm:"hostname"`
Port int `json:"-" gorm:"port"`
Models int64 `json:"-" gorm:"models"`
Components int64 `json:"-" gorm:"components"`
Relationships int64 `json:"-" gorm:"relationships"`
Policies int64 `json:"-" gorm:"policies"`
}
type HostFilter struct {
Name string
Greedy bool //when set to true - instead of an exact match, name will be prefix matched
Trim bool //when set to true - the schema is not returned
DisplayName string
Version string
Sort string //asc or desc. Default behavior is asc
OrderOn string
Limit int //If 0 or unspecified then all records are returned and limit is not used
Offset int
}
func (h *Host) GenerateID() (uuid.UUID, error) {
byt, err := json.Marshal(h)
if err != nil {
return uuid.UUID{}, err
}
hID := uuid.NewSHA1(uuid.UUID{}, byt)
return hID, nil
}
func (h *Host) Create(db *database.Handler) (uuid.UUID, error) {
hID, err := h.GenerateID()
if err != nil {
return uuid.UUID{}, err
}
var host Host
hostCreationLock.Lock()
defer hostCreationLock.Unlock()
err = db.First(&host, "id = ?", hID).Error // check if the host already exists
if err != nil && err != gorm.ErrRecordNotFound {
return uuid.UUID{}, err
}
// if not exists then create a new host and return the id
if err == gorm.ErrRecordNotFound {
h.ID = hID
err = db.Create(&h).Error
if err != nil {
return uuid.UUID{}, err
}
return h.ID, nil
}
// else return the id of the existing host
return host.ID, nil
}
func (h *Host) AfterFind(tx *gorm.DB) error {
switch h.Hostname {
case "artifacthub":
h.IHost = ArtifactHub{}
case "kubernetes":
h.IHost = Kubernetes{}
default: // do nothing if the host is not pre-unknown. Currently adapters fall into this case.
return nil
}
return nil
}
// Each host from where meshmodels can be generated needs to implement this interface
// HandleDependents, contains host specific logic for provisioning required CRDs/operators for corresponding components.
type IHost interface {
HandleDependents(comp Component, kc *kubernetes.Client, isDeploy, performUpgrade bool) (string, error)
String() string
}
type ArtifactHub struct{}
func (ah ArtifactHub) HandleDependents(comp Component, kc *kubernetes.Client, isDeploy, performUpgrade bool) (summary string, err error) {
source_uri := comp.Annotations[fmt.Sprintf("%s.model.source_uri", MesheryAnnotationPrefix)]
act := kubernetes.UNINSTALL
if isDeploy {
act = kubernetes.INSTALL
}
if source_uri != "" {
err = kc.ApplyHelmChart(kubernetes.ApplyHelmChartConfig{
URL: source_uri,
Namespace: comp.Namespace,
CreateNamespace: true,
Action: act,
UpgradeIfInstalled: performUpgrade,
})
if err != nil {
if !isDeploy {
summary = fmt.Sprintf("error undeploying dependent helm chart for %s, please proceed with manual uninstall or try again", comp.Name)
} else {
summary = fmt.Sprintf("error deploying dependent helm chart for %s, please procced with manual install or try again", comp.Name)
}
} else {
if !isDeploy {
summary = fmt.Sprintf("Undeployed dependent helm chart for %s", comp.Name)
} else {
summary = fmt.Sprintf("Deployed dependent helm chart for %s", comp.Name)
}
}
}
return summary, err
}
func (ah ArtifactHub) String() string {
return "artifacthub"
}
type Kubernetes struct{}
func (k Kubernetes) HandleDependents(comp Component, kc *kubernetes.Client, isDeploy, performUpgrade bool) (summary string, err error) {
return summary, err
}
func (k Kubernetes) String() string {
return "kubernetes"
}