Skip to content

Commit

Permalink
update steps
Browse files Browse the repository at this point in the history
Signed-off-by: richardli1598 <[email protected]>
  • Loading branch information
richardli1598 committed Oct 7, 2023
1 parent de88d2e commit 05f2310
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 159 deletions.
14 changes: 6 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

Take you to the land of light, the city of freedom(A unified external service management system for NAS).

## 场景抽象

对于公网服务暴露,存在如下场景:
无公网:
1. 本地安装frpc,本地frpc配置/长期运行
Expand All @@ -17,11 +19,9 @@ Take you to the land of light, the city of freedom(A unified external service ma
2.
3. 域名配置

对于步骤1,2,3;每个步骤都可以抽象化,定义独立的行为,抽象模型如下:
1. 本地配置
2. 服务端配置
3. 域名配置
从上面可以发现,都是一个一个步骤的抽象,上一个步骤完成,然后执行下一个步骤。所以,本质上是一个工作流的处理,携带着各种参数。

所以,本质上两种资源:步骤,和网站的服务流,服务类由一个一个步骤抽象组成。定义如下:

# demo
步骤1
Expand Down Expand Up @@ -81,7 +81,7 @@ full workflow demo:
name: exposeLocalService
kind: ServiceExpose
description: xxx
LocalConfiguration:
configurationSteps:
- use: xxx
name: frpInstall
in:
Expand All @@ -90,13 +90,11 @@ LocalConfiguration:
- use: xxx
in: |
ip: frpInstall.out.xxx
RemoteConfiguration:
- use: xxx
name: xxx
with:
- xxx: xxx.out.xxx
DNSConfiguration:
use: xxx
- use: xxx
with:
-name: xxx
```
9 changes: 9 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

# 1. Start docker service
systemctl start docker

# 2. Start mysql server
service mysql start

# 3. Start bifrost
30 changes: 8 additions & 22 deletions pkg/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,7 @@ limitations under the License.

package api

const (
LocalStepType string = "local"
RemoteStepType string = "remote"
DNSStepType string = "dns"
)

type LocalConfigDefinition ConfigStepDefinition
type RemoteConfigDefinition ConfigStepDefinition
type DNSConfigDefinition ConfigStepDefinition

type ConfigStepDefinition struct {
type ConfigurationStepDefinition struct {
Name string `json:"name"`
Description string `json:"description"`
Image string `json:"image"`
Expand Down Expand Up @@ -54,12 +44,10 @@ type ParameterDefinition struct {
}

type ConfigurationWorkflow struct {
Name string `json:"name"`
Description string `json:"description"`
LocalConfigurationSteps []ConfigurationStep `json:"localConfigurationSteps"`
RemoteConfigurationSteps []ConfigurationStep `json:"remoteConfigurationSteps"`
DNSConfigurationSteps []ConfigurationStep `json:"dnsConfigurationSteps"`
Status ConfigurationWorkflowStatus `json:"status,omitempty"`
Name string `json:"name"`
Description string `json:"description"`
ConfigurationSteps []ConfigurationStep `json:"configurationSteps"`
Status ConfigurationWorkflowStatus `json:"status,omitempty"`
}

type ConfigurationStep struct {
Expand All @@ -81,11 +69,9 @@ const (
)

type ConfigurationWorkflowStatus struct {
State ConfigurationWorkflowState `json:"state"`
Message string `json:"message"`
LocalConfigurationSteps []ConfigurationStepStatus `json:"LocalConfigurationSteps"`
RemoteConfigurationSteps []ConfigurationStepStatus `json:"RemoteConfigurationSteps"`
DNSConfigurationSteps []ConfigurationStepStatus `json:"DNSConfigurationSteps"`
State ConfigurationWorkflowState `json:"state"`
Message string `json:"message"`
ConfigurationSteps []ConfigurationStepStatus `json:"configurationSteps"`
}

type ConfigurationStepStatus struct {
Expand Down
8 changes: 7 additions & 1 deletion pkg/container/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,15 @@ func CreateContainer(workflowName, stepName, image string) (string, error) {
}
resp, err := cli.ContainerCreate(context.Background(), &container.Config{
Image: image,
Tty: false}, nil, nil, nil, "")
Tty: false}, nil, nil, nil, "bifrost-"+workflowName+"-"+stepName)
if err != nil {
return "", err
}
err = cli.ContainerStart(context.Background(), resp.ID, types.ContainerStartOptions{})
if err != nil {
// Ignore the error, we can't do anything
cli.ContainerRemove(context.Background(), resp.ID, types.ContainerRemoveOptions{Force: true})

Check failure on line 29 in pkg/container/create.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `cli.ContainerRemove` is not checked (errcheck)
return "", err
}
return resp.ID, nil
}
8 changes: 4 additions & 4 deletions pkg/controller/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func (w *WorkflowQueue) Run() {
for {
w.mutex.Lock()
defer w.mutex.Unlock()

Check failure on line 57 in pkg/controller/workflow.go

View workflow job for this annotation

GitHub Actions / lint

SA5003: defers in this infinite loop will never run (staticcheck)
for name, _ := range w.Workflow {
for name := range w.Workflow {
requeue, err := w.Reconcile(name)
if err == nil && !requeue {
delete(w.Workflow, name)
Expand Down Expand Up @@ -84,8 +84,8 @@ func (w *WorkflowQueue) Reconcile(name string) (requeue bool, err error) {
}

func (w *WorkflowQueue) DeleteWorkflow(wf *api.ConfigurationWorkflow) (requeue bool, err error) {
for index, step := range wf.DNSConfigurationSteps {
stepState := wf.Status.DNSConfigurationSteps[index]
for index, step := range wf.ConfigurationSteps {
stepState := wf.Status.ConfigurationSteps[index]

if stepState.State == api.ConfigurationWorkflowStateRunning || stepState.State == api.ConfigurationWorkflowStateRunningSuccess {
err := container.DeleteContainer(stepState.ContainerId)
Expand All @@ -109,7 +109,7 @@ func (w *WorkflowQueue) DeleteWorkflow(wf *api.ConfigurationWorkflow) (requeue b
}
}

stepDef := customapi.GetDNSStepDefinition(step.Use)
stepDef := customapi.GetStepDefinition(step.Use)
if stepDef == nil {
return false, fmt.Errorf("dns step definition %s not found", step.Use)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,20 @@
package remotesteps
/*
Copyright 2023 The opennaslab 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 applicabl e 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.
*/

package customapi

import "fmt"

Expand Down
File renamed without changes.
89 changes: 22 additions & 67 deletions pkg/customapi/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,56 +6,40 @@ import (
"reflect"

"opennaslab.io/bifrost/pkg/api"
localsteps "opennaslab.io/bifrost/pkg/customapi/localsteps"
remotesteps "opennaslab.io/bifrost/pkg/customapi/remotesteps"
)

var LocalStepsInfoMap = map[string]StepsInfo{
var StepsInfoMap = map[string]StepsInfo{
"frpc-config": {
Name: "frpc-config",
Image: "opennaslab/frpc-config:latest",
Description: "install/config frpc in local host",
Description: "install/config frpc in remote host",
},
}

var RemoteStepsInfoMap = map[string]StepsInfo{
"docker-config": {
Name: "docker-config",
Image: "opennaslan/docker-config:latest",
Description: "install/config docker in remote host",
},
}

var DNSStepsInfoMap = map[string]StepsInfo{}

type TypedInterface interface {
Validate() error
}

var LocalStepsStruct = map[string]TypedInterface{
"frpc-config": localsteps.FrpcParameterIn{Service: []localsteps.FrpService{{}}},
var StepsStruct = map[string]TypedInterface{
"frpc-config": FrpcParameterIn{Service: []FrpService{{}}},
"docker-config": DockerConfigParameterIn{},
}

var RemoteStepsStruct = map[string]TypedInterface{
"docker-config": remotesteps.DockerConfigParameterIn{},
}

var DNSStepsStruct = map[string]TypedInterface{}

func GetTypedConfig(stepType string, step *api.ConfigurationStep) (TypedInterface, error) {
if stepType == api.LocalStepType {
if _, ok := LocalStepsStruct[step.Use]; !ok {
return nil, fmt.Errorf("not found")
}
// TODO: there is currency problem
ret := LocalStepsStruct[step.Use]
if err := json.Unmarshal([]byte(step.In), ret); err != nil {
return nil, err
}
return ret, nil
func GetTypedConfig(step *api.ConfigurationStep) (TypedInterface, error) {
if _, ok := StepsStruct[step.Use]; !ok {
return nil, fmt.Errorf("not found")
}

return nil, fmt.Errorf("not found")
// TODO: there is currency problem
ret := StepsStruct[step.Use]
if err := json.Unmarshal([]byte(step.In), ret); err != nil {
return nil, err
}
return ret, nil
}

type Documentation struct {
Expand Down Expand Up @@ -105,50 +89,21 @@ type StepParameter struct {
In []Documentation `json:"in"`
}

func GetLocalStepDefinition(name string) *StepsInfo {
if _, ok := LocalStepsInfoMap[name]; !ok {
return nil
}
paraInDoc := GenerateDocumentation(LocalStepsStruct[name])
ret := LocalStepsInfoMap[name]
ret.Parameters.In = paraInDoc
return &ret
}

func GetRemoteStepDefinition(name string) *StepsInfo {
if _, ok := RemoteStepsInfoMap[name]; !ok {
func GetStepDefinition(name string) *StepsInfo {
if _, ok := StepsInfoMap[name]; !ok {
return nil
}
paraInDoc := GenerateDocumentation(RemoteStepsStruct[name])
ret := RemoteStepsInfoMap[name]
paraInDoc := GenerateDocumentation(StepsStruct[name])
ret := StepsInfoMap[name]
ret.Parameters.In = paraInDoc
return &ret
}

func GetDNSStepDefinition(name string) *StepsInfo {
if _, ok := DNSStepsInfoMap[name]; !ok {
return nil
}
ret := DNSStepsInfoMap[name]
return &ret
}

func ListLocalStepDefinitions() []StepsInfo {
ret := []StepsInfo{}
for name := range LocalStepsInfoMap {
paraInDoc := GenerateDocumentation(LocalStepsStruct[name])
ele := LocalStepsInfoMap[name]
ele.Parameters.In = paraInDoc
ret = append(ret, ele)
}
return ret
}

func ListRemoteStepDefinitions() []StepsInfo {
func ListStepDefinitions() []StepsInfo {
ret := []StepsInfo{}
for name := range RemoteStepsInfoMap {
paraInDoc := GenerateDocumentation(RemoteStepsStruct[name])
ele := RemoteStepsInfoMap[name]
for name := range StepsInfoMap {
paraInDoc := GenerateDocumentation(StepsStruct[name])
ele := StepsInfoMap[name]
ele.Parameters.In = paraInDoc
ret = append(ret, ele)
}
Expand Down
58 changes: 10 additions & 48 deletions pkg/server/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,52 +28,26 @@ import (
"opennaslab.io/bifrost/pkg/database"
)

func ListLocalStepsHandler(ctx *gin.Context) {
steps := customapi.ListLocalStepDefinitions()
func ListStepsHandler(ctx *gin.Context) {
steps := customapi.ListStepDefinitions()
respData, err := json.Marshal(steps)
if err != nil {
klog.Errorf("Marshal local steps failed:%v", err)
klog.Errorf("Marshal steps failed:%v", err)
ctx.AbortWithError(http.StatusInternalServerError, err)

Check failure on line 36 in pkg/server/handler.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `ctx.AbortWithError` is not checked (errcheck)
return
}
ctx.Data(http.StatusOK, "application/json", respData)
}

func ListRemoteStepsHandler(ctx *gin.Context) {
steps := customapi.ListRemoteStepDefinitions()
respData, err := json.Marshal(steps)
if err != nil {
klog.Errorf("Marshal remote steps failed:%v", err)
ctx.AbortWithError(http.StatusInternalServerError, err)
return
}
ctx.Data(http.StatusOK, "application/json", respData)
}

func GetLocalStepHandler(ctx *gin.Context) {
name := ctx.Param("name")
step := customapi.GetLocalStepDefinition(name)
if step == nil {
ctx.AbortWithStatus(http.StatusNotFound)
}
respData, err := json.Marshal(step)
if err != nil {
klog.Errorf("Marshal local steps failed:%v", err)
ctx.AbortWithError(http.StatusInternalServerError, err)
return
}
ctx.Data(http.StatusOK, "application/json", respData)
}

func GetRemoteStepHandler(ctx *gin.Context) {
func GetStepHandler(ctx *gin.Context) {
name := ctx.Param("name")
step := customapi.GetRemoteStepDefinition(name)
step := customapi.GetStepDefinition(name)
if step == nil {
ctx.AbortWithStatus(http.StatusNotFound)
}
respData, err := json.Marshal(step)
if err != nil {
klog.Errorf("Marshal remote steps failed:%v", err)
klog.Errorf("Marshal steps failed:%v", err)
ctx.AbortWithError(http.StatusInternalServerError, err)

Check failure on line 51 in pkg/server/handler.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `ctx.AbortWithError` is not checked (errcheck)
return
}
Expand All @@ -83,30 +57,18 @@ func GetRemoteStepHandler(ctx *gin.Context) {
func CreateOrUpdateWorkflowHandler(ctx *gin.Context) {
workflow := &api.ConfigurationWorkflow{}
ctx.BindJSON(workflow)

Check failure on line 59 in pkg/server/handler.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `ctx.BindJSON` is not checked (errcheck)
err := validateSteps(api.LocalStepType, workflow.LocalConfigurationSteps)
if err != nil {
klog.Errorf("Validate local steps failed:%v", err)
ctx.AbortWithError(http.StatusBadRequest, err)
return
}
err = validateSteps(api.RemoteStepType, workflow.RemoteConfigurationSteps)
if err != nil {
klog.Errorf("Validate remote steps failed:%v", err)
ctx.AbortWithError(http.StatusBadRequest, err)
return
}
err = validateSteps(api.DNSStepType, workflow.DNSConfigurationSteps)
err := validateSteps(workflow.ConfigurationSteps)
if err != nil {
klog.Errorf("Validate dns steps failed:%v", err)
klog.Errorf("Validate steps failed:%v", err)
ctx.AbortWithError(http.StatusBadRequest, err)

Check failure on line 63 in pkg/server/handler.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `ctx.AbortWithError` is not checked (errcheck)
return
}
ctx.Data(http.StatusOK, "application/json", []byte("OK"))
}

func validateSteps(stepType string, steps []api.ConfigurationStep) error {
func validateSteps(steps []api.ConfigurationStep) error {
for _, step := range steps {
typedStep, err := customapi.GetTypedConfig(stepType, &step)
typedStep, err := customapi.GetTypedConfig(&step)
if err != nil {
klog.Errorf("Get local step %s failed:%v", step.Use, err)
return err
Expand Down
Loading

0 comments on commit 05f2310

Please sign in to comment.