support for custom component types and add thirdcomponent componentdefinition

This commit is contained in:
barnettZQG 2021-06-30 16:46:39 +08:00
parent 5a63dc5dd7
commit 4a74d64e1d
70 changed files with 4301 additions and 270 deletions

View File

@ -61,6 +61,8 @@ generate: controller-gen
chmod +x vendor/k8s.io/code-generator/generate-groups.sh
./hack/k8s/codegen/update-generated.sh
$(CONTROLLER_GEN) object:headerFile="hack/k8s/codegen/boilerplate.go.txt" paths="./pkg/apis/..."
cp -r github.com/goodrain/rainbond/pkg/ ./pkg/
rm -rf github.com/
# find or download controller-gen
# download controller-gen if necessary

View File

@ -666,14 +666,16 @@ func (t *TenantStruct) CreateService(w http.ResponseWriter, r *http.Request) {
handler.GetEtcdHandler().CleanServiceCheckData(ss.EtcdKey)
values := url.Values{}
if ss.Endpoints != nil && strings.TrimSpace(ss.Endpoints.Static) != "" {
if strings.Contains(ss.Endpoints.Static, "127.0.0.1") {
values["ip"] = []string{"The ip field is can't contains '127.0.0.1'"}
if ss.Endpoints != nil {
for _, endpoint := range ss.Endpoints.Static {
if strings.Contains(endpoint, "127.0.0.1") {
values["ip"] = []string{"The ip field is can't contains '127.0.0.1'"}
}
}
if len(values) > 0 {
httputil.ReturnValidationError(r, w, values)
return
}
}
if len(values) > 0 {
httputil.ReturnValidationError(r, w, values)
return
}
tenantID := r.Context().Value(ctxutil.ContextKey("tenant_id")).(string)

View File

@ -98,7 +98,7 @@ func (a *ApplicationAction) CreateApp(ctx context.Context, req *model.Applicatio
}
if appReq.AppType == model.AppTypeHelm {
// create helmapp.rainbond.goodrain.io
// create helmapp.rainbond.io
return a.createHelmApp(ctx, appReq)
}
return nil

View File

@ -718,20 +718,12 @@ func (s *ServiceAction) ServiceCreate(sc *api_model.ServiceStruct) error {
tx.Rollback()
return fmt.Errorf("endpoints can not be empty for third-party service")
}
if config := strings.Replace(sc.Endpoints.Discovery, " ", "", -1); config != "" {
var cfg dCfg
err := json.Unmarshal([]byte(config), &cfg)
if err != nil {
tx.Rollback()
return err
}
if sc.Endpoints.Kubernetes != nil {
c := &dbmodel.ThirdPartySvcDiscoveryCfg{
ServiceID: sc.ServiceID,
Type: cfg.Type,
Servers: strings.Join(cfg.Servers, ","),
Key: cfg.Key,
Username: cfg.Username,
Password: cfg.Password,
ServiceID: sc.ServiceID,
Type: string(dbmodel.DiscorveryTypeKubernetes),
Namespace: sc.Endpoints.Kubernetes.Namespace,
ServiceName: sc.Endpoints.Kubernetes.ServiceName,
}
if err := db.GetManager().ThirdPartySvcDiscoveryCfgDaoTransactions(tx).
AddModel(c); err != nil {
@ -739,15 +731,10 @@ func (s *ServiceAction) ServiceCreate(sc *api_model.ServiceStruct) error {
tx.Rollback()
return err
}
} else if static := strings.Replace(sc.Endpoints.Static, " ", "", -1); static != "" {
var obj []string
err := json.Unmarshal([]byte(static), &obj)
if err != nil {
tx.Rollback()
return err
}
}
if sc.Endpoints.Static != nil {
trueValue := true
for _, o := range obj {
for _, o := range sc.Endpoints.Static {
ep := &dbmodel.Endpoint{
ServiceID: sc.ServiceID,
UUID: core_util.NewUUID(),
@ -852,33 +839,9 @@ func (s *ServiceAction) ServiceCreate(sc *api_model.ServiceStruct) error {
}
logrus.Debugf("create a new app %s success", ts.ServiceAlias)
if sc.Kind == dbmodel.ServiceKindThirdParty.String() {
s.openInnerPorts(ts.ServiceID, ports)
}
return nil
}
func (s *ServiceAction) openInnerPorts(componentID string, ports []dbmodel.TenantServicesPort) {
// TODO: support open multiple ports in one task.
for _, port := range ports {
if !port.IsOpen() {
continue
}
logrus.Infof("component: %s; port: %d; open inner ports", componentID, port.ContainerPort)
task := &ComponentIngressTask{
ComponentID: componentID,
Action: "port-open",
Port: port.ContainerPort,
IsInner: true,
}
if err := GetGatewayHandler().SendTask(task); err != nil {
logrus.Warningf("send runtime message about gateway failure %s", err.Error())
}
}
}
func (s *ServiceAction) convertProbeModel(req *api_model.ServiceProbe, serviceID string) *dbmodel.TenantServiceProbe {
return &dbmodel.TenantServiceProbe{
ServiceID: serviceID,

View File

@ -44,6 +44,7 @@ import (
v1 "k8s.io/api/core/v1"
k8sErrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/kubernetes"
k8sclient "sigs.k8s.io/controller-runtime/pkg/client"
@ -59,7 +60,7 @@ type TenantAction struct {
cacheTime time.Time
prometheusCli prometheus.Interface
k8sClient k8sclient.Client
resources map[string]k8sclient.Object
resources map[string]runtime.Object
}
//CreateTenManager create Manger
@ -69,7 +70,7 @@ func CreateTenManager(mqc mqclient.MQClient, statusCli *client.AppRuntimeSyncCli
prometheusCli prometheus.Interface,
k8sClient k8sclient.Client) *TenantAction {
resources := map[string]k8sclient.Object{
resources := map[string]runtime.Object{
"helmApp": &v1alpha1.HelmApp{},
"service": &corev1.Service{},
}

View File

@ -362,8 +362,13 @@ type ServiceStruct struct {
// Endpoints holds third-party service endpoints or configuraion to get endpoints.
type Endpoints struct {
Static string `json:"static" validate:"static"`
Discovery string `json:"discovery" validate:"discovery"`
Static []string `json:"static" validate:"static"`
Kubernetes *EndpointKubernetes `json:"kubernetes" validate:"kubernetes"`
}
type EndpointKubernetes struct {
Namespace string `json:"namespace"`
ServiceName string `json:"serviceName"`
}
//TenantServiceVolumeStruct -

View File

@ -49,7 +49,7 @@ type EndpointResp struct {
// ThridPartyServiceProbe is the json obejct in the request
// to update or fetch the ThridPartyServiceProbe.
type ThridPartyServiceProbe struct {
Scheme string `json:"scheme;"`
Scheme string `json:"scheme"`
Path string `json:"path"`
Port int `json:"port"`
TimeInterval int `json:"time_interval"`

View File

@ -37,6 +37,10 @@ import (
)
func main() {
if os.Getenv("LOG_LEVEL") != "" {
level, _ := logrus.ParseLevel(os.Getenv("LOG_LEVEL"))
logrus.SetLevel(level)
}
if len(os.Args) > 1 && os.Args[1] == "version" {
cmd.ShowVersion("sidecar")
}
@ -49,7 +53,7 @@ func main() {
client := &http.Client{
Timeout: time.Duration(requestTimeoutMillis) * time.Millisecond,
}
logrus.Infof("Waiting for Envoy proxy to be ready (timeout: %d seconds)...", timeoutSeconds)
logrus.Debugf("Waiting for Envoy proxy to be ready (timeout: %d seconds)...", timeoutSeconds)
var err error
timeoutAt := time.Now().Add(time.Duration(timeoutSeconds) * time.Second)
@ -59,7 +63,7 @@ func main() {
logrus.Infof("Sidecar server is ready!")
break
}
logrus.Infof("Not ready yet: %v", err)
logrus.Debugf("Not ready yet: %v", err)
time.Sleep(time.Duration(periodMillis) * time.Millisecond)
}
if len(os.Args) > 2 && os.Args[2] != "0" {
@ -69,14 +73,14 @@ func main() {
logrus.Infof("Sidecar is ready!")
os.Exit(0)
}
logrus.Infof("Not ready yet: %v", err)
logrus.Debugf("Not ready yet: %v", err)
time.Sleep(time.Duration(periodMillis) * time.Millisecond)
}
} else {
logrus.Infof("Sidecar is ready!")
os.Exit(0)
}
logrus.Errorf("timeout waiting for Envoy proxy to become ready. Last error: %v", err)
logrus.Errorf("timeout waiting for Mesh Sidecar to become ready. Last error: %v", err)
os.Exit(1)
}
if len(os.Args) > 1 && os.Args[1] == "run" {
@ -106,7 +110,7 @@ func Run() error {
ticker := time.NewTicker(time.Second * 5)
defer ticker.Stop()
//step finally: listen Signal
term := make(chan os.Signal)
term := make(chan os.Signal, 1)
signal.Notify(term, os.Interrupt, syscall.SIGTERM)
for {
select {

View File

@ -28,10 +28,12 @@ import (
"github.com/goodrain/rainbond/db"
"github.com/goodrain/rainbond/db/config"
"github.com/goodrain/rainbond/event"
"github.com/goodrain/rainbond/pkg/common"
"github.com/goodrain/rainbond/pkg/generated/clientset/versioned"
etcdutil "github.com/goodrain/rainbond/util/etcd"
k8sutil "github.com/goodrain/rainbond/util/k8s"
"github.com/goodrain/rainbond/worker/appm"
"github.com/goodrain/rainbond/worker/appm/componentdefinition"
"github.com/goodrain/rainbond/worker/appm/controller"
"github.com/goodrain/rainbond/worker/appm/store"
"github.com/goodrain/rainbond/worker/discover"
@ -42,6 +44,7 @@ import (
"github.com/sirupsen/logrus"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/util/flowcontrol"
"sigs.k8s.io/controller-runtime/pkg/client"
)
//Run start run
@ -85,10 +88,16 @@ func Run(s *option.Worker) error {
return err
}
s.Config.KubeClient = clientset
runtimeClient, err := client.New(restConfig, client.Options{Scheme: common.Scheme})
if err != nil {
logrus.Errorf("create kube runtime client error: %s", err.Error())
return err
}
rainbondClient := versioned.NewForConfigOrDie(restConfig)
//step 3: create componentdefinition builder factory
componentdefinition.NewComponentDefinitionBuilder(s.Config.RBDNamespace)
//step 3: create resource store
//step 4: create component resource store
startCh := channels.NewRingChannel(1024)
updateCh := channels.NewRingChannel(1024)
probeCh := channels.NewRingChannel(1024)
@ -103,12 +112,12 @@ func Run(s *option.Worker) error {
return err
}
//step 4: create controller manager
controllerManager := controller.NewManager(cachestore, clientset)
//step 5: create controller manager
controllerManager := controller.NewManager(cachestore, clientset, runtimeClient)
defer controllerManager.Stop()
//step 5 : start runtime master
masterCon, err := master.NewMasterController(s.Config, cachestore, clientset, rainbondClient)
//step 6 : start runtime master
masterCon, err := master.NewMasterController(s.Config, cachestore, clientset, rainbondClient, restConfig)
if err != nil {
return err
}
@ -117,18 +126,19 @@ func Run(s *option.Worker) error {
}
defer masterCon.Stop()
//step 6 : create discover module
//step 7 : create discover module
garbageCollector := gc.NewGarbageCollector(clientset)
taskManager := discover.NewTaskManager(s.Config, cachestore, controllerManager, garbageCollector, startCh)
if err := taskManager.Start(); err != nil {
return err
}
defer taskManager.Stop()
//step 7: start app runtimer server
//step 8: start app runtimer server
runtimeServer := server.CreaterRuntimeServer(s.Config, cachestore, clientset, updateCh)
runtimeServer.Start(errChan)
//step 8: create application use resource exporter.
//step 9: create application use resource exporter.
exporterManager := monitor.NewManager(s.Config, masterCon, controllerManager)
if err := exporterManager.Start(); err != nil {
return err
@ -138,7 +148,7 @@ func Run(s *option.Worker) error {
logrus.Info("worker begin running...")
//step finally: listen Signal
term := make(chan os.Signal)
term := make(chan os.Signal, 1)
signal.Notify(term, os.Interrupt, syscall.SIGTERM)
select {
case <-term:

View File

@ -0,0 +1,297 @@
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.3.0
creationTimestamp: null
name: componentdefinitions.rainbond.io
spec:
additionalPrinterColumns:
- JSONPath: .spec.workload.definition.kind
name: WORKLOAD-KIND
type: string
- JSONPath: .metadata.annotations.definition\.oam\.dev/description
name: DESCRIPTION
type: string
group: rainbond.io
names:
categories:
- oam
kind: ComponentDefinition
listKind: ComponentDefinitionList
plural: componentdefinitions
shortNames:
- comp
singular: componentdefinition
scope: Namespaced
subresources:
status: {}
validation:
openAPIV3Schema:
description: ComponentDefinition is the Schema for the componentdefinitions
API
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
description: ComponentDefinitionSpec defines the desired state of ComponentDefinition
properties:
childResourceKinds:
description: ChildResourceKinds are the list of GVK of the child resources
this workload generates
items:
description: A ChildResourceKind defines a child Kubernetes resource
kind with a selector
properties:
apiVersion:
description: APIVersion of the child resource
type: string
kind:
description: Kind of the child resource
type: string
selector:
additionalProperties:
type: string
description: Selector to select the child resources that the workload
wants to expose to traits
type: object
required:
- apiVersion
- kind
type: object
type: array
extension:
description: Extension is used for extension needs by OAM platform builders
type: object
x-kubernetes-preserve-unknown-fields: true
podSpecPath:
description: PodSpecPath indicates where/if this workload has K8s podSpec
field if one workload has podSpec, trait can do lot's of assumption
such as port, env, volume fields.
type: string
revisionLabel:
description: RevisionLabel indicates which label for underlying resources(e.g.
pods) of this workload can be used by trait to create resource selectors(e.g.
label selector for pods).
type: string
schematic:
description: Schematic defines the data format and template of the encapsulation
of the workload
properties:
cue:
description: CUE defines the encapsulation in CUE format
properties:
template:
description: Template defines the abstraction template data
of the capability, it will replace the old CUE template in
extension field. Template is a required field if CUE is defined
in Capability Definition.
type: string
required:
- template
type: object
helm:
description: A Helm represents resources used by a Helm module
properties:
release:
description: Release records a Helm release used by a Helm module
workload.
type: object
x-kubernetes-preserve-unknown-fields: true
repository:
description: HelmRelease records a Helm repository used by a
Helm module workload.
type: object
x-kubernetes-preserve-unknown-fields: true
required:
- release
- repository
type: object
kube:
description: Kube defines the encapsulation in raw Kubernetes resource
format
properties:
parameters:
description: Parameters defines configurable parameters
items:
description: A KubeParameter defines a configurable parameter
of a component.
properties:
description:
description: Description of this parameter.
type: string
fieldPaths:
description: "FieldPaths specifies an array of fields
within this workload that will be overwritten by the
value of this parameter. \tAll fields must be of the
same type. Fields are specified as JSON field paths
without a leading dot, for example 'spec.replicas'."
items:
type: string
type: array
name:
description: Name of this parameter
type: string
required:
default: false
description: Required specifies whether or not a value
for this parameter must be supplied when authoring an
Application.
type: boolean
type:
description: 'ValueType indicates the type of the parameter
value, and only supports basic data types: string, number,
boolean.'
enum:
- string
- number
- boolean
type: string
required:
- fieldPaths
- name
- type
type: object
type: array
template:
description: Template defines the raw Kubernetes resource
type: object
x-kubernetes-preserve-unknown-fields: true
required:
- template
type: object
terraform:
description: Terraform is the struct to describe cloud resources
managed by Hashicorp Terraform
properties:
configuration:
description: Configuration is Terraform Configuration
type: string
type:
default: hcl
description: Type specifies which Terraform configuration it
is, HCL or JSON syntax
enum:
- hcl
- json
type: string
required:
- configuration
type: object
type: object
status:
description: Status defines the custom health policy and status message
for workload
properties:
customStatus:
description: CustomStatus defines the custom status message that
could display to user
type: string
healthPolicy:
description: HealthPolicy defines the health check policy for the
abstraction
type: string
type: object
workload:
description: Workload is a workload type descriptor
properties:
definition:
description: Definition mutually exclusive to workload.type, a embedded
WorkloadDefinition
properties:
apiVersion:
type: string
kind:
type: string
required:
- apiVersion
- kind
type: object
type:
description: Type ref to a WorkloadDefinition via name
type: string
type: object
required:
- workload
type: object
status:
description: ComponentDefinitionStatus is the status of ComponentDefinition
properties:
conditions:
description: Conditions of the resource.
items:
description: A Condition that may apply to a resource.
properties:
lastTransitionTime:
description: LastTransitionTime is the last time this condition
transitioned from one status to another.
format: date-time
type: string
message:
description: A Message containing details about this condition's
last transition from one status to another, if any.
type: string
reason:
description: A Reason for this condition's last transition from
one status to another.
type: string
status:
description: Status of this condition; is it currently True, False,
or Unknown?
type: string
type:
description: Type of this condition. At most one of each condition
type may apply to a resource at any point in time.
type: string
required:
- lastTransitionTime
- reason
- status
- type
type: object
type: array
configMapRef:
description: ConfigMapRef refer to a ConfigMap which contains OpenAPI
V3 JSON schema of Component parameters.
type: string
latestRevision:
description: LatestRevision of the component definition
properties:
name:
type: string
revision:
format: int64
type: integer
revisionHash:
description: RevisionHash record the hash value of the spec of ApplicationRevision
object.
type: string
required:
- name
- revision
type: object
type: object
type: object
version: v1alpha1
versions:
- name: v1alpha1
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View File

@ -4,11 +4,11 @@ apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.2.5
controller-gen.kubebuilder.io/version: v0.3.0
creationTimestamp: null
name: helmapps.rainbond.goodrain.io
name: helmapps.rainbond.io
spec:
group: rainbond.goodrain.io
group: rainbond.io
names:
kind: HelmApp
listKind: HelmAppList

View File

@ -0,0 +1,204 @@
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.3.0
creationTimestamp: null
name: thirdcomponents.rainbond.io
spec:
group: rainbond.io
names:
kind: ThirdComponent
listKind: ThirdComponentList
plural: thirdcomponents
singular: thirdcomponent
scope: Namespaced
subresources:
status: {}
validation:
openAPIV3Schema:
description: HelmApp -
properties:
apiVersion:
description: 'APIVersion defines the versioned schema of this representation
of an object. Servers should convert recognized schemas to the latest
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
type: string
kind:
description: 'Kind is a string value representing the REST resource this
object represents. Servers may infer this from the endpoint the client
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
metadata:
type: object
spec:
properties:
endpointSource:
description: endpoint source config
properties:
endpoints:
items:
properties:
address:
description: The address including the port number.
type: string
clientSecret:
description: Specify a private certificate when the protocol
is HTTPS
type: string
protocol:
description: 'Address protocols, including: HTTP, TCP, UDP,
HTTPS'
type: string
required:
- address
type: object
type: array
kubernetesService:
properties:
name:
type: string
namespace:
description: If not specified, the namespace is the namespace
of the current resource
type: string
required:
- name
type: object
type: object
ports:
description: component regist ports
items:
description: ComponentPort component port define
properties:
name:
type: string
openInner:
type: boolean
openOuter:
type: boolean
port:
type: integer
required:
- name
- openInner
- openOuter
- port
type: object
type: array
probe:
description: health check probe
properties:
httpGet:
description: HTTPGet specifies the http request to perform.
properties:
httpHeaders:
description: Custom headers to set in the request. HTTP allows
repeated headers.
items:
description: HTTPHeader describes a custom header to be used
in HTTP probes
properties:
name:
description: The header field name
type: string
value:
description: The header field value
type: string
required:
- name
- value
type: object
type: array
path:
description: Path to access on the HTTP server.
type: string
type: object
tcpSocket:
description: 'TCPSocket specifies an action involving a TCP port.
TCP hooks not yet supported TODO: implement a realistic TCP lifecycle
hook'
type: object
type: object
required:
- endpointSource
- ports
type: object
status:
properties:
endpoints:
items:
description: ThirdComponentEndpointStatus endpoint status
properties:
address:
description: The address including the port number.
type: string
reason:
description: Reason probe not passed reason
type: string
status:
description: Status endpoint status
type: string
targetRef:
description: Reference to object providing the endpoint.
properties:
apiVersion:
description: API version of the referent.
type: string
fieldPath:
description: 'If referring to a piece of an object instead
of an entire object, this string should contain a valid
JSON/Go field access statement, such as desiredState.manifest.containers[2].
For example, if the object reference is to a container within
a pod, this would take on a value like: "spec.containers{name}"
(where "name" refers to the name of the container that triggered
the event) or if no container name is specified "spec.containers[2]"
(container with index 2 in this pod). This syntax is chosen
only to have some well-defined way of referencing a part
of an object. TODO: this design is not final and this field
is subject to change in the future.'
type: string
kind:
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
type: string
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
namespace:
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/'
type: string
resourceVersion:
description: 'Specific resourceVersion to which this reference
is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency'
type: string
uid:
description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids'
type: string
type: object
required:
- address
- status
type: object
type: array
phase:
type: string
reason:
type: string
required:
- endpoints
- phase
type: object
type: object
version: v1alpha1
versions:
- name: v1alpha1
served: true
storage: true
status:
acceptedNames:
kind: ""
plural: ""
conditions: []
storedVersions: []

View File

@ -25,7 +25,7 @@ type Application struct {
TenantID string `gorm:"column:tenant_id" json:"tenant_id"`
AppName string `gorm:"column:app_name" json:"app_name"`
AppID string `gorm:"column:app_id" json:"app_id"`
AppType string `gorm:"column:app_type;default:rainbond" json:"app_type"`
AppType string `gorm:"column:app_type;default:'rainbond'" json:"app_type"`
AppStoreName string `gorm:"column:app_store_name" json:"app_store_name"`
AppStoreURL string `gorm:"column:app_store_url" json:"app_store_url"`
AppTemplateName string `gorm:"column:app_template_name" json:"app_template_name"`

View File

@ -83,6 +83,9 @@ var ServiceKindThirdParty ServiceKind = "third_party"
// ServiceKindInternal means internal service
var ServiceKindInternal ServiceKind = "internal"
// ServiceKindCustom means custom component define
var ServiceKindCustom ServiceKind = "custom.componentdefinition."
func (s ServiceKind) String() string {
return string(s)
}
@ -191,7 +194,7 @@ type TenantServices struct {
UpdateTime time.Time `gorm:"column:update_time" json:"update_time"`
// 服务创建类型cloud云市服务,assistant云帮服务
ServiceOrigin string `gorm:"column:service_origin;default:'assistant'" json:"service_origin"`
// kind of service. option: internal, third_party
// kind of service. option: internal, third_party, custom
Kind string `gorm:"column:kind;default:'internal'" json:"kind"`
// service bind appID
AppID string `gorm:"column:app_id" json:"app_id"`

View File

@ -40,6 +40,9 @@ type DiscorveryType string
// DiscorveryTypeEtcd etcd
var DiscorveryTypeEtcd DiscorveryType = "etcd"
// DiscorveryTypeKubernetes kubernetes service
var DiscorveryTypeKubernetes DiscorveryType = "kubernetes"
func (d DiscorveryType) String() string {
return string(d)
}
@ -55,6 +58,9 @@ type ThirdPartySvcDiscoveryCfg struct {
Key string `gorm:"key"`
Username string `gorm:"username"`
Password string `gorm:"password"`
//for kubernetes service
Namespace string `gorm:"namespace"`
ServiceName string `gorm:"serviceName"`
}
// TableName returns table name of ThirdPartySvcDiscoveryCfg.

16
go.mod
View File

@ -3,8 +3,8 @@ module github.com/goodrain/rainbond
go 1.15
require (
cuelang.org/go v0.2.2
github.com/DATA-DOG/go-sqlmock v1.5.0
github.com/NYTimes/gziphandler v1.1.1 // indirect
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
github.com/alecthomas/units v0.0.0-20201120081800-1786d5ef83d4 // indirect
github.com/aliyun/aliyun-oss-go-sdk v2.1.5+incompatible
@ -17,6 +17,7 @@ require (
github.com/cockroachdb/cmux v0.0.0-20170110192607-30d10be49292 // indirect
github.com/coreos/etcd v3.3.17+incompatible
github.com/creack/pty v1.1.11 // indirect
github.com/crossplane/crossplane-runtime v0.10.0
github.com/docker/cli v20.10.3+incompatible
github.com/docker/distribution v2.7.1+incompatible
github.com/docker/docker v20.10.2+incompatible
@ -35,7 +36,7 @@ require (
github.com/go-kit/kit v0.10.0
github.com/go-ole/go-ole v1.2.4 // indirect
github.com/go-playground/assert/v2 v2.0.1
github.com/go-playground/validator/v10 v10.2.0
github.com/go-playground/validator/v10 v10.4.1
github.com/go-sql-driver/mysql v1.5.0
github.com/godbus/dbus v4.1.0+incompatible // indirect
github.com/gofrs/flock v0.8.0
@ -47,7 +48,6 @@ require (
github.com/goodrain/rainbond-operator v1.3.1-0.20210401055914-f8fe4bf89a21
github.com/google/go-cmp v0.5.4 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/gopherjs/gopherjs v0.0.0-20191106031601-ce3c9ade29de // indirect
github.com/gorilla/websocket v1.4.2
github.com/gosuri/uitable v0.0.4
github.com/grpc-ecosystem/grpc-gateway v1.16.0 // indirect
@ -57,14 +57,14 @@ require (
github.com/json-iterator/go v1.1.10
github.com/kr/pretty v0.2.1 // indirect
github.com/kr/pty v1.1.8
github.com/mattn/go-colorable v0.1.6 // indirect
github.com/mattn/go-runewidth v0.0.6
github.com/mitchellh/go-ps v1.0.0
github.com/mitchellh/go-wordwrap v1.0.0
github.com/mitchellh/mapstructure v1.3.3
github.com/ncabatoff/process-exporter v0.7.1
github.com/oam-dev/kubevela v1.1.0-alpha.4.0.20210625105426-e176fcfc56f0
github.com/onsi/ginkgo v1.14.1
github.com/onsi/gomega v1.10.2
github.com/onsi/gomega v1.10.3
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/runc v1.0.0-rc91.0.20200707015106-819fcc687efb // indirect
github.com/pborman/uuid v1.2.1
@ -79,20 +79,17 @@ require (
github.com/prometheus/common v0.15.0
github.com/prometheus/node_exporter v1.0.1
github.com/prometheus/procfs v0.2.0
github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b // indirect
github.com/shirou/gopsutil v3.21.3+incompatible
github.com/sirupsen/logrus v1.7.0
github.com/smartystreets/assertions v1.0.1 // indirect
github.com/smartystreets/goconvey v1.6.4
github.com/spf13/pflag v1.0.5
github.com/stretchr/testify v1.7.0
github.com/testcontainers/testcontainers-go v0.8.0
github.com/thejerf/suture v3.0.3+incompatible
github.com/tidwall/gjson v1.6.1
github.com/tidwall/gjson v1.6.8
github.com/twinj/uuid v1.0.0
github.com/urfave/cli v1.22.2
github.com/yudai/umutex v0.0.0-20150817080136-18216d265c6b
go.uber.org/atomic v1.7.0 // indirect
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
golang.org/x/net v0.0.0-20201224014010-6772e930b67b
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5 // indirect
@ -131,4 +128,5 @@ replace (
k8s.io/client-go => k8s.io/client-go v0.20.0
k8s.io/code-generator => k8s.io/code-generator v0.20.0
k8s.io/component-base => k8s.io/component-base v0.20.0
sigs.k8s.io/controller-runtime => sigs.k8s.io/controller-runtime v0.6.2
)

646
go.sum

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,109 @@
/*
Copyright 2021 The KubeVela Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
// Code from kubevela, Used to generate the SDK.
*/
package v1alpha1
import (
runtimev1alpha1 "github.com/crossplane/crossplane-runtime/apis/core/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
)
// ComponentDefinitionSpec defines the desired state of ComponentDefinition
type ComponentDefinitionSpec struct {
// Workload is a workload type descriptor
Workload common.WorkloadTypeDescriptor `json:"workload"`
// ChildResourceKinds are the list of GVK of the child resources this workload generates
ChildResourceKinds []common.ChildResourceKind `json:"childResourceKinds,omitempty"`
// RevisionLabel indicates which label for underlying resources(e.g. pods) of this workload
// can be used by trait to create resource selectors(e.g. label selector for pods).
// +optional
RevisionLabel string `json:"revisionLabel,omitempty"`
// PodSpecPath indicates where/if this workload has K8s podSpec field
// if one workload has podSpec, trait can do lot's of assumption such as port, env, volume fields.
// +optional
PodSpecPath string `json:"podSpecPath,omitempty"`
// Status defines the custom health policy and status message for workload
// +optional
Status *common.Status `json:"status,omitempty"`
// Schematic defines the data format and template of the encapsulation of the workload
// +optional
Schematic *common.Schematic `json:"schematic,omitempty"`
// Extension is used for extension needs by OAM platform builders
// +optional
// +kubebuilder:pruning:PreserveUnknownFields
Extension *runtime.RawExtension `json:"extension,omitempty"`
}
// ComponentDefinitionStatus is the status of ComponentDefinition
type ComponentDefinitionStatus struct {
// ConditionedStatus reflects the observed status of a resource
runtimev1alpha1.ConditionedStatus `json:",inline"`
// ConfigMapRef refer to a ConfigMap which contains OpenAPI V3 JSON schema of Component parameters.
ConfigMapRef string `json:"configMapRef,omitempty"`
// LatestRevision of the component definition
// +optional
LatestRevision *common.Revision `json:"latestRevision,omitempty"`
}
// +kubebuilder:object:root=true
// ComponentDefinition is the Schema for the componentdefinitions API
// +genclient
// +kubebuilder:resource:scope=Namespaced,categories={oam},shortName=comp
// +kubebuilder:subresource:status
// +kubebuilder:printcolumn:name="WORKLOAD-KIND",type=string,JSONPath=".spec.workload.definition.kind"
// +kubebuilder:printcolumn:name="DESCRIPTION",type=string,JSONPath=".metadata.annotations.definition\\.oam\\.dev/description"
type ComponentDefinition struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec ComponentDefinitionSpec `json:"spec,omitempty"`
Status ComponentDefinitionStatus `json:"status,omitempty"`
}
// SetConditions set condition for ComponentDefinition
func (cd *ComponentDefinition) SetConditions(c ...runtimev1alpha1.Condition) {
cd.Status.SetConditions(c...)
}
// GetCondition gets condition from ComponentDefinition
func (cd *ComponentDefinition) GetCondition(conditionType runtimev1alpha1.ConditionType) runtimev1alpha1.Condition {
return cd.Status.GetCondition(conditionType)
}
// +kubebuilder:object:root=true
// ComponentDefinitionList contains a list of ComponentDefinition
type ComponentDefinitionList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []ComponentDefinition `json:"items"`
}
func init() {
SchemeBuilder.Register(&ComponentDefinition{}, &ComponentDefinitionList{})
}

View File

@ -1,4 +1,4 @@
// Package v1alpha1 contains API Schema definitions for the rainbond v1alpha1 API group
// +k8s:deepcopy-gen=package,register
// +groupName=rainbond.goodrain.io
// +groupName=rainbond.io
package v1alpha1

View File

@ -2,7 +2,7 @@
// Package v1alpha1 contains API Schema definitions for the rainbond v1alpha1 API group
// +k8s:deepcopy-gen=package,register
// +groupName=rainbond.goodrain.io
// +groupName=rainbond.io
package v1alpha1
import (
@ -12,7 +12,7 @@ import (
var (
// SchemeGroupVersion is group version used to register these objects
SchemeGroupVersion = schema.GroupVersion{Group: "rainbond.goodrain.io", Version: "v1alpha1"}
SchemeGroupVersion = schema.GroupVersion{Group: "rainbond.io", Version: "v1alpha1"}
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: SchemeGroupVersion}

View File

@ -18,12 +18,26 @@
package v1alpha1
import (
"fmt"
"net"
"strconv"
"strings"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
func init() {
SchemeBuilder.Register(&ThirdComponent{}, &ThirdComponentList{})
}
// +genclient
// +kubebuilder:object:root=true
// HelmApp -
// +kubebuilder:subresource:status
// +kubebuilder:resource:path=thirdcomponent,scope=Namespaced
// +kubebuilder:resource:path=thirdcomponents,scope=Namespaced
type ThirdComponent struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
@ -32,19 +46,28 @@ type ThirdComponent struct {
Status ThirdComponentStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// ThirdComponentList contains a list of ThirdComponent
type ThirdComponentList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []ThirdComponent `json:"items"`
}
type ThirdComponentSpec struct {
// health check probe
// +optional
HealthProbe *HealthProbe `json:"health_probe,omitempty"`
Probe *HealthProbe `json:"probe,omitempty"`
// component regist ports
Ports []*ComponentPort `json:"ports"`
// endpoint source config
EndpointSource ThirdComponentEndpointSource `json:"endpoint_source"`
EndpointSource ThirdComponentEndpointSource `json:"endpointSource"`
}
type ThirdComponentEndpointSource struct {
StaticEndpoints []*ThirdComponentEndpoint `json:"endpoints,omitempty"`
KubernetesService KubernetesServiceSource `json:"kubernetes_service,omitempty"`
KubernetesService *KubernetesServiceSource `json:"kubernetesService,omitempty"`
//other source
// NacosSource
// EurekaSource
@ -60,7 +83,7 @@ type ThirdComponentEndpoint struct {
Protocol string `json:"protocol,omitempty"`
// Specify a private certificate when the protocol is HTTPS
// +optional
ClentSecret string `json:"client_secret,omitempty"`
ClentSecret string `json:"clientSecret,omitempty"`
}
type KubernetesServiceSource struct {
@ -81,7 +104,12 @@ type HealthProbe struct {
TCPSocket *TCPSocketAction `json:"tcpSocket,omitempty"`
}
//ComponentPort component port define
type ComponentPort struct {
Name string `json:"name"`
Port int `json:"port"`
OpenInner bool `json:"openInner"`
OpenOuter bool `json:"openOuter"`
}
//TCPSocketAction enable tcp check
@ -92,10 +120,10 @@ type TCPSocketAction struct {
type HTTPGetAction struct {
// Path to access on the HTTP server.
// +optional
Path string `json:"path,omitempty" protobuf:"bytes,1,opt,name=path"`
Path string `json:"path,omitempty"`
// Custom headers to set in the request. HTTP allows repeated headers.
// +optional
HTTPHeaders []HTTPHeader `json:"httpHeaders,omitempty" protobuf:"bytes,5,rep,name=httpHeaders"`
HTTPHeaders []HTTPHeader `json:"httpHeaders,omitempty"`
}
// HTTPHeader describes a custom header to be used in HTTP probes
@ -121,6 +149,7 @@ const (
type ThirdComponentStatus struct {
Phase ComponentPhase `json:"phase"`
Reason string `json:"reason,omitempty"`
Endpoints []*ThirdComponentEndpointStatus `json:"endpoints"`
}
@ -133,15 +162,45 @@ const (
EndpointNotReady EndpointStatus = "NotReady"
)
type EndpointAddress string
func (e EndpointAddress) GetIP() string {
info := strings.Split(string(e), ":")
if len(info) == 2 {
return info[0]
}
return ""
}
func (e EndpointAddress) GetPort() int {
info := strings.Split(string(e), ":")
if len(info) == 2 {
port, _ := strconv.Atoi(info[1])
return port
}
return 0
}
func NewEndpointAddress(host string, port int) *EndpointAddress {
if net.ParseIP(host) == nil {
return nil
}
if port < 0 || port > 65533 {
return nil
}
ea := EndpointAddress(fmt.Sprintf("%s:%d", host, port))
return &ea
}
//ThirdComponentEndpointStatus endpoint status
type ThirdComponentEndpointStatus struct {
// The address including the port number.
Address string `json:"address"`
//PodName means endpoint come from kubernetes pod
Address EndpointAddress `json:"address"`
// Reference to object providing the endpoint.
// +optional
PodName string `json:"pod_name"`
TargetRef *v1.ObjectReference `json:"targetRef,omitempty" protobuf:"bytes,2,opt,name=targetRef"`
//Status endpoint status
Status EndpointStatus `json:"status"`
//Reason probe not passed reason
Reason string `json:"reason"`
Reason string `json:"reason,omitempty"`
}

View File

@ -23,9 +23,204 @@
package v1alpha1
import (
runtime "k8s.io/apimachinery/pkg/runtime"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
)
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ComponentDefinition) DeepCopyInto(out *ComponentDefinition) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentDefinition.
func (in *ComponentDefinition) DeepCopy() *ComponentDefinition {
if in == nil {
return nil
}
out := new(ComponentDefinition)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ComponentDefinition) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ComponentDefinitionList) DeepCopyInto(out *ComponentDefinitionList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]ComponentDefinition, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentDefinitionList.
func (in *ComponentDefinitionList) DeepCopy() *ComponentDefinitionList {
if in == nil {
return nil
}
out := new(ComponentDefinitionList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ComponentDefinitionList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ComponentDefinitionSpec) DeepCopyInto(out *ComponentDefinitionSpec) {
*out = *in
out.Workload = in.Workload
if in.ChildResourceKinds != nil {
in, out := &in.ChildResourceKinds, &out.ChildResourceKinds
*out = make([]common.ChildResourceKind, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
if in.Status != nil {
in, out := &in.Status, &out.Status
*out = new(common.Status)
**out = **in
}
if in.Schematic != nil {
in, out := &in.Schematic, &out.Schematic
*out = new(common.Schematic)
(*in).DeepCopyInto(*out)
}
if in.Extension != nil {
in, out := &in.Extension, &out.Extension
*out = new(runtime.RawExtension)
(*in).DeepCopyInto(*out)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentDefinitionSpec.
func (in *ComponentDefinitionSpec) DeepCopy() *ComponentDefinitionSpec {
if in == nil {
return nil
}
out := new(ComponentDefinitionSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ComponentDefinitionStatus) DeepCopyInto(out *ComponentDefinitionStatus) {
*out = *in
in.ConditionedStatus.DeepCopyInto(&out.ConditionedStatus)
if in.LatestRevision != nil {
in, out := &in.LatestRevision, &out.LatestRevision
*out = new(common.Revision)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentDefinitionStatus.
func (in *ComponentDefinitionStatus) DeepCopy() *ComponentDefinitionStatus {
if in == nil {
return nil
}
out := new(ComponentDefinitionStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ComponentPort) DeepCopyInto(out *ComponentPort) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ComponentPort.
func (in *ComponentPort) DeepCopy() *ComponentPort {
if in == nil {
return nil
}
out := new(ComponentPort)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HTTPGetAction) DeepCopyInto(out *HTTPGetAction) {
*out = *in
if in.HTTPHeaders != nil {
in, out := &in.HTTPHeaders, &out.HTTPHeaders
*out = make([]HTTPHeader, len(*in))
copy(*out, *in)
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPGetAction.
func (in *HTTPGetAction) DeepCopy() *HTTPGetAction {
if in == nil {
return nil
}
out := new(HTTPGetAction)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HTTPHeader) DeepCopyInto(out *HTTPHeader) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HTTPHeader.
func (in *HTTPHeader) DeepCopy() *HTTPHeader {
if in == nil {
return nil
}
out := new(HTTPHeader)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HealthProbe) DeepCopyInto(out *HealthProbe) {
*out = *in
if in.HTTPGet != nil {
in, out := &in.HTTPGet, &out.HTTPGet
*out = new(HTTPGetAction)
(*in).DeepCopyInto(*out)
}
if in.TCPSocket != nil {
in, out := &in.TCPSocket, &out.TCPSocket
*out = new(TCPSocketAction)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HealthProbe.
func (in *HealthProbe) DeepCopy() *HealthProbe {
if in == nil {
return nil
}
out := new(HealthProbe)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *HelmApp) DeepCopyInto(out *HelmApp) {
*out = *in
@ -167,3 +362,216 @@ func (in *HelmAppStore) DeepCopy() *HelmAppStore {
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *KubernetesServiceSource) DeepCopyInto(out *KubernetesServiceSource) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KubernetesServiceSource.
func (in *KubernetesServiceSource) DeepCopy() *KubernetesServiceSource {
if in == nil {
return nil
}
out := new(KubernetesServiceSource)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *TCPSocketAction) DeepCopyInto(out *TCPSocketAction) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TCPSocketAction.
func (in *TCPSocketAction) DeepCopy() *TCPSocketAction {
if in == nil {
return nil
}
out := new(TCPSocketAction)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ThirdComponent) DeepCopyInto(out *ThirdComponent) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
in.Spec.DeepCopyInto(&out.Spec)
in.Status.DeepCopyInto(&out.Status)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ThirdComponent.
func (in *ThirdComponent) DeepCopy() *ThirdComponent {
if in == nil {
return nil
}
out := new(ThirdComponent)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ThirdComponent) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ThirdComponentEndpoint) DeepCopyInto(out *ThirdComponentEndpoint) {
*out = *in
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ThirdComponentEndpoint.
func (in *ThirdComponentEndpoint) DeepCopy() *ThirdComponentEndpoint {
if in == nil {
return nil
}
out := new(ThirdComponentEndpoint)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ThirdComponentEndpointSource) DeepCopyInto(out *ThirdComponentEndpointSource) {
*out = *in
if in.StaticEndpoints != nil {
in, out := &in.StaticEndpoints, &out.StaticEndpoints
*out = make([]*ThirdComponentEndpoint, len(*in))
for i := range *in {
if (*in)[i] != nil {
in, out := &(*in)[i], &(*out)[i]
*out = new(ThirdComponentEndpoint)
**out = **in
}
}
}
if in.KubernetesService != nil {
in, out := &in.KubernetesService, &out.KubernetesService
*out = new(KubernetesServiceSource)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ThirdComponentEndpointSource.
func (in *ThirdComponentEndpointSource) DeepCopy() *ThirdComponentEndpointSource {
if in == nil {
return nil
}
out := new(ThirdComponentEndpointSource)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ThirdComponentEndpointStatus) DeepCopyInto(out *ThirdComponentEndpointStatus) {
*out = *in
if in.TargetRef != nil {
in, out := &in.TargetRef, &out.TargetRef
*out = new(v1.ObjectReference)
**out = **in
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ThirdComponentEndpointStatus.
func (in *ThirdComponentEndpointStatus) DeepCopy() *ThirdComponentEndpointStatus {
if in == nil {
return nil
}
out := new(ThirdComponentEndpointStatus)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ThirdComponentList) DeepCopyInto(out *ThirdComponentList) {
*out = *in
out.TypeMeta = in.TypeMeta
in.ListMeta.DeepCopyInto(&out.ListMeta)
if in.Items != nil {
in, out := &in.Items, &out.Items
*out = make([]ThirdComponent, len(*in))
for i := range *in {
(*in)[i].DeepCopyInto(&(*out)[i])
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ThirdComponentList.
func (in *ThirdComponentList) DeepCopy() *ThirdComponentList {
if in == nil {
return nil
}
out := new(ThirdComponentList)
in.DeepCopyInto(out)
return out
}
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
func (in *ThirdComponentList) DeepCopyObject() runtime.Object {
if c := in.DeepCopy(); c != nil {
return c
}
return nil
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ThirdComponentSpec) DeepCopyInto(out *ThirdComponentSpec) {
*out = *in
if in.Probe != nil {
in, out := &in.Probe, &out.Probe
*out = new(HealthProbe)
(*in).DeepCopyInto(*out)
}
if in.Ports != nil {
in, out := &in.Ports, &out.Ports
*out = make([]*ComponentPort, len(*in))
for i := range *in {
if (*in)[i] != nil {
in, out := &(*in)[i], &(*out)[i]
*out = new(ComponentPort)
**out = **in
}
}
}
in.EndpointSource.DeepCopyInto(&out.EndpointSource)
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ThirdComponentSpec.
func (in *ThirdComponentSpec) DeepCopy() *ThirdComponentSpec {
if in == nil {
return nil
}
out := new(ThirdComponentSpec)
in.DeepCopyInto(out)
return out
}
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *ThirdComponentStatus) DeepCopyInto(out *ThirdComponentStatus) {
*out = *in
if in.Endpoints != nil {
in, out := &in.Endpoints, &out.Endpoints
*out = make([]*ThirdComponentEndpointStatus, len(*in))
for i := range *in {
if (*in)[i] != nil {
in, out := &(*in)[i], &(*out)[i]
*out = new(ThirdComponentEndpointStatus)
(*in).DeepCopyInto(*out)
}
}
}
}
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ThirdComponentStatus.
func (in *ThirdComponentStatus) DeepCopy() *ThirdComponentStatus {
if in == nil {
return nil
}
out := new(ThirdComponentStatus)
in.DeepCopyInto(out)
return out
}

42
pkg/common/scheme.go Normal file
View File

@ -0,0 +1,42 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2021-2021 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package common
import (
rainbondv1alpha1 "github.com/goodrain/rainbond/pkg/apis/rainbond/v1alpha1"
oamcore "github.com/oam-dev/kubevela/apis/core.oam.dev"
oamstandard "github.com/oam-dev/kubevela/apis/standard.oam.dev/v1alpha1"
crdv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
k8sruntime "k8s.io/apimachinery/pkg/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
)
var (
// Scheme defines the default KubeVela schema
Scheme = k8sruntime.NewScheme()
)
func init() {
_ = clientgoscheme.AddToScheme(Scheme)
_ = crdv1.AddToScheme(Scheme)
_ = oamcore.AddToScheme(Scheme)
_ = oamstandard.AddToScheme(Scheme)
_ = rainbondv1alpha1.AddToScheme(Scheme)
// +kubebuilder:scaffold:scheme
}

View File

@ -0,0 +1,197 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2021 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Code generated by client-gen. DO NOT EDIT.
package v1alpha1
import (
"context"
"time"
v1alpha1 "github.com/goodrain/rainbond/pkg/apis/rainbond/v1alpha1"
scheme "github.com/goodrain/rainbond/pkg/generated/clientset/versioned/scheme"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
rest "k8s.io/client-go/rest"
)
// ComponentDefinitionsGetter has a method to return a ComponentDefinitionInterface.
// A group's client should implement this interface.
type ComponentDefinitionsGetter interface {
ComponentDefinitions(namespace string) ComponentDefinitionInterface
}
// ComponentDefinitionInterface has methods to work with ComponentDefinition resources.
type ComponentDefinitionInterface interface {
Create(ctx context.Context, componentDefinition *v1alpha1.ComponentDefinition, opts v1.CreateOptions) (*v1alpha1.ComponentDefinition, error)
Update(ctx context.Context, componentDefinition *v1alpha1.ComponentDefinition, opts v1.UpdateOptions) (*v1alpha1.ComponentDefinition, error)
UpdateStatus(ctx context.Context, componentDefinition *v1alpha1.ComponentDefinition, opts v1.UpdateOptions) (*v1alpha1.ComponentDefinition, error)
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ComponentDefinition, error)
List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ComponentDefinitionList, error)
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ComponentDefinition, err error)
ComponentDefinitionExpansion
}
// componentDefinitions implements ComponentDefinitionInterface
type componentDefinitions struct {
client rest.Interface
ns string
}
// newComponentDefinitions returns a ComponentDefinitions
func newComponentDefinitions(c *RainbondV1alpha1Client, namespace string) *componentDefinitions {
return &componentDefinitions{
client: c.RESTClient(),
ns: namespace,
}
}
// Get takes name of the componentDefinition, and returns the corresponding componentDefinition object, and an error if there is any.
func (c *componentDefinitions) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ComponentDefinition, err error) {
result = &v1alpha1.ComponentDefinition{}
err = c.client.Get().
Namespace(c.ns).
Resource("componentdefinitions").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do(ctx).
Into(result)
return
}
// List takes label and field selectors, and returns the list of ComponentDefinitions that match those selectors.
func (c *componentDefinitions) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ComponentDefinitionList, err error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
result = &v1alpha1.ComponentDefinitionList{}
err = c.client.Get().
Namespace(c.ns).
Resource("componentdefinitions").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Do(ctx).
Into(result)
return
}
// Watch returns a watch.Interface that watches the requested componentDefinitions.
func (c *componentDefinitions) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
opts.Watch = true
return c.client.Get().
Namespace(c.ns).
Resource("componentdefinitions").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Watch(ctx)
}
// Create takes the representation of a componentDefinition and creates it. Returns the server's representation of the componentDefinition, and an error, if there is any.
func (c *componentDefinitions) Create(ctx context.Context, componentDefinition *v1alpha1.ComponentDefinition, opts v1.CreateOptions) (result *v1alpha1.ComponentDefinition, err error) {
result = &v1alpha1.ComponentDefinition{}
err = c.client.Post().
Namespace(c.ns).
Resource("componentdefinitions").
VersionedParams(&opts, scheme.ParameterCodec).
Body(componentDefinition).
Do(ctx).
Into(result)
return
}
// Update takes the representation of a componentDefinition and updates it. Returns the server's representation of the componentDefinition, and an error, if there is any.
func (c *componentDefinitions) Update(ctx context.Context, componentDefinition *v1alpha1.ComponentDefinition, opts v1.UpdateOptions) (result *v1alpha1.ComponentDefinition, err error) {
result = &v1alpha1.ComponentDefinition{}
err = c.client.Put().
Namespace(c.ns).
Resource("componentdefinitions").
Name(componentDefinition.Name).
VersionedParams(&opts, scheme.ParameterCodec).
Body(componentDefinition).
Do(ctx).
Into(result)
return
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *componentDefinitions) UpdateStatus(ctx context.Context, componentDefinition *v1alpha1.ComponentDefinition, opts v1.UpdateOptions) (result *v1alpha1.ComponentDefinition, err error) {
result = &v1alpha1.ComponentDefinition{}
err = c.client.Put().
Namespace(c.ns).
Resource("componentdefinitions").
Name(componentDefinition.Name).
SubResource("status").
VersionedParams(&opts, scheme.ParameterCodec).
Body(componentDefinition).
Do(ctx).
Into(result)
return
}
// Delete takes name of the componentDefinition and deletes it. Returns an error if one occurs.
func (c *componentDefinitions) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
return c.client.Delete().
Namespace(c.ns).
Resource("componentdefinitions").
Name(name).
Body(&opts).
Do(ctx).
Error()
}
// DeleteCollection deletes a collection of objects.
func (c *componentDefinitions) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
var timeout time.Duration
if listOpts.TimeoutSeconds != nil {
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
}
return c.client.Delete().
Namespace(c.ns).
Resource("componentdefinitions").
VersionedParams(&listOpts, scheme.ParameterCodec).
Timeout(timeout).
Body(&opts).
Do(ctx).
Error()
}
// Patch applies the patch and returns the patched componentDefinition.
func (c *componentDefinitions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ComponentDefinition, err error) {
result = &v1alpha1.ComponentDefinition{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("componentdefinitions").
Name(name).
SubResource(subresources...).
VersionedParams(&opts, scheme.ParameterCodec).
Body(data).
Do(ctx).
Into(result)
return
}

View File

@ -0,0 +1,144 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2021 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
"context"
v1alpha1 "github.com/goodrain/rainbond/pkg/apis/rainbond/v1alpha1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
)
// FakeComponentDefinitions implements ComponentDefinitionInterface
type FakeComponentDefinitions struct {
Fake *FakeRainbondV1alpha1
ns string
}
var componentdefinitionsResource = schema.GroupVersionResource{Group: "rainbond.io", Version: "v1alpha1", Resource: "componentdefinitions"}
var componentdefinitionsKind = schema.GroupVersionKind{Group: "rainbond.io", Version: "v1alpha1", Kind: "ComponentDefinition"}
// Get takes name of the componentDefinition, and returns the corresponding componentDefinition object, and an error if there is any.
func (c *FakeComponentDefinitions) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ComponentDefinition, err error) {
obj, err := c.Fake.
Invokes(testing.NewGetAction(componentdefinitionsResource, c.ns, name), &v1alpha1.ComponentDefinition{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.ComponentDefinition), err
}
// List takes label and field selectors, and returns the list of ComponentDefinitions that match those selectors.
func (c *FakeComponentDefinitions) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ComponentDefinitionList, err error) {
obj, err := c.Fake.
Invokes(testing.NewListAction(componentdefinitionsResource, componentdefinitionsKind, c.ns, opts), &v1alpha1.ComponentDefinitionList{})
if obj == nil {
return nil, err
}
label, _, _ := testing.ExtractFromListOptions(opts)
if label == nil {
label = labels.Everything()
}
list := &v1alpha1.ComponentDefinitionList{ListMeta: obj.(*v1alpha1.ComponentDefinitionList).ListMeta}
for _, item := range obj.(*v1alpha1.ComponentDefinitionList).Items {
if label.Matches(labels.Set(item.Labels)) {
list.Items = append(list.Items, item)
}
}
return list, err
}
// Watch returns a watch.Interface that watches the requested componentDefinitions.
func (c *FakeComponentDefinitions) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
return c.Fake.
InvokesWatch(testing.NewWatchAction(componentdefinitionsResource, c.ns, opts))
}
// Create takes the representation of a componentDefinition and creates it. Returns the server's representation of the componentDefinition, and an error, if there is any.
func (c *FakeComponentDefinitions) Create(ctx context.Context, componentDefinition *v1alpha1.ComponentDefinition, opts v1.CreateOptions) (result *v1alpha1.ComponentDefinition, err error) {
obj, err := c.Fake.
Invokes(testing.NewCreateAction(componentdefinitionsResource, c.ns, componentDefinition), &v1alpha1.ComponentDefinition{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.ComponentDefinition), err
}
// Update takes the representation of a componentDefinition and updates it. Returns the server's representation of the componentDefinition, and an error, if there is any.
func (c *FakeComponentDefinitions) Update(ctx context.Context, componentDefinition *v1alpha1.ComponentDefinition, opts v1.UpdateOptions) (result *v1alpha1.ComponentDefinition, err error) {
obj, err := c.Fake.
Invokes(testing.NewUpdateAction(componentdefinitionsResource, c.ns, componentDefinition), &v1alpha1.ComponentDefinition{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.ComponentDefinition), err
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *FakeComponentDefinitions) UpdateStatus(ctx context.Context, componentDefinition *v1alpha1.ComponentDefinition, opts v1.UpdateOptions) (*v1alpha1.ComponentDefinition, error) {
obj, err := c.Fake.
Invokes(testing.NewUpdateSubresourceAction(componentdefinitionsResource, "status", c.ns, componentDefinition), &v1alpha1.ComponentDefinition{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.ComponentDefinition), err
}
// Delete takes name of the componentDefinition and deletes it. Returns an error if one occurs.
func (c *FakeComponentDefinitions) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewDeleteAction(componentdefinitionsResource, c.ns, name), &v1alpha1.ComponentDefinition{})
return err
}
// DeleteCollection deletes a collection of objects.
func (c *FakeComponentDefinitions) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
action := testing.NewDeleteCollectionAction(componentdefinitionsResource, c.ns, listOpts)
_, err := c.Fake.Invokes(action, &v1alpha1.ComponentDefinitionList{})
return err
}
// Patch applies the patch and returns the patched componentDefinition.
func (c *FakeComponentDefinitions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ComponentDefinition, err error) {
obj, err := c.Fake.
Invokes(testing.NewPatchSubresourceAction(componentdefinitionsResource, c.ns, name, pt, data, subresources...), &v1alpha1.ComponentDefinition{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.ComponentDefinition), err
}

View File

@ -38,9 +38,9 @@ type FakeHelmApps struct {
ns string
}
var helmappsResource = schema.GroupVersionResource{Group: "rainbond.goodrain.io", Version: "v1alpha1", Resource: "helmapps"}
var helmappsResource = schema.GroupVersionResource{Group: "rainbond.io", Version: "v1alpha1", Resource: "helmapps"}
var helmappsKind = schema.GroupVersionKind{Group: "rainbond.goodrain.io", Version: "v1alpha1", Kind: "HelmApp"}
var helmappsKind = schema.GroupVersionKind{Group: "rainbond.io", Version: "v1alpha1", Kind: "HelmApp"}
// Get takes name of the helmApp, and returns the corresponding helmApp object, and an error if there is any.
func (c *FakeHelmApps) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.HelmApp, err error) {

View File

@ -30,10 +30,18 @@ type FakeRainbondV1alpha1 struct {
*testing.Fake
}
func (c *FakeRainbondV1alpha1) ComponentDefinitions(namespace string) v1alpha1.ComponentDefinitionInterface {
return &FakeComponentDefinitions{c, namespace}
}
func (c *FakeRainbondV1alpha1) HelmApps(namespace string) v1alpha1.HelmAppInterface {
return &FakeHelmApps{c, namespace}
}
func (c *FakeRainbondV1alpha1) ThirdComponents(namespace string) v1alpha1.ThirdComponentInterface {
return &FakeThirdComponents{c, namespace}
}
// RESTClient returns a RESTClient that is used to communicate
// with API server by this client implementation.
func (c *FakeRainbondV1alpha1) RESTClient() rest.Interface {

View File

@ -0,0 +1,144 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2021 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Code generated by client-gen. DO NOT EDIT.
package fake
import (
"context"
v1alpha1 "github.com/goodrain/rainbond/pkg/apis/rainbond/v1alpha1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
labels "k8s.io/apimachinery/pkg/labels"
schema "k8s.io/apimachinery/pkg/runtime/schema"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
testing "k8s.io/client-go/testing"
)
// FakeThirdComponents implements ThirdComponentInterface
type FakeThirdComponents struct {
Fake *FakeRainbondV1alpha1
ns string
}
var thirdcomponentsResource = schema.GroupVersionResource{Group: "rainbond.io", Version: "v1alpha1", Resource: "thirdcomponents"}
var thirdcomponentsKind = schema.GroupVersionKind{Group: "rainbond.io", Version: "v1alpha1", Kind: "ThirdComponent"}
// Get takes name of the thirdComponent, and returns the corresponding thirdComponent object, and an error if there is any.
func (c *FakeThirdComponents) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ThirdComponent, err error) {
obj, err := c.Fake.
Invokes(testing.NewGetAction(thirdcomponentsResource, c.ns, name), &v1alpha1.ThirdComponent{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.ThirdComponent), err
}
// List takes label and field selectors, and returns the list of ThirdComponents that match those selectors.
func (c *FakeThirdComponents) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ThirdComponentList, err error) {
obj, err := c.Fake.
Invokes(testing.NewListAction(thirdcomponentsResource, thirdcomponentsKind, c.ns, opts), &v1alpha1.ThirdComponentList{})
if obj == nil {
return nil, err
}
label, _, _ := testing.ExtractFromListOptions(opts)
if label == nil {
label = labels.Everything()
}
list := &v1alpha1.ThirdComponentList{ListMeta: obj.(*v1alpha1.ThirdComponentList).ListMeta}
for _, item := range obj.(*v1alpha1.ThirdComponentList).Items {
if label.Matches(labels.Set(item.Labels)) {
list.Items = append(list.Items, item)
}
}
return list, err
}
// Watch returns a watch.Interface that watches the requested thirdComponents.
func (c *FakeThirdComponents) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
return c.Fake.
InvokesWatch(testing.NewWatchAction(thirdcomponentsResource, c.ns, opts))
}
// Create takes the representation of a thirdComponent and creates it. Returns the server's representation of the thirdComponent, and an error, if there is any.
func (c *FakeThirdComponents) Create(ctx context.Context, thirdComponent *v1alpha1.ThirdComponent, opts v1.CreateOptions) (result *v1alpha1.ThirdComponent, err error) {
obj, err := c.Fake.
Invokes(testing.NewCreateAction(thirdcomponentsResource, c.ns, thirdComponent), &v1alpha1.ThirdComponent{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.ThirdComponent), err
}
// Update takes the representation of a thirdComponent and updates it. Returns the server's representation of the thirdComponent, and an error, if there is any.
func (c *FakeThirdComponents) Update(ctx context.Context, thirdComponent *v1alpha1.ThirdComponent, opts v1.UpdateOptions) (result *v1alpha1.ThirdComponent, err error) {
obj, err := c.Fake.
Invokes(testing.NewUpdateAction(thirdcomponentsResource, c.ns, thirdComponent), &v1alpha1.ThirdComponent{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.ThirdComponent), err
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *FakeThirdComponents) UpdateStatus(ctx context.Context, thirdComponent *v1alpha1.ThirdComponent, opts v1.UpdateOptions) (*v1alpha1.ThirdComponent, error) {
obj, err := c.Fake.
Invokes(testing.NewUpdateSubresourceAction(thirdcomponentsResource, "status", c.ns, thirdComponent), &v1alpha1.ThirdComponent{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.ThirdComponent), err
}
// Delete takes name of the thirdComponent and deletes it. Returns an error if one occurs.
func (c *FakeThirdComponents) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
_, err := c.Fake.
Invokes(testing.NewDeleteAction(thirdcomponentsResource, c.ns, name), &v1alpha1.ThirdComponent{})
return err
}
// DeleteCollection deletes a collection of objects.
func (c *FakeThirdComponents) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
action := testing.NewDeleteCollectionAction(thirdcomponentsResource, c.ns, listOpts)
_, err := c.Fake.Invokes(action, &v1alpha1.ThirdComponentList{})
return err
}
// Patch applies the patch and returns the patched thirdComponent.
func (c *FakeThirdComponents) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ThirdComponent, err error) {
obj, err := c.Fake.
Invokes(testing.NewPatchSubresourceAction(thirdcomponentsResource, c.ns, name, pt, data, subresources...), &v1alpha1.ThirdComponent{})
if obj == nil {
return nil, err
}
return obj.(*v1alpha1.ThirdComponent), err
}

View File

@ -20,4 +20,8 @@
package v1alpha1
type ComponentDefinitionExpansion interface{}
type HelmAppExpansion interface{}
type ThirdComponentExpansion interface{}

View File

@ -28,18 +28,28 @@ import (
type RainbondV1alpha1Interface interface {
RESTClient() rest.Interface
ComponentDefinitionsGetter
HelmAppsGetter
ThirdComponentsGetter
}
// RainbondV1alpha1Client is used to interact with features provided by the rainbond.goodrain.io group.
// RainbondV1alpha1Client is used to interact with features provided by the rainbond.io group.
type RainbondV1alpha1Client struct {
restClient rest.Interface
}
func (c *RainbondV1alpha1Client) ComponentDefinitions(namespace string) ComponentDefinitionInterface {
return newComponentDefinitions(c, namespace)
}
func (c *RainbondV1alpha1Client) HelmApps(namespace string) HelmAppInterface {
return newHelmApps(c, namespace)
}
func (c *RainbondV1alpha1Client) ThirdComponents(namespace string) ThirdComponentInterface {
return newThirdComponents(c, namespace)
}
// NewForConfig creates a new RainbondV1alpha1Client for the given config.
func NewForConfig(c *rest.Config) (*RainbondV1alpha1Client, error) {
config := *c

View File

@ -0,0 +1,197 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2021 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Code generated by client-gen. DO NOT EDIT.
package v1alpha1
import (
"context"
"time"
v1alpha1 "github.com/goodrain/rainbond/pkg/apis/rainbond/v1alpha1"
scheme "github.com/goodrain/rainbond/pkg/generated/clientset/versioned/scheme"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
types "k8s.io/apimachinery/pkg/types"
watch "k8s.io/apimachinery/pkg/watch"
rest "k8s.io/client-go/rest"
)
// ThirdComponentsGetter has a method to return a ThirdComponentInterface.
// A group's client should implement this interface.
type ThirdComponentsGetter interface {
ThirdComponents(namespace string) ThirdComponentInterface
}
// ThirdComponentInterface has methods to work with ThirdComponent resources.
type ThirdComponentInterface interface {
Create(ctx context.Context, thirdComponent *v1alpha1.ThirdComponent, opts v1.CreateOptions) (*v1alpha1.ThirdComponent, error)
Update(ctx context.Context, thirdComponent *v1alpha1.ThirdComponent, opts v1.UpdateOptions) (*v1alpha1.ThirdComponent, error)
UpdateStatus(ctx context.Context, thirdComponent *v1alpha1.ThirdComponent, opts v1.UpdateOptions) (*v1alpha1.ThirdComponent, error)
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1alpha1.ThirdComponent, error)
List(ctx context.Context, opts v1.ListOptions) (*v1alpha1.ThirdComponentList, error)
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ThirdComponent, err error)
ThirdComponentExpansion
}
// thirdComponents implements ThirdComponentInterface
type thirdComponents struct {
client rest.Interface
ns string
}
// newThirdComponents returns a ThirdComponents
func newThirdComponents(c *RainbondV1alpha1Client, namespace string) *thirdComponents {
return &thirdComponents{
client: c.RESTClient(),
ns: namespace,
}
}
// Get takes name of the thirdComponent, and returns the corresponding thirdComponent object, and an error if there is any.
func (c *thirdComponents) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1alpha1.ThirdComponent, err error) {
result = &v1alpha1.ThirdComponent{}
err = c.client.Get().
Namespace(c.ns).
Resource("thirdcomponents").
Name(name).
VersionedParams(&options, scheme.ParameterCodec).
Do(ctx).
Into(result)
return
}
// List takes label and field selectors, and returns the list of ThirdComponents that match those selectors.
func (c *thirdComponents) List(ctx context.Context, opts v1.ListOptions) (result *v1alpha1.ThirdComponentList, err error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
result = &v1alpha1.ThirdComponentList{}
err = c.client.Get().
Namespace(c.ns).
Resource("thirdcomponents").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Do(ctx).
Into(result)
return
}
// Watch returns a watch.Interface that watches the requested thirdComponents.
func (c *thirdComponents) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
var timeout time.Duration
if opts.TimeoutSeconds != nil {
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
}
opts.Watch = true
return c.client.Get().
Namespace(c.ns).
Resource("thirdcomponents").
VersionedParams(&opts, scheme.ParameterCodec).
Timeout(timeout).
Watch(ctx)
}
// Create takes the representation of a thirdComponent and creates it. Returns the server's representation of the thirdComponent, and an error, if there is any.
func (c *thirdComponents) Create(ctx context.Context, thirdComponent *v1alpha1.ThirdComponent, opts v1.CreateOptions) (result *v1alpha1.ThirdComponent, err error) {
result = &v1alpha1.ThirdComponent{}
err = c.client.Post().
Namespace(c.ns).
Resource("thirdcomponents").
VersionedParams(&opts, scheme.ParameterCodec).
Body(thirdComponent).
Do(ctx).
Into(result)
return
}
// Update takes the representation of a thirdComponent and updates it. Returns the server's representation of the thirdComponent, and an error, if there is any.
func (c *thirdComponents) Update(ctx context.Context, thirdComponent *v1alpha1.ThirdComponent, opts v1.UpdateOptions) (result *v1alpha1.ThirdComponent, err error) {
result = &v1alpha1.ThirdComponent{}
err = c.client.Put().
Namespace(c.ns).
Resource("thirdcomponents").
Name(thirdComponent.Name).
VersionedParams(&opts, scheme.ParameterCodec).
Body(thirdComponent).
Do(ctx).
Into(result)
return
}
// UpdateStatus was generated because the type contains a Status member.
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
func (c *thirdComponents) UpdateStatus(ctx context.Context, thirdComponent *v1alpha1.ThirdComponent, opts v1.UpdateOptions) (result *v1alpha1.ThirdComponent, err error) {
result = &v1alpha1.ThirdComponent{}
err = c.client.Put().
Namespace(c.ns).
Resource("thirdcomponents").
Name(thirdComponent.Name).
SubResource("status").
VersionedParams(&opts, scheme.ParameterCodec).
Body(thirdComponent).
Do(ctx).
Into(result)
return
}
// Delete takes name of the thirdComponent and deletes it. Returns an error if one occurs.
func (c *thirdComponents) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
return c.client.Delete().
Namespace(c.ns).
Resource("thirdcomponents").
Name(name).
Body(&opts).
Do(ctx).
Error()
}
// DeleteCollection deletes a collection of objects.
func (c *thirdComponents) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
var timeout time.Duration
if listOpts.TimeoutSeconds != nil {
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
}
return c.client.Delete().
Namespace(c.ns).
Resource("thirdcomponents").
VersionedParams(&listOpts, scheme.ParameterCodec).
Timeout(timeout).
Body(&opts).
Do(ctx).
Error()
}
// Patch applies the patch and returns the patched thirdComponent.
func (c *thirdComponents) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1alpha1.ThirdComponent, err error) {
result = &v1alpha1.ThirdComponent{}
err = c.client.Patch(pt).
Namespace(c.ns).
Resource("thirdcomponents").
Name(name).
SubResource(subresources...).
VersionedParams(&opts, scheme.ParameterCodec).
Body(data).
Do(ctx).
Into(result)
return
}

View File

@ -54,9 +54,13 @@ func (f *genericInformer) Lister() cache.GenericLister {
// TODO extend this to unknown resources with a client pool
func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) {
switch resource {
// Group=rainbond.goodrain.io, Version=v1alpha1
// Group=rainbond.io, Version=v1alpha1
case v1alpha1.SchemeGroupVersion.WithResource("componentdefinitions"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Rainbond().V1alpha1().ComponentDefinitions().Informer()}, nil
case v1alpha1.SchemeGroupVersion.WithResource("helmapps"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Rainbond().V1alpha1().HelmApps().Informer()}, nil
case v1alpha1.SchemeGroupVersion.WithResource("thirdcomponents"):
return &genericInformer{resource: resource.GroupResource(), informer: f.Rainbond().V1alpha1().ThirdComponents().Informer()}, nil
}

View File

@ -0,0 +1,92 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2021 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Code generated by informer-gen. DO NOT EDIT.
package v1alpha1
import (
"context"
time "time"
rainbondv1alpha1 "github.com/goodrain/rainbond/pkg/apis/rainbond/v1alpha1"
versioned "github.com/goodrain/rainbond/pkg/generated/clientset/versioned"
internalinterfaces "github.com/goodrain/rainbond/pkg/generated/informers/externalversions/internalinterfaces"
v1alpha1 "github.com/goodrain/rainbond/pkg/generated/listers/rainbond/v1alpha1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
watch "k8s.io/apimachinery/pkg/watch"
cache "k8s.io/client-go/tools/cache"
)
// ComponentDefinitionInformer provides access to a shared informer and lister for
// ComponentDefinitions.
type ComponentDefinitionInformer interface {
Informer() cache.SharedIndexInformer
Lister() v1alpha1.ComponentDefinitionLister
}
type componentDefinitionInformer struct {
factory internalinterfaces.SharedInformerFactory
tweakListOptions internalinterfaces.TweakListOptionsFunc
namespace string
}
// NewComponentDefinitionInformer constructs a new informer for ComponentDefinition type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewComponentDefinitionInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
return NewFilteredComponentDefinitionInformer(client, namespace, resyncPeriod, indexers, nil)
}
// NewFilteredComponentDefinitionInformer constructs a new informer for ComponentDefinition type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewFilteredComponentDefinitionInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.RainbondV1alpha1().ComponentDefinitions(namespace).List(context.TODO(), options)
},
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.RainbondV1alpha1().ComponentDefinitions(namespace).Watch(context.TODO(), options)
},
},
&rainbondv1alpha1.ComponentDefinition{},
resyncPeriod,
indexers,
)
}
func (f *componentDefinitionInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
return NewFilteredComponentDefinitionInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
}
func (f *componentDefinitionInformer) Informer() cache.SharedIndexInformer {
return f.factory.InformerFor(&rainbondv1alpha1.ComponentDefinition{}, f.defaultInformer)
}
func (f *componentDefinitionInformer) Lister() v1alpha1.ComponentDefinitionLister {
return v1alpha1.NewComponentDefinitionLister(f.Informer().GetIndexer())
}

View File

@ -26,8 +26,12 @@ import (
// Interface provides access to all the informers in this group version.
type Interface interface {
// ComponentDefinitions returns a ComponentDefinitionInformer.
ComponentDefinitions() ComponentDefinitionInformer
// HelmApps returns a HelmAppInformer.
HelmApps() HelmAppInformer
// ThirdComponents returns a ThirdComponentInformer.
ThirdComponents() ThirdComponentInformer
}
type version struct {
@ -41,7 +45,17 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
}
// ComponentDefinitions returns a ComponentDefinitionInformer.
func (v *version) ComponentDefinitions() ComponentDefinitionInformer {
return &componentDefinitionInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
}
// HelmApps returns a HelmAppInformer.
func (v *version) HelmApps() HelmAppInformer {
return &helmAppInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
}
// ThirdComponents returns a ThirdComponentInformer.
func (v *version) ThirdComponents() ThirdComponentInformer {
return &thirdComponentInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
}

View File

@ -0,0 +1,92 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2021 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Code generated by informer-gen. DO NOT EDIT.
package v1alpha1
import (
"context"
time "time"
rainbondv1alpha1 "github.com/goodrain/rainbond/pkg/apis/rainbond/v1alpha1"
versioned "github.com/goodrain/rainbond/pkg/generated/clientset/versioned"
internalinterfaces "github.com/goodrain/rainbond/pkg/generated/informers/externalversions/internalinterfaces"
v1alpha1 "github.com/goodrain/rainbond/pkg/generated/listers/rainbond/v1alpha1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
runtime "k8s.io/apimachinery/pkg/runtime"
watch "k8s.io/apimachinery/pkg/watch"
cache "k8s.io/client-go/tools/cache"
)
// ThirdComponentInformer provides access to a shared informer and lister for
// ThirdComponents.
type ThirdComponentInformer interface {
Informer() cache.SharedIndexInformer
Lister() v1alpha1.ThirdComponentLister
}
type thirdComponentInformer struct {
factory internalinterfaces.SharedInformerFactory
tweakListOptions internalinterfaces.TweakListOptionsFunc
namespace string
}
// NewThirdComponentInformer constructs a new informer for ThirdComponent type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewThirdComponentInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
return NewFilteredThirdComponentInformer(client, namespace, resyncPeriod, indexers, nil)
}
// NewFilteredThirdComponentInformer constructs a new informer for ThirdComponent type.
// Always prefer using an informer factory to get a shared informer instead of getting an independent
// one. This reduces memory footprint and number of connections to the server.
func NewFilteredThirdComponentInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
return cache.NewSharedIndexInformer(
&cache.ListWatch{
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.RainbondV1alpha1().ThirdComponents(namespace).List(context.TODO(), options)
},
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
if tweakListOptions != nil {
tweakListOptions(&options)
}
return client.RainbondV1alpha1().ThirdComponents(namespace).Watch(context.TODO(), options)
},
},
&rainbondv1alpha1.ThirdComponent{},
resyncPeriod,
indexers,
)
}
func (f *thirdComponentInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
return NewFilteredThirdComponentInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
}
func (f *thirdComponentInformer) Informer() cache.SharedIndexInformer {
return f.factory.InformerFor(&rainbondv1alpha1.ThirdComponent{}, f.defaultInformer)
}
func (f *thirdComponentInformer) Lister() v1alpha1.ThirdComponentLister {
return v1alpha1.NewThirdComponentLister(f.Informer().GetIndexer())
}

View File

@ -0,0 +1,101 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2021 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Code generated by lister-gen. DO NOT EDIT.
package v1alpha1
import (
v1alpha1 "github.com/goodrain/rainbond/pkg/apis/rainbond/v1alpha1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
// ComponentDefinitionLister helps list ComponentDefinitions.
// All objects returned here must be treated as read-only.
type ComponentDefinitionLister interface {
// List lists all ComponentDefinitions in the indexer.
// Objects returned here must be treated as read-only.
List(selector labels.Selector) (ret []*v1alpha1.ComponentDefinition, err error)
// ComponentDefinitions returns an object that can list and get ComponentDefinitions.
ComponentDefinitions(namespace string) ComponentDefinitionNamespaceLister
ComponentDefinitionListerExpansion
}
// componentDefinitionLister implements the ComponentDefinitionLister interface.
type componentDefinitionLister struct {
indexer cache.Indexer
}
// NewComponentDefinitionLister returns a new ComponentDefinitionLister.
func NewComponentDefinitionLister(indexer cache.Indexer) ComponentDefinitionLister {
return &componentDefinitionLister{indexer: indexer}
}
// List lists all ComponentDefinitions in the indexer.
func (s *componentDefinitionLister) List(selector labels.Selector) (ret []*v1alpha1.ComponentDefinition, err error) {
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1alpha1.ComponentDefinition))
})
return ret, err
}
// ComponentDefinitions returns an object that can list and get ComponentDefinitions.
func (s *componentDefinitionLister) ComponentDefinitions(namespace string) ComponentDefinitionNamespaceLister {
return componentDefinitionNamespaceLister{indexer: s.indexer, namespace: namespace}
}
// ComponentDefinitionNamespaceLister helps list and get ComponentDefinitions.
// All objects returned here must be treated as read-only.
type ComponentDefinitionNamespaceLister interface {
// List lists all ComponentDefinitions in the indexer for a given namespace.
// Objects returned here must be treated as read-only.
List(selector labels.Selector) (ret []*v1alpha1.ComponentDefinition, err error)
// Get retrieves the ComponentDefinition from the indexer for a given namespace and name.
// Objects returned here must be treated as read-only.
Get(name string) (*v1alpha1.ComponentDefinition, error)
ComponentDefinitionNamespaceListerExpansion
}
// componentDefinitionNamespaceLister implements the ComponentDefinitionNamespaceLister
// interface.
type componentDefinitionNamespaceLister struct {
indexer cache.Indexer
namespace string
}
// List lists all ComponentDefinitions in the indexer for a given namespace.
func (s componentDefinitionNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.ComponentDefinition, err error) {
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*v1alpha1.ComponentDefinition))
})
return ret, err
}
// Get retrieves the ComponentDefinition from the indexer for a given namespace and name.
func (s componentDefinitionNamespaceLister) Get(name string) (*v1alpha1.ComponentDefinition, error) {
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(v1alpha1.Resource("componentdefinition"), name)
}
return obj.(*v1alpha1.ComponentDefinition), nil
}

View File

@ -20,6 +20,14 @@
package v1alpha1
// ComponentDefinitionListerExpansion allows custom methods to be added to
// ComponentDefinitionLister.
type ComponentDefinitionListerExpansion interface{}
// ComponentDefinitionNamespaceListerExpansion allows custom methods to be added to
// ComponentDefinitionNamespaceLister.
type ComponentDefinitionNamespaceListerExpansion interface{}
// HelmAppListerExpansion allows custom methods to be added to
// HelmAppLister.
type HelmAppListerExpansion interface{}
@ -27,3 +35,11 @@ type HelmAppListerExpansion interface{}
// HelmAppNamespaceListerExpansion allows custom methods to be added to
// HelmAppNamespaceLister.
type HelmAppNamespaceListerExpansion interface{}
// ThirdComponentListerExpansion allows custom methods to be added to
// ThirdComponentLister.
type ThirdComponentListerExpansion interface{}
// ThirdComponentNamespaceListerExpansion allows custom methods to be added to
// ThirdComponentNamespaceLister.
type ThirdComponentNamespaceListerExpansion interface{}

View File

@ -0,0 +1,101 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2021 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
// Code generated by lister-gen. DO NOT EDIT.
package v1alpha1
import (
v1alpha1 "github.com/goodrain/rainbond/pkg/apis/rainbond/v1alpha1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/tools/cache"
)
// ThirdComponentLister helps list ThirdComponents.
// All objects returned here must be treated as read-only.
type ThirdComponentLister interface {
// List lists all ThirdComponents in the indexer.
// Objects returned here must be treated as read-only.
List(selector labels.Selector) (ret []*v1alpha1.ThirdComponent, err error)
// ThirdComponents returns an object that can list and get ThirdComponents.
ThirdComponents(namespace string) ThirdComponentNamespaceLister
ThirdComponentListerExpansion
}
// thirdComponentLister implements the ThirdComponentLister interface.
type thirdComponentLister struct {
indexer cache.Indexer
}
// NewThirdComponentLister returns a new ThirdComponentLister.
func NewThirdComponentLister(indexer cache.Indexer) ThirdComponentLister {
return &thirdComponentLister{indexer: indexer}
}
// List lists all ThirdComponents in the indexer.
func (s *thirdComponentLister) List(selector labels.Selector) (ret []*v1alpha1.ThirdComponent, err error) {
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
ret = append(ret, m.(*v1alpha1.ThirdComponent))
})
return ret, err
}
// ThirdComponents returns an object that can list and get ThirdComponents.
func (s *thirdComponentLister) ThirdComponents(namespace string) ThirdComponentNamespaceLister {
return thirdComponentNamespaceLister{indexer: s.indexer, namespace: namespace}
}
// ThirdComponentNamespaceLister helps list and get ThirdComponents.
// All objects returned here must be treated as read-only.
type ThirdComponentNamespaceLister interface {
// List lists all ThirdComponents in the indexer for a given namespace.
// Objects returned here must be treated as read-only.
List(selector labels.Selector) (ret []*v1alpha1.ThirdComponent, err error)
// Get retrieves the ThirdComponent from the indexer for a given namespace and name.
// Objects returned here must be treated as read-only.
Get(name string) (*v1alpha1.ThirdComponent, error)
ThirdComponentNamespaceListerExpansion
}
// thirdComponentNamespaceLister implements the ThirdComponentNamespaceLister
// interface.
type thirdComponentNamespaceLister struct {
indexer cache.Indexer
namespace string
}
// List lists all ThirdComponents in the indexer for a given namespace.
func (s thirdComponentNamespaceLister) List(selector labels.Selector) (ret []*v1alpha1.ThirdComponent, err error) {
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
ret = append(ret, m.(*v1alpha1.ThirdComponent))
})
return ret, err
}
// Get retrieves the ThirdComponent from the indexer for a given namespace and name.
func (s thirdComponentNamespaceLister) Get(name string) (*v1alpha1.ThirdComponent, error) {
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
if err != nil {
return nil, err
}
if !exists {
return nil, errors.NewNotFound(v1alpha1.Resource("thirdcomponent"), name)
}
return obj.(*v1alpha1.ThirdComponent), nil
}

View File

@ -20,7 +20,6 @@ package appm
import (
"github.com/eapache/channels"
opt "github.com/goodrain/rainbond/cmd/worker/option"
"github.com/goodrain/rainbond/worker/appm/prober"
"github.com/goodrain/rainbond/worker/appm/store"
"github.com/goodrain/rainbond/worker/appm/thirdparty"
@ -49,8 +48,6 @@ func NewAPPMController(clientset kubernetes.Interface,
// Controller describes a new appm controller.
type Controller struct {
cfg opt.Config
store store.Storer
thirdparty thirdparty.ThirdPartier
prober prober.Prober

View File

@ -1,5 +1,5 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2014-2017 Goodrain Co., Ltd.
// Copyright (C) 2021-2021 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -16,15 +16,22 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package main
package componentdefinition
import "testing"
func TestHaveChange(t *testing.T) {
old := make(map[string]string)
t.Log(haveChange(map[string]string{"console": "127.0.0.1"}, old))
t.Log(haveChange(map[string]string{"console": "127.0.0.1"}, map[string]string{"console": "127.0.0.1"}))
t.Log(haveChange(map[string]string{"console": "127.0.0.2"}, map[string]string{"console": "127.0.0.1"}))
t.Log(haveChange(map[string]string{"console": "127.0.0.2", "console1": "127.0.0.1"}, map[string]string{"console": "127.0.0.1"}))
t.Log(haveChange(map[string]string{"console": "127.0.0.2"}, map[string]string{"console2": "127.0.0.1", "console1": "127.0.0.1"}))
//ThirdComponentProperties third component properties
type ThirdComponentProperties struct {
Kubernetes ThirdComponentKubernetes `json:"kubernetes"`
Port []*ThirdComponentPort `json:"port"`
}
type ThirdComponentPort struct {
Name string `json:"name"`
Port int `json:"port"`
OpenInner bool `json:"openInner"`
OpenOuter bool `json:"openOuter"`
}
type ThirdComponentKubernetes struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
}

View File

@ -0,0 +1,164 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2021-2021 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package componentdefinition
import (
"context"
"fmt"
"strings"
"sync"
"github.com/goodrain/rainbond/db"
dbmodel "github.com/goodrain/rainbond/db/model"
"github.com/goodrain/rainbond/pkg/apis/rainbond/v1alpha1"
rainbondversioned "github.com/goodrain/rainbond/pkg/generated/clientset/versioned"
v1 "github.com/goodrain/rainbond/worker/appm/types/v1"
"github.com/sirupsen/logrus"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
var ErrNotSupport = fmt.Errorf("not support component definition")
var ErrOnlyCUESupport = fmt.Errorf("component definition only support cue template")
type ComponentDefinitionBuilder struct {
definitions map[string]*v1alpha1.ComponentDefinition
namespace string
lock sync.Mutex
}
var componentDefinitionBuilder *ComponentDefinitionBuilder
func NewComponentDefinitionBuilder(namespace string) *ComponentDefinitionBuilder {
componentDefinitionBuilder = &ComponentDefinitionBuilder{
definitions: make(map[string]*v1alpha1.ComponentDefinition),
namespace: namespace,
}
return componentDefinitionBuilder
}
func GetComponentDefinitionBuilder() *ComponentDefinitionBuilder {
return componentDefinitionBuilder
}
func (c *ComponentDefinitionBuilder) OnAdd(obj interface{}) {
c.lock.Lock()
defer c.lock.Unlock()
cd, ok := obj.(*v1alpha1.ComponentDefinition)
if ok {
logrus.Infof("load componentdefinition %s", cd.Name)
c.definitions[cd.Name] = cd
}
}
func (c *ComponentDefinitionBuilder) OnUpdate(oldObj, newObj interface{}) {
c.lock.Lock()
defer c.lock.Unlock()
cd, ok := newObj.(*v1alpha1.ComponentDefinition)
if ok {
logrus.Infof("update componentdefinition %s", cd.Name)
c.definitions[cd.Name] = cd
}
}
func (c *ComponentDefinitionBuilder) OnDelete(obj interface{}) {
c.lock.Lock()
defer c.lock.Unlock()
cd, ok := obj.(*v1alpha1.ComponentDefinition)
if ok {
logrus.Infof("delete componentdefinition %s", cd.Name)
delete(c.definitions, cd.Name)
}
}
func (c *ComponentDefinitionBuilder) GetComponentDefinition(name string) *v1alpha1.ComponentDefinition {
c.lock.Lock()
defer c.lock.Unlock()
return c.definitions[name]
}
func (c *ComponentDefinitionBuilder) GetComponentProperties(as *v1.AppService, dbm db.Manager, cd *v1alpha1.ComponentDefinition) interface{} {
//TODO: support custom component properties
switch cd.Name {
case thirdComponetDefineName:
properties := &ThirdComponentProperties{}
tpsd, err := dbm.ThirdPartySvcDiscoveryCfgDao().GetByServiceID(as.ServiceID)
if err != nil {
logrus.Errorf("query component %s third source config failure %s", as.ServiceID, err.Error())
}
if tpsd != nil {
// support other source type
if tpsd.Type == dbmodel.DiscorveryTypeKubernetes.String() {
properties.Kubernetes = ThirdComponentKubernetes{
Name: tpsd.ServiceName,
Namespace: tpsd.Namespace,
}
}
}
ports, err := dbm.TenantServicesPortDao().GetPortsByServiceID(as.ServiceID)
if err != nil {
logrus.Errorf("query component %s ports failure %s", as.ServiceID, err.Error())
}
for _, port := range ports {
properties.Port = append(properties.Port, &ThirdComponentPort{
Port: port.ContainerPort,
Name: strings.ToLower(port.PortAlias),
OpenInner: *port.IsInnerService,
OpenOuter: *port.IsOuterService,
})
}
if properties.Port == nil {
properties.Port = []*ThirdComponentPort{}
}
return properties
default:
return nil
}
}
func (c *ComponentDefinitionBuilder) BuildWorkloadResource(as *v1.AppService, dbm db.Manager) error {
cd := c.GetComponentDefinition(as.GetComponentDefinitionName())
if cd == nil {
return ErrNotSupport
}
if cd.Spec.Schematic == nil || cd.Spec.Schematic.CUE == nil {
return ErrOnlyCUESupport
}
ctx := NewTemplateContext(as, cd.Spec.Schematic.CUE.Template, c.GetComponentProperties(as, dbm, cd))
manifests, err := ctx.GenerateComponentManifests()
if err != nil {
return err
}
ctx.SetContextValue(manifests)
as.SetManifests(manifests)
return nil
}
//InitCoreComponentDefinition init the built-in component type definition.
//Should be called after the store is initialized.
func (c *ComponentDefinitionBuilder) InitCoreComponentDefinition(rainbondClient rainbondversioned.Interface) {
coreComponentDefinition := []*v1alpha1.ComponentDefinition{&thirdComponetDefine}
for _, ccd := range coreComponentDefinition {
if c.GetComponentDefinition(ccd.Name) == nil {
logrus.Infof("create core componentdefinition %s", ccd.Name)
if _, err := rainbondClient.RainbondV1alpha1().ComponentDefinitions(c.namespace).Create(context.Background(), ccd, metav1.CreateOptions{}); err != nil {
logrus.Errorf("create core componentdefinition %s failire %s", ccd.Name, err.Error())
}
}
}
logrus.Infof("success check core componentdefinition from cluster")
}

View File

@ -0,0 +1,42 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2021-2021 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package componentdefinition
import (
"encoding/json"
"testing"
v1 "github.com/goodrain/rainbond/worker/appm/types/v1"
)
func TestTemplateContext(t *testing.T) {
ctx := NewTemplateContext(&v1.AppService{AppServiceBase: v1.AppServiceBase{ServiceID: "1234567890", ServiceAlias: "niasdjaj", TenantID: "098765432345678"}}, cueTemplate, map[string]interface{}{
"kubernetes": map[string]interface{}{
"name": "service-name",
"namespace": "t-namesapce",
},
"port": []map[string]interface{}{},
})
manifests, err := ctx.GenerateComponentManifests()
if err != nil {
t.Fatal(err)
}
show, _ := json.Marshal(manifests)
t.Log(string(show))
}

View File

@ -0,0 +1,183 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2021-2021 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package componentdefinition
import (
"encoding/json"
"fmt"
"strings"
"unicode"
"cuelang.org/go/cue"
"cuelang.org/go/cue/build"
v1 "github.com/goodrain/rainbond/worker/appm/types/v1"
"github.com/oam-dev/kubevela/pkg/cue/model"
"github.com/pkg/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
const (
// ParameterTag is the keyword in CUE template to define users' input
ParameterTag = "parameter"
// OutputFieldName is the reference of context base object
OutputFieldName = "output"
// OutputsFieldName is the reference of context Auxiliaries
OutputsFieldName = "outputs"
// ConfigFieldName is the reference of context config
ConfigFieldName = "config"
// ContextName is the name of context
ContextName = "name"
// ContextAppName is the appName of context
ContextAppName = "appName"
// ContextID is the componentID of context
ContextID = "componentID"
// ContextAppID is the appID of context
ContextAppID = "appID"
// ContextNamespace is the namespace of the app
ContextNamespace = "namespace"
)
type TemplateContext struct {
as *v1.AppService
componentName string
appName string
componentID string
appID string
namespace string
template string
params interface{}
}
func NewTemplateContext(as *v1.AppService, template string, params interface{}) *TemplateContext {
return &TemplateContext{
as: as,
componentName: as.ServiceAlias,
appName: as.AppID,
componentID: as.ServiceID,
appID: as.AppID,
namespace: as.TenantID,
template: template,
params: params,
}
}
func (c *TemplateContext) GenerateComponentManifests() ([]*unstructured.Unstructured, error) {
bi := build.NewContext().NewInstance("", nil)
if err := bi.AddFile("-", c.template); err != nil {
return nil, errors.WithMessagef(err, "invalid cue template of component %s", c.componentID)
}
var paramFile = "parameter: {}"
if c.params != nil {
bt, err := json.Marshal(c.params)
if err != nil {
return nil, errors.WithMessagef(err, "marshal parameter of component %s", c.componentID)
}
if string(bt) != "null" {
paramFile = fmt.Sprintf("%s: %s", ParameterTag, string(bt))
}
}
if err := bi.AddFile("parameter", paramFile); err != nil {
return nil, errors.WithMessagef(err, "invalid parameter of component %s", c.componentID)
}
if err := bi.AddFile("-", c.ExtendedContextFile()); err != nil {
return nil, err
}
var r cue.Runtime
inst, err := r.Build(bi)
if err != nil {
return nil, err
}
if err := inst.Value().Validate(); err != nil {
return nil, errors.WithMessagef(err, "invalid cue template of component %s after merge parameter and context", c.componentID)
}
output := inst.Lookup(OutputFieldName)
base, err := model.NewBase(output)
if err != nil {
return nil, errors.WithMessagef(err, "invalid output of component %s", c.componentID)
}
workload, err := base.Unstructured()
if err != nil {
return nil, errors.WithMessagef(err, "invalid output of component %s", c.componentID)
}
manifests := []*unstructured.Unstructured{workload}
outputs := inst.Lookup(OutputsFieldName)
if !outputs.Exists() {
return manifests, nil
}
st, err := outputs.Struct()
if err != nil {
return nil, errors.WithMessagef(err, "invalid outputs of workload %s", c.componentID)
}
for i := 0; i < st.Len(); i++ {
fieldInfo := st.Field(i)
if fieldInfo.IsDefinition || fieldInfo.IsHidden || fieldInfo.IsOptional {
continue
}
other, err := model.NewOther(fieldInfo.Value)
if err != nil {
return nil, errors.WithMessagef(err, "invalid outputs(%s) of workload %s", fieldInfo.Name, c.componentID)
}
othermanifest, err := other.Unstructured()
if err != nil {
return nil, errors.WithMessagef(err, "invalid outputs(%s) of workload %s", fieldInfo.Name, c.componentID)
}
manifests = append(manifests, othermanifest)
}
return manifests, nil
}
func (c *TemplateContext) SetContextValue(manifests []*unstructured.Unstructured) {
for i := range manifests {
manifests[i].SetNamespace(c.namespace)
manifests[i].SetLabels(c.as.GetCommonLabels(manifests[i].GetLabels()))
}
}
func (c *TemplateContext) ExtendedContextFile() string {
var buff string
buff += fmt.Sprintf(ContextName+": \"%s\"\n", c.componentName)
buff += fmt.Sprintf(ContextAppName+": \"%s\"\n", c.appName)
buff += fmt.Sprintf(ContextNamespace+": \"%s\"\n", c.namespace)
buff += fmt.Sprintf(ContextAppID+": \"%s\"\n", c.appID)
buff += fmt.Sprintf(ContextID+": \"%s\"\n", c.componentID)
return fmt.Sprintf("context: %s", structMarshal(buff))
}
func structMarshal(v string) string {
skip := false
v = strings.TrimFunc(v, func(r rune) bool {
if !skip {
if unicode.IsSpace(r) {
return true
}
skip = true
}
return false
})
if strings.HasPrefix(v, "{") {
return v
}
return fmt.Sprintf("{%s}", v)
}

View File

@ -0,0 +1,89 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2021-2021 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package componentdefinition
import (
"github.com/goodrain/rainbond/pkg/apis/rainbond/v1alpha1"
"github.com/oam-dev/kubevela/apis/core.oam.dev/common"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
var cueTemplate = `
output: {
apiVersion: "rainbond.io/v1alpha1"
kind: "ThirdComponent"
metadata: {
name: context.componentID
namespace: context.namespace
}
spec: {
endpointSource: {
if parameter["kubernetes"] != _|_ {
kubernetesService: {
namespace: parameter["kubernetes"]["namespace"],
name: parameter["kubernetes"]["name"]
}
}
}
if parameter["port"] != _|_ {
ports: parameter["port"]
}
}
}
parameter: {
kubernetes?: {
namespace?: string
name: string
}
port?: [...{
name: string
port: >0 & <=65533
openInner: bool
openOuter: bool
}]
}
`
var thirdComponetDefineName = "core-thirdcomponent"
var thirdComponetDefine = v1alpha1.ComponentDefinition{
TypeMeta: v1.TypeMeta{
Kind: "ComponentDefinition",
APIVersion: "rainbond.io/v1alpha1",
},
ObjectMeta: v1.ObjectMeta{
Name: thirdComponetDefineName,
Annotations: map[string]string{
"definition.oam.dev/description": "Rainbond built-in component type that defines third-party service components.",
},
},
Spec: v1alpha1.ComponentDefinitionSpec{
Workload: common.WorkloadTypeDescriptor{
Type: "ThirdComponent",
Definition: common.WorkloadGVK{
APIVersion: "rainbond.io/v1alpha1",
Kind: "ThirdComponent",
},
},
Schematic: &common.Schematic{
CUE: &common.CUE{
Template: cueTemplate,
},
},
},
}

View File

@ -26,7 +26,9 @@ import (
"github.com/goodrain/rainbond/util"
"github.com/goodrain/rainbond/worker/appm/store"
v1 "github.com/goodrain/rainbond/worker/appm/types/v1"
"github.com/oam-dev/kubevela/pkg/utils/apply"
"k8s.io/client-go/kubernetes"
"sigs.k8s.io/controller-runtime/pkg/client"
)
//Controller service operating controller interface
@ -64,23 +66,27 @@ var TypeControllerRefreshHPA TypeController = "refreshhpa"
//Manager controller manager
type Manager struct {
ctx context.Context
cancel context.CancelFunc
client kubernetes.Interface
controllers map[string]Controller
store store.Storer
lock sync.Mutex
ctx context.Context
cancel context.CancelFunc
client kubernetes.Interface
runtimeClient client.Client
apply apply.Applicator
controllers map[string]Controller
store store.Storer
lock sync.Mutex
}
//NewManager new manager
func NewManager(store store.Storer, client kubernetes.Interface) *Manager {
func NewManager(store store.Storer, client kubernetes.Interface, runtimeClient client.Client) *Manager {
ctx, cancel := context.WithCancel(context.Background())
return &Manager{
ctx: ctx,
cancel: cancel,
client: client,
controllers: make(map[string]Controller),
store: store,
ctx: ctx,
cancel: cancel,
client: client,
apply: apply.NewAPIApplicator(runtimeClient),
runtimeClient: runtimeClient,
controllers: make(map[string]Controller),
store: store,
}
}
@ -108,6 +114,7 @@ func (m *Manager) StartController(controllerType TypeController, apps ...v1.AppS
appService: apps,
manager: m,
stopChan: make(chan struct{}),
ctx: context.Background(),
}
case TypeStopController:
controller = &stopController{
@ -115,6 +122,7 @@ func (m *Manager) StartController(controllerType TypeController, apps ...v1.AppS
appService: apps,
manager: m,
stopChan: make(chan struct{}),
ctx: context.Background(),
}
case TypeScalingController:
controller = &scalingController{

View File

@ -39,6 +39,7 @@ type startController struct {
controllerID string
appService []v1.AppService
manager *Manager
ctx context.Context
}
func (s *startController) Begin() {
@ -54,8 +55,8 @@ func (s *startController) Begin() {
for _, slist := range sl {
var wait sync.WaitGroup
for _, service := range slist {
wait.Add(1)
go func(service v1.AppService) {
wait.Add(1)
defer wait.Done()
logrus.Debugf("App runtime begin start app service(%s)", service.ServiceAlias)
service.Logger.Info("App runtime begin start app service "+service.ServiceAlias, event.GetLoggerOption("starting"))
@ -82,6 +83,7 @@ func (s *startController) errorCallback(app v1.AppService) error {
app.Logger.Info("Begin clean resources that have been created", event.GetLoggerOption("starting"))
stopController := stopController{
manager: s.manager,
ctx: s.ctx,
}
if err := stopController.stopOne(app); err != nil {
logrus.Errorf("stop app failure after start failure. %s", err.Error())
@ -92,19 +94,28 @@ func (s *startController) errorCallback(app v1.AppService) error {
}
func (s *startController) startOne(app v1.AppService) error {
//first: check and create namespace
_, err := s.manager.client.CoreV1().Namespaces().Get(context.Background(), app.TenantID, metav1.GetOptions{})
_, err := s.manager.client.CoreV1().Namespaces().Get(s.ctx, app.TenantID, metav1.GetOptions{})
if err != nil {
if errors.IsNotFound(err) {
_, err = s.manager.client.CoreV1().Namespaces().Create(context.Background(), app.GetTenant(), metav1.CreateOptions{})
_, err = s.manager.client.CoreV1().Namespaces().Create(s.ctx, app.GetTenant(), metav1.CreateOptions{})
}
if err != nil {
return fmt.Errorf("create or check namespace failure %s", err.Error())
}
}
// for custom component
if len(app.GetManifests()) > 0 {
for _, manifest := range app.GetManifests() {
if err := s.manager.apply.Apply(s.ctx, manifest); err != nil {
return fmt.Errorf("apply custom component manifest %s/%s failure %s", manifest.GetKind(), manifest.GetName(), err.Error())
}
}
}
// for core component
//step 1: create configmap
if configs := app.GetConfigMaps(); configs != nil {
for _, config := range configs {
_, err := s.manager.client.CoreV1().ConfigMaps(app.TenantID).Create(context.Background(), config, metav1.CreateOptions{})
_, err := s.manager.client.CoreV1().ConfigMaps(app.TenantID).Create(s.ctx, config, metav1.CreateOptions{})
if err != nil && !errors.IsAlreadyExists(err) {
return fmt.Errorf("create config map failure:%s", err.Error())
}
@ -113,20 +124,20 @@ func (s *startController) startOne(app v1.AppService) error {
// create claims
for _, claim := range app.GetClaimsManually() {
logrus.Debugf("create claim: %s", claim.Name)
_, err := s.manager.client.CoreV1().PersistentVolumeClaims(app.TenantID).Create(context.Background(), claim, metav1.CreateOptions{})
_, err := s.manager.client.CoreV1().PersistentVolumeClaims(app.TenantID).Create(s.ctx, claim, metav1.CreateOptions{})
if err != nil && !errors.IsAlreadyExists(err) {
return fmt.Errorf("create claims: %v", err)
}
}
//step 2: create statefulset or deployment
if statefulset := app.GetStatefulSet(); statefulset != nil {
_, err = s.manager.client.AppsV1().StatefulSets(app.TenantID).Create(context.Background(), statefulset, metav1.CreateOptions{})
_, err = s.manager.client.AppsV1().StatefulSets(app.TenantID).Create(s.ctx, statefulset, metav1.CreateOptions{})
if err != nil {
return fmt.Errorf("create statefulset failure:%s", err.Error())
}
}
if deployment := app.GetDeployment(); deployment != nil {
_, err = s.manager.client.AppsV1().Deployments(app.TenantID).Create(context.Background(), deployment, metav1.CreateOptions{})
_, err = s.manager.client.AppsV1().Deployments(app.TenantID).Create(s.ctx, deployment, metav1.CreateOptions{})
if err != nil {
return fmt.Errorf("create deployment failure:%s;", err.Error())
}
@ -134,14 +145,14 @@ func (s *startController) startOne(app v1.AppService) error {
//step 3: create services
if services := app.GetServices(true); services != nil {
if err := CreateKubeService(s.manager.client, app.TenantID, services...); err != nil {
return fmt.Errorf("Create service failure %s", err.Error())
return fmt.Errorf("create service failure %s", err.Error())
}
}
//step 4: create secrets
if secrets := append(app.GetSecrets(true), app.GetEnvVarSecrets(true)...); secrets != nil {
for _, secret := range secrets {
if len(secret.ResourceVersion) == 0 {
_, err := s.manager.client.CoreV1().Secrets(app.TenantID).Create(context.Background(), secret, metav1.CreateOptions{})
_, err := s.manager.client.CoreV1().Secrets(app.TenantID).Create(s.ctx, secret, metav1.CreateOptions{})
if err != nil && !errors.IsAlreadyExists(err) {
return fmt.Errorf("create secret failure:%s", err.Error())
}
@ -152,7 +163,7 @@ func (s *startController) startOne(app v1.AppService) error {
if ingresses := app.GetIngress(true); ingresses != nil {
for _, ingress := range ingresses {
if len(ingress.ResourceVersion) == 0 {
_, err := s.manager.client.ExtensionsV1beta1().Ingresses(app.TenantID).Create(context.Background(), ingress, metav1.CreateOptions{})
_, err := s.manager.client.ExtensionsV1beta1().Ingresses(app.TenantID).Create(s.ctx, ingress, metav1.CreateOptions{})
if err != nil && !errors.IsAlreadyExists(err) {
return fmt.Errorf("create ingress failure:%s", err.Error())
}
@ -163,7 +174,7 @@ func (s *startController) startOne(app v1.AppService) error {
if hpas := app.GetHPAs(); len(hpas) != 0 {
for _, hpa := range hpas {
if len(hpa.ResourceVersion) == 0 {
_, err := s.manager.client.AutoscalingV2beta2().HorizontalPodAutoscalers(hpa.GetNamespace()).Create(context.Background(), hpa, metav1.CreateOptions{})
_, err := s.manager.client.AutoscalingV2beta2().HorizontalPodAutoscalers(hpa.GetNamespace()).Create(s.ctx, hpa, metav1.CreateOptions{})
if err != nil && !errors.IsAlreadyExists(err) {
logrus.Debugf("hpa: %#v", hpa)
return fmt.Errorf("create hpa: %v", err)
@ -182,7 +193,7 @@ func (s *startController) startOne(app v1.AppService) error {
if smClient != nil {
for _, sm := range sms {
if len(sm.ResourceVersion) == 0 {
_, err := smClient.MonitoringV1().ServiceMonitors(sm.GetNamespace()).Create(context.Background(), sm, metav1.CreateOptions{})
_, err := smClient.MonitoringV1().ServiceMonitors(sm.GetNamespace()).Create(s.ctx, sm, metav1.CreateOptions{})
if err != nil && !errors.IsAlreadyExists(err) {
logrus.Errorf("create service monitor failure: %s", err.Error())
}

View File

@ -39,6 +39,7 @@ type stopController struct {
appService []v1.AppService
manager *Manager
waiting time.Duration
ctx context.Context
}
func (s *stopController) Begin() {
@ -64,12 +65,21 @@ func (s *stopController) Begin() {
s.manager.callback(s.controllerID, nil)
}
func (s *stopController) stopOne(app v1.AppService) error {
// for custom component
if len(app.GetManifests()) > 0 {
for _, manifest := range app.GetManifests() {
if err := s.manager.runtimeClient.Delete(s.ctx, manifest); err != nil && !errors.IsNotFound(err) {
logrus.Errorf("delete custom component manifest %s/%s failure %s", manifest.GetKind(), manifest.GetName(), err.Error())
}
}
}
var zero int64
//step 1: delete services
if services := app.GetServices(true); services != nil {
for _, service := range services {
if service != nil && service.Name != "" {
err := s.manager.client.CoreV1().Services(app.TenantID).Delete(context.Background(), service.Name, metav1.DeleteOptions{
err := s.manager.client.CoreV1().Services(app.TenantID).Delete(s.ctx, service.Name, metav1.DeleteOptions{
GracePeriodSeconds: &zero,
})
if err != nil && !errors.IsNotFound(err) {
@ -82,7 +92,7 @@ func (s *stopController) stopOne(app v1.AppService) error {
if secrets := app.GetSecrets(true); secrets != nil {
for _, secret := range secrets {
if secret != nil && secret.Name != "" {
err := s.manager.client.CoreV1().Secrets(app.TenantID).Delete(context.Background(), secret.Name, metav1.DeleteOptions{
err := s.manager.client.CoreV1().Secrets(app.TenantID).Delete(s.ctx, secret.Name, metav1.DeleteOptions{
GracePeriodSeconds: &zero,
})
if err != nil && !errors.IsNotFound(err) {
@ -95,7 +105,7 @@ func (s *stopController) stopOne(app v1.AppService) error {
if ingresses := app.GetIngress(true); ingresses != nil {
for _, ingress := range ingresses {
if ingress != nil && ingress.Name != "" {
err := s.manager.client.ExtensionsV1beta1().Ingresses(app.TenantID).Delete(context.Background(), ingress.Name, metav1.DeleteOptions{
err := s.manager.client.ExtensionsV1beta1().Ingresses(app.TenantID).Delete(s.ctx, ingress.Name, metav1.DeleteOptions{
GracePeriodSeconds: &zero,
})
if err != nil && !errors.IsNotFound(err) {
@ -108,7 +118,7 @@ func (s *stopController) stopOne(app v1.AppService) error {
if configs := app.GetConfigMaps(); configs != nil {
for _, config := range configs {
if config != nil && config.Name != "" {
err := s.manager.client.CoreV1().ConfigMaps(app.TenantID).Delete(context.Background(), config.Name, metav1.DeleteOptions{
err := s.manager.client.CoreV1().ConfigMaps(app.TenantID).Delete(s.ctx, config.Name, metav1.DeleteOptions{
GracePeriodSeconds: &zero,
})
if err != nil && !errors.IsNotFound(err) {
@ -119,14 +129,14 @@ func (s *stopController) stopOne(app v1.AppService) error {
}
//step 5: delete statefulset or deployment
if statefulset := app.GetStatefulSet(); statefulset != nil {
err := s.manager.client.AppsV1().StatefulSets(app.TenantID).Delete(context.Background(), statefulset.Name, metav1.DeleteOptions{})
err := s.manager.client.AppsV1().StatefulSets(app.TenantID).Delete(s.ctx, statefulset.Name, metav1.DeleteOptions{})
if err != nil && !errors.IsNotFound(err) {
return fmt.Errorf("delete statefulset failure:%s", err.Error())
}
s.manager.store.OnDeletes(statefulset)
}
if deployment := app.GetDeployment(); deployment != nil && deployment.Name != "" {
err := s.manager.client.AppsV1().Deployments(app.TenantID).Delete(context.Background(), deployment.Name, metav1.DeleteOptions{})
err := s.manager.client.AppsV1().Deployments(app.TenantID).Delete(s.ctx, deployment.Name, metav1.DeleteOptions{})
if err != nil && !errors.IsNotFound(err) {
return fmt.Errorf("delete deployment failure:%s", err.Error())
}
@ -137,7 +147,7 @@ func (s *stopController) stopOne(app v1.AppService) error {
if pods := app.GetPods(true); pods != nil {
for _, pod := range pods {
if pod != nil && pod.Name != "" {
err := s.manager.client.CoreV1().Pods(app.TenantID).Delete(context.Background(), pod.Name, metav1.DeleteOptions{
err := s.manager.client.CoreV1().Pods(app.TenantID).Delete(s.ctx, pod.Name, metav1.DeleteOptions{
GracePeriodSeconds: &gracePeriodSeconds,
})
if err != nil && !errors.IsNotFound(err) {
@ -149,7 +159,7 @@ func (s *stopController) stopOne(app v1.AppService) error {
//step 7: deleta all hpa
if hpas := app.GetHPAs(); len(hpas) != 0 {
for _, hpa := range hpas {
err := s.manager.client.AutoscalingV2beta2().HorizontalPodAutoscalers(hpa.GetNamespace()).Delete(context.Background(), hpa.GetName(), metav1.DeleteOptions{})
err := s.manager.client.AutoscalingV2beta2().HorizontalPodAutoscalers(hpa.GetNamespace()).Delete(s.ctx, hpa.GetName(), metav1.DeleteOptions{})
if err != nil && !errors.IsNotFound(err) {
return fmt.Errorf("delete hpa: %v", err)
}
@ -165,7 +175,7 @@ func (s *stopController) stopOne(app v1.AppService) error {
}
if smClient != nil {
for _, sm := range sms {
err := smClient.MonitoringV1().ServiceMonitors(sm.GetNamespace()).Delete(context.Background(), sm.GetName(), metav1.DeleteOptions{})
err := smClient.MonitoringV1().ServiceMonitors(sm.GetNamespace()).Delete(s.ctx, sm.GetName(), metav1.DeleteOptions{})
if err != nil && !errors.IsNotFound(err) {
logrus.Errorf("delete service monitor failure: %s", err.Error())
}

View File

@ -25,25 +25,22 @@ import (
"github.com/goodrain/rainbond/db"
"github.com/goodrain/rainbond/db/model"
"github.com/goodrain/rainbond/util"
"github.com/goodrain/rainbond/worker/appm/componentdefinition"
v1 "github.com/goodrain/rainbond/worker/appm/types/v1"
"github.com/sirupsen/logrus"
)
func init() {
//first conv service source
RegistConversion("ServiceSource", ServiceSource)
//step2 conv service base
RegistConversion("TenantServiceBase", TenantServiceBase)
// core component conversion
// convert config group to env secrets
RegistConversion("TenantServiceConfigGroup", TenantServiceConfigGroup)
//step3 conv service pod base info
//step1 conv service pod base info
RegistConversion("TenantServiceVersion", TenantServiceVersion)
//step4 conv service plugin
//step2 conv service plugin
RegistConversion("TenantServicePlugin", TenantServicePlugin)
//step5 conv service inner and outer regist
RegistConversion("TenantServiceRegist", TenantServiceRegist)
//step6 -
//step3 -
RegistConversion("TenantServiceAutoscaler", TenantServiceAutoscaler)
//step7 conv service monitor
//step4 conv service monitor
RegistConversion("TenantServiceMonitor", TenantServiceMonitor)
}
@ -88,7 +85,22 @@ func InitAppService(dbmanager db.Manager, serviceID string, configs map[string]s
if app != nil {
appService.AppServiceBase.GovernanceMode = app.GovernanceMode
}
if err := TenantServiceBase(appService, dbmanager); err != nil {
logrus.Errorf("init component base config failure %s", err.Error())
return nil, err
}
// all component can regist server.
if err := TenantServiceRegist(appService, dbmanager); err != nil {
logrus.Errorf("init component server regist config failure %s", err.Error())
return nil, err
}
if appService.IsCustomComponent() {
if err := componentdefinition.GetComponentDefinitionBuilder().BuildWorkloadResource(appService, dbmanager); err != nil {
logrus.Errorf("init component by component definition build failure %s", err.Error())
return nil, err
}
return appService, nil
}
for _, c := range conversionList {
if len(enableConversionList) == 0 || util.StringArrayContains(enableConversionList, c.Name) {
if err := c.Conversion(appService, dbmanager); err != nil {

View File

@ -138,12 +138,15 @@ func (a *AppServiceBuild) Build() (*v1.K8sResources, error) {
return nil, fmt.Errorf("find upstream plugin mapping port error, %s", err.Error())
}
ports, pp, err = a.CreateUpstreamPluginMappingPort(ports, pluginPorts)
if err != nil {
logrus.Errorf("create mapping port failure %s", err.Error())
}
}
var services []*corev1.Service
var ingresses []*extensions.Ingress
var secrets []*corev1.Secret
if ports != nil && len(ports) > 0 {
if len(ports) > 0 {
for i := range ports {
port := ports[i]
if *port.IsInnerService {

View File

@ -218,10 +218,10 @@ func createTCPDefaultPluginContainer(as *typesv1.AppService, pluginID string, en
}
func setSidecarContainerLifecycle(as *typesv1.AppService, con *corev1.Container, pluginConfig *api_model.ResourceSpec) {
if strings.ToLower(as.ExtensionSet["DISABLE_SIDECAR_CHECK"]) != "true" {
if strings.ToLower(as.ExtensionSet["disable_sidecar_check"]) != "true" {
var port int
if as.ExtensionSet["SIDECAR_CHECK_PORT"] != "" {
cport, _ := strconv.Atoi(as.ExtensionSet["SIDECAR_CHECK_PORT"])
if as.ExtensionSet["sidecar_check_port"] != "" {
cport, _ := strconv.Atoi(as.ExtensionSet["sidecar_check_port"])
if cport != 0 {
port = cport
}

View File

@ -95,11 +95,7 @@ func TenantServiceBase(as *v1.AppService, dbmanager db.Manager) error {
if as.DeployVersion == "" {
as.DeployVersion = tenantService.DeployVersion
}
as.ContainerCPU = tenantService.ContainerCPU
as.ContainerGPU = tenantService.ContainerGPU
as.AppID = tenantService.AppID
as.ContainerMemory = tenantService.ContainerMemory
as.Replicas = tenantService.Replicas
as.ServiceAlias = tenantService.ServiceAlias
as.UpgradeMethod = v1.TypeUpgradeMethod(tenantService.UpgradeMethod)
if as.CreaterID == "" {
@ -110,12 +106,19 @@ func TenantServiceBase(as *v1.AppService, dbmanager db.Manager) error {
return fmt.Errorf("conversion tenant info failure %s", err.Error())
}
if tenantService.Kind == dbmodel.ServiceKindThirdParty.String() {
disCfg, _ := dbmanager.ThirdPartySvcDiscoveryCfgDao().GetByServiceID(as.ServiceID)
as.SetDiscoveryCfg(disCfg)
return nil
}
label, err := dbmanager.TenantServiceLabelDao().GetLabelByNodeSelectorKey(as.ServiceID, "windows")
if tenantService.Kind == dbmodel.ServiceKindCustom.String() {
return nil
}
label, _ := dbmanager.TenantServiceLabelDao().GetLabelByNodeSelectorKey(as.ServiceID, "windows")
if label != nil {
as.IsWindowsService = true
}
if !tenantService.IsState() {
initBaseDeployment(as, tenantService)
return nil
@ -124,8 +127,12 @@ func TenantServiceBase(as *v1.AppService, dbmanager db.Manager) error {
initBaseStatefulSet(as, tenantService)
return nil
}
return fmt.Errorf("Kind: %s; do not decision build type for service %s",
tenantService.Kind, as.ServiceAlias)
// component resource and
as.ContainerCPU = tenantService.ContainerCPU
as.ContainerGPU = tenantService.ContainerGPU
as.ContainerMemory = tenantService.ContainerMemory
as.Replicas = tenantService.Replicas
return fmt.Errorf("kind: %s; do not decision build type for service %s", tenantService.Kind, as.ServiceAlias)
}
func initTenant(as *v1.AppService, tenant *dbmodel.Tenants) error {

View File

@ -41,6 +41,8 @@ type Informer struct {
HorizontalPodAutoscaler cache.SharedIndexInformer
CRD cache.SharedIndexInformer
HelmApp cache.SharedIndexInformer
ComponentDefinition cache.SharedIndexInformer
ThirdComponent cache.SharedIndexInformer
CRS map[string]cache.SharedIndexInformer
}
@ -70,6 +72,8 @@ func (i *Informer) Start(stop chan struct{}) {
go i.Claims.Run(stop)
go i.CRD.Run(stop)
go i.HelmApp.Run(stop)
go i.ComponentDefinition.Run(stop)
go i.ThirdComponent.Run(stop)
}
//Ready if all kube informers is syncd, store is ready

View File

@ -45,4 +45,6 @@ type Lister struct {
HorizontalPodAutoscaler autoscalingv2.HorizontalPodAutoscalerLister
CRD crdlisters.CustomResourceDefinitionLister
HelmApp v1alpha1.HelmAppLister
ComponentDefinition v1alpha1.ComponentDefinitionLister
ThirdComponent v1alpha1.ThirdComponentLister
}

View File

@ -35,6 +35,7 @@ import (
"github.com/goodrain/rainbond/pkg/generated/informers/externalversions"
"github.com/goodrain/rainbond/util/constants"
k8sutil "github.com/goodrain/rainbond/util/k8s"
"github.com/goodrain/rainbond/worker/appm/componentdefinition"
"github.com/goodrain/rainbond/worker/appm/conversion"
"github.com/goodrain/rainbond/worker/appm/f"
v1 "github.com/goodrain/rainbond/worker/appm/types/v1"
@ -137,6 +138,7 @@ type appRuntimeStore struct {
kubeconfig *rest.Config
clientset kubernetes.Interface
crdClient *internalclientset.Clientset
rainbondClient rainbondversioned.Interface
crClients map[string]interface{}
ctx context.Context
cancel context.CancelFunc
@ -169,6 +171,7 @@ func NewStore(
store := &appRuntimeStore{
kubeconfig: kubeconfig,
clientset: clientset,
rainbondClient: rainbondClient,
ctx: ctx,
cancel: cancel,
informers: &Informer{CRS: make(map[string]cache.SharedIndexInformer)},
@ -197,11 +200,6 @@ func NewStore(
infFactory := informers.NewSharedInformerFactoryWithOptions(conf.KubeClient, 10*time.Second,
informers.WithNamespace(corev1.NamespaceAll))
sharedInformer := externalversions.NewSharedInformerFactoryWithOptions(rainbondClient, 10*time.Second,
externalversions.WithNamespace(corev1.NamespaceAll))
store.listers.HelmApp = sharedInformer.Rainbond().V1alpha1().HelmApps().Lister()
store.informers.HelmApp = sharedInformer.Rainbond().V1alpha1().HelmApps().Informer()
store.informers.Namespace = infFactory.Core().V1().Namespaces().Informer()
store.informers.Deployment = infFactory.Apps().V1().Deployments().Informer()
@ -245,6 +243,17 @@ func NewStore(
store.informers.HorizontalPodAutoscaler = infFactory.Autoscaling().V2beta2().HorizontalPodAutoscalers().Informer()
store.listers.HorizontalPodAutoscaler = infFactory.Autoscaling().V2beta2().HorizontalPodAutoscalers().Lister()
// rainbond custom resource
rainbondInformer := externalversions.NewSharedInformerFactoryWithOptions(rainbondClient, 10*time.Second,
externalversions.WithNamespace(corev1.NamespaceAll))
store.listers.HelmApp = rainbondInformer.Rainbond().V1alpha1().HelmApps().Lister()
store.informers.HelmApp = rainbondInformer.Rainbond().V1alpha1().HelmApps().Informer()
store.listers.ThirdComponent = rainbondInformer.Rainbond().V1alpha1().ThirdComponents().Lister()
store.informers.ThirdComponent = rainbondInformer.Rainbond().V1alpha1().ThirdComponents().Informer()
store.listers.ComponentDefinition = rainbondInformer.Rainbond().V1alpha1().ComponentDefinitions().Lister()
store.informers.ComponentDefinition = rainbondInformer.Rainbond().V1alpha1().ComponentDefinitions().Informer()
store.informers.ComponentDefinition.AddEventHandlerWithResyncPeriod(componentdefinition.GetComponentDefinitionBuilder(), time.Second*300)
isThirdParty := func(ep *corev1.Endpoints) bool {
return ep.Labels["service-kind"] == model.ServiceKindThirdParty.String()
}
@ -427,6 +436,8 @@ func (a *appRuntimeStore) Start() error {
go a.clean()
for !a.Ready() {
}
// init core componentdefinition
componentdefinition.GetComponentDefinitionBuilder().InitCoreComponentDefinition(a.rainbondClient)
go func() {
a.initThirdPartyService()
a.initCustomResourceInformer(stopch)
@ -989,6 +1000,13 @@ func (a *appRuntimeStore) GetAllAppServices() (apps []*v1.AppService) {
func (a *appRuntimeStore) GetAppServiceStatus(serviceID string) string {
app := a.GetAppService(serviceID)
if app == nil {
component, _ := a.dbmanager.TenantServiceDao().GetServiceByID(serviceID)
if component == nil {
return v1.UNKNOW
}
if component.Kind == model.ServiceKindThirdParty.String() {
return v1.CLOSED
}
versions, err := a.dbmanager.VersionInfoDao().GetVersionByServiceID(serviceID)
if (err != nil && err == gorm.ErrRecordNotFound) || len(versions) == 0 {
return v1.UNDEPLOY

View File

@ -90,12 +90,13 @@ var (
//GetServiceStatus get service status
func (a *AppService) GetServiceStatus() string {
//TODO: support custom component status
if a.ServiceKind == model.ServiceKindThirdParty {
endpoints := a.GetEndpoints(false)
if len(endpoints) == 0 {
return CLOSED
}
var readyEndpointSize int
for _, ed := range endpoints {
for _, s := range ed.Subsets {

View File

@ -22,7 +22,9 @@ import (
"fmt"
"os"
"strconv"
"strings"
dbmodel "github.com/goodrain/rainbond/db/model"
monitorv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
"github.com/sirupsen/logrus"
v1 "k8s.io/api/apps/v1"
@ -30,6 +32,7 @@ import (
corev1 "k8s.io/api/core/v1"
extensions "k8s.io/api/extensions/v1beta1"
storagev1 "k8s.io/api/storage/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"github.com/goodrain/rainbond/builder"
"github.com/goodrain/rainbond/db/model"
@ -87,6 +90,7 @@ type AppServiceBase struct {
ServiceAlias string
ServiceType AppServiceType
ServiceKind model.ServiceKind
discoveryCfg *dbmodel.ThirdPartySvcDiscoveryCfg
DeployVersion string
ContainerCPU int
ContainerMemory int
@ -102,6 +106,31 @@ type AppServiceBase struct {
GovernanceMode string
}
//GetComponentDefinitionName get component definition name by component kind
func (a AppServiceBase) GetComponentDefinitionName() string {
if strings.HasPrefix(a.ServiceKind.String(), dbmodel.ServiceKindCustom.String()) {
return strings.Replace(a.ServiceKind.String(), dbmodel.ServiceKindCustom.String(), "", 1)
}
if a.discoveryCfg != nil && a.discoveryCfg.Type == dbmodel.DiscorveryTypeKubernetes.String() {
return "core-thirdcomponent"
}
return ""
}
func (a AppServiceBase) IsCustomComponent() bool {
if strings.HasPrefix(a.ServiceKind.String(), dbmodel.ServiceKindCustom.String()) {
return true
}
if a.discoveryCfg != nil && a.discoveryCfg.Type == dbmodel.DiscorveryTypeKubernetes.String() {
return true
}
return false
}
func (a *AppServiceBase) SetDiscoveryCfg(discoveryCfg *dbmodel.ThirdPartySvcDiscoveryCfg) {
a.discoveryCfg = discoveryCfg
}
//AppService a service of rainbond app state in kubernetes
type AppService struct {
AppServiceBase
@ -124,7 +153,6 @@ type AppService struct {
serviceMonitor []*monitorv1.ServiceMonitor
// claims that needs to be created manually
claimsmanual []*corev1.PersistentVolumeClaim
status AppServiceStatus
podMemoryRequest int64
podCPURequest int64
BootSeqContainer *corev1.Container
@ -133,6 +161,8 @@ type AppService struct {
UpgradePatch map[string][]byte
CustomParams map[string]string
envVarSecrets []*corev1.Secret
// custom componentdefinition output manifests
manifests []*unstructured.Unstructured
}
//CacheKey app cache key
@ -140,10 +170,7 @@ type CacheKey string
//Equal cache key serviceid and version and createID Equal
func (c CacheKey) Equal(end CacheKey) bool {
if string(c) == string(end) {
return true
}
return false
return string(c) == string(end)
}
//GetCacheKeyOnlyServiceID get cache key only service id
@ -798,6 +825,16 @@ func (a *AppService) GetCPURequest() (res int64) {
return
}
//GetManifests get component custom manifest
func (a *AppService) GetManifests() []*unstructured.Unstructured {
return a.manifests
}
//GetManifests get component custom manifest
func (a *AppService) SetManifests(manifests []*unstructured.Unstructured) {
a.manifests = manifests
}
func (a *AppService) String() string {
return fmt.Sprintf(`
-----------------------------------------------------

View File

@ -1,5 +1,5 @@
// Copyright (C) 2nilfmt.Errorf("a")4-2nilfmt.Errorf("a")8 Goodrain Co., Ltd.
// RAINBOND, Application Management Platform
// RAINBOND, component Management Platform
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@ -78,10 +78,7 @@ func NewManager(ctx context.Context,
var ErrCallback = fmt.Errorf("callback task to mq")
func (m *Manager) checkCount() bool {
if m.controllerManager.GetControllerSize() > m.cfg.MaxTasks {
return true
}
return false
return m.controllerManager.GetControllerSize() > m.cfg.MaxTasks
}
//AnalystToExec analyst exec
@ -146,28 +143,28 @@ func (m *Manager) startExec(task *model.Task) error {
logger := event.GetManager().GetLogger(body.EventID)
appService := m.store.GetAppService(body.ServiceID)
if appService != nil && !appService.IsClosed() {
logger.Info("Application is not closed, can not start", event.GetLastLoggerOption())
logger.Info("component is not closed, can not start", event.GetLastLoggerOption())
event.GetManager().ReleaseLogger(logger)
return nil
}
newAppService, err := conversion.InitAppService(m.dbmanager, body.ServiceID, body.Configs)
if err != nil {
logrus.Errorf("Application init create failure:%s", err.Error())
logger.Error("Application init create failure", event.GetCallbackLoggerOption())
logrus.Errorf("component init create failure:%s", err.Error())
logger.Error("component init create failure", event.GetCallbackLoggerOption())
event.GetManager().ReleaseLogger(logger)
return fmt.Errorf("Application init create failure")
return fmt.Errorf("application init create failure")
}
newAppService.Logger = logger
//regist new app service
m.store.RegistAppService(newAppService)
err = m.controllerManager.StartController(controller.TypeStartController, *newAppService)
if err != nil {
logrus.Errorf("Application run start controller failure:%s", err.Error())
logger.Error("Application run start controller failure", event.GetCallbackLoggerOption())
logrus.Errorf("component run start controller failure:%s", err.Error())
logger.Error("component run start controller failure", event.GetCallbackLoggerOption())
event.GetManager().ReleaseLogger(logger)
return fmt.Errorf("Application start failure")
return fmt.Errorf("component start failure")
}
logrus.Infof("service(%s) %s working is running.", body.ServiceID, "start")
logrus.Infof("component(%s) %s working is running.", body.ServiceID, "start")
return nil
}
@ -180,7 +177,7 @@ func (m *Manager) stopExec(task *model.Task) error {
logger := event.GetManager().GetLogger(body.EventID)
appService := m.store.GetAppService(body.ServiceID)
if appService == nil {
logger.Info("Application is closed, can not stop", event.GetLastLoggerOption())
logger.Info("component is closed, can not stop", event.GetLastLoggerOption())
event.GetManager().ReleaseLogger(logger)
return nil
}
@ -190,10 +187,10 @@ func (m *Manager) stopExec(task *model.Task) error {
}
err := m.controllerManager.StartController(controller.TypeStopController, *appService)
if err != nil {
logrus.Errorf("Application run stop controller failure:%s", err.Error())
logger.Info("Application run stop controller failure", event.GetCallbackLoggerOption())
logrus.Errorf("component run stop controller failure:%s", err.Error())
logger.Info("component run stop controller failure", event.GetCallbackLoggerOption())
event.GetManager().ReleaseLogger(logger)
return fmt.Errorf("Application stop failure")
return fmt.Errorf("component stop failure")
}
logrus.Infof("service(%s) %s working is running.", body.ServiceID, "stop")
return nil
@ -208,7 +205,7 @@ func (m *Manager) restartExec(task *model.Task) error {
logger := event.GetManager().GetLogger(body.EventID)
appService := m.store.GetAppService(body.ServiceID)
if appService == nil {
logger.Info("Application is closed, can not stop", event.GetLastLoggerOption())
logger.Info("component is closed, can not stop", event.GetLastLoggerOption())
event.GetManager().ReleaseLogger(logger)
return nil
}
@ -219,10 +216,10 @@ func (m *Manager) restartExec(task *model.Task) error {
//first stop app
err := m.controllerManager.StartController(controller.TypeRestartController, *appService)
if err != nil {
logrus.Errorf("Application run restart controller failure:%s", err.Error())
logger.Info("Application run restart controller failure", event.GetCallbackLoggerOption())
logrus.Errorf("component run restart controller failure:%s", err.Error())
logger.Info("component run restart controller failure", event.GetCallbackLoggerOption())
event.GetManager().ReleaseLogger(logger)
return fmt.Errorf("Application restart failure")
return fmt.Errorf("component restart failure")
}
logrus.Infof("service(%s) %s working is running.", body.ServiceID, "restart")
return nil
@ -280,8 +277,8 @@ func (m *Manager) horizontalScalingExec(task *model.Task) (err error) {
appService.Replicas = service.Replicas
err = m.controllerManager.StartController(controller.TypeScalingController, *appService)
if err != nil {
logrus.Errorf("Application run scaling controller failure:%s", err.Error())
logger.Info("Application run scaling controller failure", event.GetCallbackLoggerOption())
logrus.Errorf("component run scaling controller failure:%s", err.Error())
logger.Info("component run scaling controller failure", event.GetCallbackLoggerOption())
event.GetManager().ReleaseLogger(logger)
return
}
@ -315,8 +312,8 @@ func (m *Manager) verticalScalingExec(task *model.Task) error {
appService.Logger = logger
newAppService, err := conversion.InitAppService(m.dbmanager, body.ServiceID, nil)
if err != nil {
logrus.Errorf("Application init create failure:%s", err.Error())
logger.Error("Application init create failure", event.GetCallbackLoggerOption())
logrus.Errorf("component init create failure:%s", err.Error())
logger.Error("component init create failure", event.GetCallbackLoggerOption())
event.GetManager().ReleaseLogger(logger)
return fmt.Errorf("application init create failure")
}
@ -324,8 +321,8 @@ func (m *Manager) verticalScalingExec(task *model.Task) error {
appService.SetUpgradePatch(newAppService)
err = m.controllerManager.StartController(controller.TypeUpgradeController, *newAppService)
if err != nil {
logrus.Errorf("Application run vertical scaling(upgrade) controller failure:%s", err.Error())
logger.Info("Application run vertical scaling(upgrade) controller failure", event.GetCallbackLoggerOption())
logrus.Errorf("component run vertical scaling(upgrade) controller failure:%s", err.Error())
logger.Info("component run vertical scaling(upgrade) controller failure", event.GetCallbackLoggerOption())
event.GetManager().ReleaseLogger(logger)
return fmt.Errorf("application vertical scaling(upgrade) failure")
}
@ -342,10 +339,10 @@ func (m *Manager) rollingUpgradeExec(task *model.Task) error {
logger := event.GetManager().GetLogger(body.EventID)
newAppService, err := conversion.InitAppService(m.dbmanager, body.ServiceID, body.Configs)
if err != nil {
logrus.Errorf("Application init create failure:%s", err.Error())
logger.Error("Application init create failure", event.GetCallbackLoggerOption())
logrus.Errorf("component init create failure:%s", err.Error())
logger.Error("component init create failure", event.GetCallbackLoggerOption())
event.GetManager().ReleaseLogger(logger)
return fmt.Errorf("Application init create failure")
return fmt.Errorf("component init create failure")
}
newAppService.Logger = logger
oldAppService := m.store.GetAppService(body.ServiceID)
@ -355,30 +352,30 @@ func (m *Manager) rollingUpgradeExec(task *model.Task) error {
m.store.RegistAppService(newAppService)
err = m.controllerManager.StartController(controller.TypeStartController, *newAppService)
if err != nil {
logrus.Errorf("Application run start controller failure:%s", err.Error())
logger.Info("Application run start controller failure", event.GetCallbackLoggerOption())
logrus.Errorf("component run start controller failure:%s", err.Error())
logger.Info("component run start controller failure", event.GetCallbackLoggerOption())
event.GetManager().ReleaseLogger(logger)
return fmt.Errorf("Application start failure")
return fmt.Errorf("component start failure")
}
logrus.Infof("service(%s) %s working is running.", body.ServiceID, "start")
return nil
}
if err := oldAppService.SetUpgradePatch(newAppService); err != nil {
if err.Error() == "no upgrade" {
logger.Info("Application no change no need upgrade.", event.GetLastLoggerOption())
logger.Info("component no change no need upgrade.", event.GetLastLoggerOption())
return nil
}
logrus.Errorf("Application get upgrade info error:%s", err.Error())
logger.Error(fmt.Sprintf("Application get upgrade info error:%s", err.Error()), event.GetCallbackLoggerOption())
logrus.Errorf("component get upgrade info error:%s", err.Error())
logger.Error(fmt.Sprintf("component get upgrade info error:%s", err.Error()), event.GetCallbackLoggerOption())
return nil
}
//if service already deploy,upgrade it:
err = m.controllerManager.StartController(controller.TypeUpgradeController, *newAppService)
if err != nil {
logrus.Errorf("Application run upgrade controller failure:%s", err.Error())
logger.Info("Application run upgrade controller failure", event.GetCallbackLoggerOption())
logrus.Errorf("component run upgrade controller failure:%s", err.Error())
logger.Info("component run upgrade controller failure", event.GetCallbackLoggerOption())
event.GetManager().ReleaseLogger(logger)
return fmt.Errorf("Application upgrade failure")
return fmt.Errorf("component upgrade failure")
}
logrus.Infof("service(%s) %s working is running.", body.ServiceID, "upgrade")
return nil
@ -388,7 +385,7 @@ func (m *Manager) applyRuleExec(task *model.Task) error {
body, ok := task.Body.(*model.ApplyRuleTaskBody)
if !ok {
logrus.Errorf("Can't convert %s to *model.ApplyRuleTaskBody", reflect.TypeOf(task.Body))
return fmt.Errorf("Can't convert %s to *model.ApplyRuleTaskBody", reflect.TypeOf(task.Body))
return fmt.Errorf("can't convert %s to *model.ApplyRuleTaskBody", reflect.TypeOf(task.Body))
}
svc, err := db.GetManager().TenantServiceDao().GetServiceByID(body.ServiceID)
if err != nil {
@ -414,10 +411,10 @@ func (m *Manager) applyRuleExec(task *model.Task) error {
newAppService, err = conversion.InitAppService(m.dbmanager, body.ServiceID, nil)
}
if err != nil {
logrus.Errorf("Application init create failure:%s", err.Error())
logger.Error("Application init create failure", event.GetCallbackLoggerOption())
logrus.Errorf("component init create failure:%s", err.Error())
logger.Error("component init create failure", event.GetCallbackLoggerOption())
event.GetManager().ReleaseLogger(logger)
return fmt.Errorf("Application init create failure")
return fmt.Errorf("component init create failure")
}
newAppService.Logger = logger
newAppService.SetDeletedResources(m.store.GetAppService(body.ServiceID))
@ -425,8 +422,8 @@ func (m *Manager) applyRuleExec(task *model.Task) error {
newAppService.CustomParams = body.Limit
err = m.controllerManager.StartController(controller.TypeApplyRuleController, *newAppService)
if err != nil {
logrus.Errorf("Application apply rule controller failure:%s", err.Error())
return fmt.Errorf("Application apply rule controller failure:%s", err.Error())
logrus.Errorf("component apply rule controller failure:%s", err.Error())
return fmt.Errorf("component apply rule controller failure:%s", err.Error())
}
if svc.Kind == dbmodel.ServiceKindThirdParty.String() && strings.HasPrefix(body.Action, "port") {
@ -463,7 +460,7 @@ func (m *Manager) applyPluginConfig(task *model.Task) error {
body, ok := task.Body.(*model.ApplyPluginConfigTaskBody)
if !ok {
logrus.Errorf("Can't convert %s to *model.ApplyPluginConfigTaskBody", reflect.TypeOf(task.Body))
return fmt.Errorf("Can't convert %s to *model.ApplyPluginConfigTaskBody", reflect.TypeOf(task.Body))
return fmt.Errorf("can't convert %s to *model.ApplyPluginConfigTaskBody", reflect.TypeOf(task.Body))
}
oldAppService := m.store.GetAppService(body.ServiceID)
if oldAppService == nil || oldAppService.IsClosed() {
@ -472,13 +469,13 @@ func (m *Manager) applyPluginConfig(task *model.Task) error {
}
newApp, err := conversion.InitAppService(m.dbmanager, body.ServiceID, nil, "ServiceSource", "TenantServiceBase", "TenantServicePlugin")
if err != nil {
logrus.Errorf("Application apply plugin config controller failure:%s", err.Error())
logrus.Errorf("component apply plugin config controller failure:%s", err.Error())
return err
}
err = m.controllerManager.StartController(controller.TypeApplyConfigController, *newApp)
if err != nil {
logrus.Errorf("Application apply plugin config controller failure:%s", err.Error())
return fmt.Errorf("Application apply plugin config controller failure:%s", err.Error())
logrus.Errorf("component apply plugin config controller failure:%s", err.Error())
return fmt.Errorf("component apply plugin config controller failure:%s", err.Error())
}
return nil
}
@ -519,7 +516,7 @@ func (m *Manager) deleteTenant(task *model.Task) (err error) {
tenant.Status = dbmodel.TenantStatusDeleteFailed.String()
err := db.GetManager().TenantDao().UpdateModel(tenant)
if err != nil {
err = fmt.Errorf("update tenant_status to '%s': %v", tenant.Status, err)
logrus.Errorf("update tenant_status to '%s': %v", tenant.Status, err)
return
}
}()
@ -559,18 +556,18 @@ func (m *Manager) ExecRefreshHPATask(task *model.Task) error {
newAppService, err := conversion.InitAppService(m.dbmanager, body.ServiceID, nil)
if err != nil {
logrus.Errorf("Application init create failure:%s", err.Error())
logger.Error("Application init create failure", event.GetCallbackLoggerOption())
logrus.Errorf("component init create failure:%s", err.Error())
logger.Error("component init create failure", event.GetCallbackLoggerOption())
event.GetManager().ReleaseLogger(logger)
return fmt.Errorf("Application init create failure")
return fmt.Errorf("component init create failure")
}
newAppService.Logger = logger
newAppService.SetDeletedResources(oldAppService)
err = m.controllerManager.StartController(controller.TypeControllerRefreshHPA, *newAppService)
if err != nil {
logrus.Errorf("Application run refreshhpa controller failure: %s", err.Error())
logger.Error("Application run refreshhpa controller failure", event.GetCallbackLoggerOption())
logrus.Errorf("component run refreshhpa controller failure: %s", err.Error())
logger.Error("component run refreshhpa controller failure", event.GetCallbackLoggerOption())
event.GetManager().ReleaseLogger(logger)
return fmt.Errorf("refresh hpa: %v", err)
}

View File

@ -20,14 +20,17 @@ package helmapp
import (
"context"
"github.com/goodrain/rainbond/util"
clientset "k8s.io/client-go/kubernetes"
"os"
"path/filepath"
"testing"
"time"
"github.com/goodrain/rainbond/util"
corev1 "k8s.io/api/core/v1"
clientset "k8s.io/client-go/kubernetes"
"github.com/goodrain/rainbond/pkg/generated/clientset/versioned"
"github.com/goodrain/rainbond/pkg/generated/informers/externalversions"
k8sutil "github.com/goodrain/rainbond/util/k8s"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
@ -72,8 +75,10 @@ var _ = BeforeSuite(func() {
rainbondClient = versioned.NewForConfigOrDie(restConfig)
kubeClient = clientset.NewForConfigOrDie(restConfig)
rainbondInformer := externalversions.NewSharedInformerFactoryWithOptions(rainbondClient, 10*time.Second,
externalversions.WithNamespace(corev1.NamespaceAll))
ctrl := NewController(ctx, stopCh, kubeClient, rainbondClient, 5*time.Second, "/tmp/helm/repo/repositories.yaml", "/tmp/helm/cache", "/tmp/helm/chart")
ctrl := NewController(ctx, stopCh, kubeClient, rainbondClient, rainbondInformer.Rainbond().V1alpha1().HelmApps().Informer(), rainbondInformer.Rainbond().V1alpha1().HelmApps().Lister(), "/tmp/helm/repo/repositories.yaml", "/tmp/helm/cache", "/tmp/helm/chart")
go ctrl.Start()
// create namespace

View File

@ -0,0 +1,271 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2021-2021 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package thirdcomponent
import (
"context"
"reflect"
"time"
"github.com/goodrain/rainbond/pkg/apis/rainbond/v1alpha1"
"github.com/oam-dev/kubevela/pkg/utils/apply"
"github.com/sirupsen/logrus"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/client-go/rest"
"k8s.io/client-go/util/retry"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
)
const reconcileTimeOut = 60 * time.Second
type Reconciler struct {
Client client.Client
restConfig *rest.Config
Scheme *runtime.Scheme
concurrentReconciles int
applyer apply.Applicator
discoverPool *DiscoverPool
}
// Reconcile is the main logic of appDeployment controller
func (r *Reconciler) Reconcile(req ctrl.Request) (res reconcile.Result, retErr error) {
log := logrus.WithField("thirdcomponent", req)
commonResult := ctrl.Result{RequeueAfter: time.Second * 5}
component := &v1alpha1.ThirdComponent{}
ctx, cancel := context.WithTimeout(context.TODO(), reconcileTimeOut)
defer cancel()
defer func() {
if retErr == nil {
log.Infof("finished reconciling")
} else {
log.Errorf("Failed to reconcile %v", retErr)
}
}()
if err := r.Client.Get(ctx, req.NamespacedName, component); err != nil {
if apierrors.IsNotFound(err) {
log.Infof("thirdcomponent %s does not exist", req)
}
return ctrl.Result{}, client.IgnoreNotFound(err)
}
if component.DeletionTimestamp != nil {
log.Infof("component %s will be deleted", req)
return ctrl.Result{}, nil
}
logrus.Infof("start to reconcile component %s/%s", component.Namespace, component.Name)
discover, err := NewDiscover(component, r.restConfig)
if err != nil {
component.Status.Phase = v1alpha1.ComponentFailed
component.Status.Reason = err.Error()
r.updateStatus(ctx, component)
return ctrl.Result{}, nil
}
if discover == nil {
component.Status.Phase = v1alpha1.ComponentFailed
component.Status.Reason = "third component source not support"
r.updateStatus(ctx, component)
return ctrl.Result{}, nil
}
endpoints, err := discover.DiscoverOne(ctx)
if err != nil {
component.Status.Phase = v1alpha1.ComponentFailed
component.Status.Reason = err.Error()
r.updateStatus(ctx, component)
return commonResult, nil
}
r.discoverPool.AddDiscover(discover)
if len(endpoints) == 0 {
component.Status.Phase = v1alpha1.ComponentPending
component.Status.Reason = "endpoints not found"
r.updateStatus(ctx, component)
return commonResult, nil
}
// create endpoints for service
if len(component.Spec.Ports) > 0 && len(component.Status.Endpoints) > 0 {
var services corev1.ServiceList
selector, err := labels.Parse(labels.FormatLabels(map[string]string{
"service_id": component.Labels["service_id"],
}))
if err != nil {
logrus.Errorf("create selector failure %s", err.Error())
return commonResult, err
}
err = r.Client.List(ctx, &services, &client.ListOptions{LabelSelector: selector})
if err != nil {
return commonResult, nil
}
log.Infof("list component service success, size:%d", len(services.Items))
if len(services.Items) == 0 {
log.Warning("component service is empty")
return commonResult, nil
}
// init component port
var portMap = make(map[int][]*v1alpha1.ThirdComponentEndpointStatus)
for _, end := range component.Status.Endpoints {
portMap[end.Address.GetPort()] = append(portMap[end.Address.GetPort()], end)
}
// create endpoint for component service
for _, service := range services.Items {
for _, port := range service.Spec.Ports {
// if component port not exist in endpoint port list, ignore it.
if sourceEndpoint, ok := portMap[int(port.Port)]; ok {
endpoint := createEndpoint(component, &service, sourceEndpoint, int(port.Port))
var old corev1.Endpoints
var apply = true
if err := r.Client.Get(ctx, types.NamespacedName{Namespace: endpoint.Namespace, Name: endpoint.Name}, &old); err == nil {
// no change not apply
if reflect.DeepEqual(old.Subsets, endpoint.Subsets) {
apply = false
}
}
if apply {
if err := r.applyer.Apply(ctx, &endpoint); err != nil {
log.Errorf("apply endpoint for service %s failure %s", service.Name, err.Error())
}
log.Infof("apply endpoint for service %s success", service.Name)
}
}
}
}
}
component.Status.Endpoints = endpoints
component.Status.Phase = v1alpha1.ComponentRunning
if err := r.updateStatus(ctx, component); err != nil {
log.Errorf("update status failure %s", err.Error())
return commonResult, nil
}
return reconcile.Result{}, nil
}
func createEndpoint(component *v1alpha1.ThirdComponent, service *corev1.Service, sourceEndpoint []*v1alpha1.ThirdComponentEndpointStatus, port int) corev1.Endpoints {
endpoints := corev1.Endpoints{
TypeMeta: metav1.TypeMeta{
Kind: "Endpoints",
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: service.Name,
Namespace: service.Namespace,
Labels: service.Labels,
},
Subsets: func() []corev1.EndpointSubset {
return []corev1.EndpointSubset{
{
Ports: func() (re []corev1.EndpointPort) {
for _, servicePort := range service.Spec.Ports {
re = append(re, corev1.EndpointPort{
Name: servicePort.Name,
Port: servicePort.Port,
Protocol: servicePort.Protocol,
AppProtocol: servicePort.AppProtocol,
})
}
return
}(),
Addresses: func() (re []corev1.EndpointAddress) {
for _, se := range sourceEndpoint {
if se.Status == v1alpha1.EndpointReady {
re = append(re, corev1.EndpointAddress{
IP: se.Address.GetIP(),
TargetRef: &corev1.ObjectReference{
Namespace: component.Namespace,
Name: component.Name,
Kind: component.Kind,
APIVersion: component.APIVersion,
UID: component.UID,
ResourceVersion: component.ResourceVersion,
},
})
}
}
return
}(),
NotReadyAddresses: func() (re []corev1.EndpointAddress) {
for _, se := range sourceEndpoint {
if se.Status == v1alpha1.EndpointNotReady {
re = append(re, corev1.EndpointAddress{
IP: se.Address.GetIP(),
TargetRef: &corev1.ObjectReference{
Namespace: component.Namespace,
Name: component.Name,
Kind: component.Kind,
APIVersion: component.APIVersion,
UID: component.UID,
ResourceVersion: component.ResourceVersion,
},
})
}
}
return
}(),
},
}
}(),
}
return endpoints
}
// UpdateStatus updates ThirdComponent's Status with retry.RetryOnConflict
func (r *Reconciler) updateStatus(ctx context.Context, appd *v1alpha1.ThirdComponent, opts ...client.UpdateOption) error {
status := appd.DeepCopy().Status
return retry.RetryOnConflict(retry.DefaultBackoff, func() (err error) {
if err = r.Client.Get(ctx, client.ObjectKey{Namespace: appd.Namespace, Name: appd.Name}, appd); err != nil {
return
}
if status.Endpoints == nil {
status.Endpoints = []*v1alpha1.ThirdComponentEndpointStatus{}
}
appd.Status = status
return r.Client.Status().Update(ctx, appd, opts...)
})
}
// SetupWithManager setup the controller with manager
func (r *Reconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
WithOptions(controller.Options{
MaxConcurrentReconciles: r.concurrentReconciles,
}).
For(&v1alpha1.ThirdComponent{}).
Complete(r)
}
// Setup adds a controller that reconciles AppDeployment.
func Setup(ctx context.Context, mgr ctrl.Manager) error {
applyer := apply.NewAPIApplicator(mgr.GetClient())
r := &Reconciler{
Client: mgr.GetClient(),
restConfig: mgr.GetConfig(),
Scheme: mgr.GetScheme(),
applyer: applyer,
}
dp := NewDiscoverPool(ctx, r)
r.discoverPool = dp
return r.SetupWithManager(mgr)
}

View File

@ -0,0 +1,147 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2021-2021 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package thirdcomponent
import (
"context"
"fmt"
"time"
"github.com/goodrain/rainbond/pkg/apis/rainbond/v1alpha1"
"github.com/sirupsen/logrus"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
)
type Discover interface {
GetComponent() *v1alpha1.ThirdComponent
DiscoverOne(ctx context.Context) ([]*v1alpha1.ThirdComponentEndpointStatus, error)
Discover(ctx context.Context, update chan *v1alpha1.ThirdComponent) ([]*v1alpha1.ThirdComponentEndpointStatus, error)
}
func NewDiscover(component *v1alpha1.ThirdComponent, restConfig *rest.Config) (Discover, error) {
if component.Spec.EndpointSource.KubernetesService != nil {
clientset, err := kubernetes.NewForConfig(restConfig)
if err != nil {
logrus.Errorf("create kube client error: %s", err.Error())
return nil, err
}
return &kubernetesDiscover{
component: component,
client: clientset,
}, nil
}
return nil, fmt.Errorf("not support source type")
}
type kubernetesDiscover struct {
component *v1alpha1.ThirdComponent
client *kubernetes.Clientset
}
func (k *kubernetesDiscover) GetComponent() *v1alpha1.ThirdComponent {
return k.component
}
func (k *kubernetesDiscover) getNamespace() string {
component := k.component
namespace := component.Spec.EndpointSource.KubernetesService.Namespace
if namespace == "" {
namespace = component.Namespace
}
return namespace
}
func (k *kubernetesDiscover) Discover(ctx context.Context, update chan *v1alpha1.ThirdComponent) ([]*v1alpha1.ThirdComponentEndpointStatus, error) {
namespace := k.getNamespace()
component := k.component
service, err := k.client.CoreV1().Services(namespace).Get(ctx, component.Spec.EndpointSource.KubernetesService.Name, metav1.GetOptions{})
if err != nil {
return nil, fmt.Errorf("load kubernetes service failure %s", err.Error())
}
re, err := k.client.CoreV1().Endpoints(namespace).Watch(ctx, metav1.ListOptions{LabelSelector: labels.FormatLabels(service.Spec.Selector)})
if err != nil {
return nil, fmt.Errorf("watch kubernetes endpoints failure %s", err.Error())
}
defer re.Stop()
for {
select {
case <-ctx.Done():
return nil, nil
case <-re.ResultChan():
func() {
ctx, cancel := context.WithTimeout(ctx, time.Second*10)
defer cancel()
endpoints, err := k.DiscoverOne(ctx)
if err == nil {
new := component.DeepCopy()
new.Status.Endpoints = endpoints
update <- new
} else {
logrus.Errorf("discover kubernetes endpoints %s change failure %s", component.Spec.EndpointSource.KubernetesService.Name, err.Error())
}
}()
return k.DiscoverOne(ctx)
}
}
}
func (k *kubernetesDiscover) DiscoverOne(ctx context.Context) ([]*v1alpha1.ThirdComponentEndpointStatus, error) {
component := k.component
namespace := k.getNamespace()
service, err := k.client.CoreV1().Services(namespace).Get(ctx, component.Spec.EndpointSource.KubernetesService.Name, metav1.GetOptions{})
if err != nil {
return nil, fmt.Errorf("load kubernetes service failure %s", err.Error())
}
endpoints, err := k.client.CoreV1().Endpoints(namespace).List(ctx, metav1.ListOptions{LabelSelector: labels.FormatLabels(service.Spec.Selector)})
if err != nil {
if apierrors.IsNotFound(err) {
return nil, nil
}
return nil, fmt.Errorf("load kubernetes endpoints failure %s", err.Error())
}
var es = []*v1alpha1.ThirdComponentEndpointStatus{}
for _, endpoint := range endpoints.Items {
for _, subset := range endpoint.Subsets {
for _, port := range subset.Ports {
for _, address := range subset.Addresses {
ed := v1alpha1.NewEndpointAddress(address.IP, int(port.Port))
if ed != nil {
es = append(es, &v1alpha1.ThirdComponentEndpointStatus{
Address: *ed,
TargetRef: address.TargetRef,
Status: v1alpha1.EndpointReady,
})
}
}
for _, address := range subset.NotReadyAddresses {
ed := v1alpha1.NewEndpointAddress(address.IP, int(port.Port))
if ed != nil {
es = append(es, &v1alpha1.ThirdComponentEndpointStatus{
Address: *ed,
TargetRef: address.TargetRef,
Status: v1alpha1.EndpointReady,
})
}
}
}
}
}
return es, nil
}

View File

@ -0,0 +1,158 @@
// RAINBOND, Application Management Platform
// Copyright (C) 2021-2021 Goodrain Co., Ltd.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. For any non-GPL usage of Rainbond,
// one or multiple Commercial Licenses authorized by Goodrain Co., Ltd.
// must be obtained first.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package thirdcomponent
import (
"context"
"reflect"
"sync"
"time"
"github.com/goodrain/rainbond/pkg/apis/rainbond/v1alpha1"
"github.com/sirupsen/logrus"
"sigs.k8s.io/controller-runtime/pkg/client"
)
type DiscoverPool struct {
ctx context.Context
lock sync.Mutex
discoverWorker map[string]*Worker
updateChan chan *v1alpha1.ThirdComponent
reconciler *Reconciler
}
func NewDiscoverPool(ctx context.Context, reconciler *Reconciler) *DiscoverPool {
dp := &DiscoverPool{
ctx: ctx,
discoverWorker: make(map[string]*Worker),
updateChan: make(chan *v1alpha1.ThirdComponent, 1024),
reconciler: reconciler,
}
go dp.Start()
return dp
}
func (d *DiscoverPool) Start() {
logrus.Infof("third component discover pool started")
for {
select {
case <-d.ctx.Done():
logrus.Infof("third component discover pool stoped")
return
case component := <-d.updateChan:
func() {
ctx, cancel := context.WithTimeout(d.ctx, time.Second*10)
defer cancel()
var old v1alpha1.ThirdComponent
name := client.ObjectKey{Name: component.Name, Namespace: component.Namespace}
d.reconciler.Client.Get(ctx, name, &old)
if !reflect.DeepEqual(component.Status.Endpoints, old.Status.Endpoints) {
if err := d.reconciler.updateStatus(ctx, component); err != nil {
logrus.Errorf("update component status failure", err.Error())
}
logrus.Infof("update component %s status success by discover pool", name)
} else {
logrus.Debugf("component %s status endpoints not change", name)
}
}()
}
}
}
type Worker struct {
discover Discover
cancel context.CancelFunc
ctx context.Context
updateChan chan *v1alpha1.ThirdComponent
stoped bool
}
func (w *Worker) Start() {
defer func() {
logrus.Infof("discover endpoint list worker %s/%s stoed", w.discover.GetComponent().Namespace, w.discover.GetComponent().Name)
w.stoped = true
}()
w.stoped = false
logrus.Infof("discover endpoint list worker %s/%s started", w.discover.GetComponent().Namespace, w.discover.GetComponent().Name)
for {
w.discover.Discover(w.ctx, w.updateChan)
select {
case <-w.ctx.Done():
return
default:
}
}
}
func (w *Worker) UpdateDiscover(discover Discover) {
w.discover = discover
}
func (w *Worker) Stop() {
w.cancel()
}
func (w *Worker) IsStop() bool {
return w.stoped
}
func (d *DiscoverPool) newWorker(dis Discover) *Worker {
ctx, cancel := context.WithCancel(d.ctx)
return &Worker{
ctx: ctx,
discover: dis,
cancel: cancel,
updateChan: d.updateChan,
}
}
func (d *DiscoverPool) AddDiscover(dis Discover) {
d.lock.Lock()
defer d.lock.Unlock()
component := dis.GetComponent()
if component == nil {
return
}
key := component.Namespace + component.Name
olddis, exist := d.discoverWorker[key]
if exist {
olddis.UpdateDiscover(dis)
if olddis.IsStop() {
go olddis.Start()
}
return
}
worker := d.newWorker(dis)
go worker.Start()
d.discoverWorker[key] = worker
}
func (d *DiscoverPool) RemoveDiscover(dis Discover) {
d.lock.Lock()
defer d.lock.Unlock()
component := dis.GetComponent()
if component == nil {
return
}
key := component.Namespace + component.Name
olddis, exist := d.discoverWorker[key]
if exist {
olddis.Stop()
}
}

View File

@ -27,10 +27,12 @@ import (
"github.com/goodrain/rainbond/cmd/worker/option"
"github.com/goodrain/rainbond/db"
"github.com/goodrain/rainbond/db/model"
"github.com/goodrain/rainbond/pkg/common"
"github.com/goodrain/rainbond/pkg/generated/clientset/versioned"
"github.com/goodrain/rainbond/util/leader"
"github.com/goodrain/rainbond/worker/appm/store"
"github.com/goodrain/rainbond/worker/master/helmapp"
"github.com/goodrain/rainbond/worker/master/controller/helmapp"
"github.com/goodrain/rainbond/worker/master/controller/thirdcomponent"
"github.com/goodrain/rainbond/worker/master/podevent"
"github.com/goodrain/rainbond/worker/master/volumes/provider"
"github.com/goodrain/rainbond/worker/master/volumes/provider/lib/controller"
@ -40,6 +42,8 @@ import (
"github.com/sirupsen/logrus"
"k8s.io/apimachinery/pkg/version"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
ctrl "sigs.k8s.io/controller-runtime"
)
//Controller app runtime master controller
@ -70,10 +74,11 @@ type Controller struct {
version *version.Info
rainbondsssc controller.Provisioner
rainbondsslc controller.Provisioner
mgr ctrl.Manager
}
//NewMasterController new master controller
func NewMasterController(conf option.Config, store store.Storer, kubeClient kubernetes.Interface, rainbondClient versioned.Interface) (*Controller, error) {
func NewMasterController(conf option.Config, store store.Storer, kubeClient kubernetes.Interface, rainbondClient versioned.Interface, restConfig *rest.Config) (*Controller, error) {
ctx, cancel := context.WithCancel(context.Background())
// The controller needs to know what the server version is because out-of-tree
@ -99,6 +104,17 @@ func NewMasterController(conf option.Config, store store.Storer, kubeClient kube
}, serverVersion.GitVersion)
stopCh := make(chan struct{})
mgr, err := ctrl.NewManager(restConfig, ctrl.Options{
Scheme: common.Scheme,
LeaderElection: false,
LeaderElectionID: "controllers.rainbond.io",
})
if err != nil {
cancel()
return nil, err
}
thirdcomponent.Setup(ctx, mgr)
helmAppController := helmapp.NewController(ctx, stopCh, kubeClient, rainbondClient,
store.Informer().HelmApp, store.Lister().HelmApp, conf.Helm.RepoFile, conf.Helm.RepoCache, conf.Helm.RepoCache)
@ -111,6 +127,7 @@ func NewMasterController(conf option.Config, store store.Storer, kubeClient kube
cancel: cancel,
ctx: ctx,
dbmanager: db.GetManager(),
mgr: mgr,
memoryUse: prometheus.NewGaugeVec(prometheus.GaugeOpts{
Namespace: "app_resource",
Name: "appmemory",
@ -187,11 +204,17 @@ func (m *Controller) Start() error {
// helm app controller
go m.helmAppController.Start()
defer m.helmAppController.Stop()
// start controller
stopchan := make(chan struct{})
go m.mgr.Start(stopchan)
defer func() { stopchan <- struct{}{} }()
select {
case <-ctx.Done():
case <-m.ctx.Done():
}
}
// Leader election was requested.
if m.conf.LeaderElectionNamespace == "" {