Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add docker config remote step #7

Merged
merged 1 commit into from
Oct 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified main
Binary file not shown.
6 changes: 6 additions & 0 deletions pkg/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ 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
Expand Down
82 changes: 60 additions & 22 deletions pkg/customapi/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,56 @@ import (
"reflect"

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

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

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

var TypedInterfaceMap = map[string]TypedInterface{
"frpc-config": &FrpcParameterIn{},
}
var DNSStpesInfoMap = map[string]StepsInfo{}

type TypedInterface interface {
Validate() error
GetExecutionConfig() ([]byte, error)
}

func GetTypedConfig(step *api.ConfigurationStep) (TypedInterface, error) {
if _, ok := TypedInterfaceMap[step.Use]; !ok {
return nil, fmt.Errorf("not found")
}
// TODO: there is currency problem
ret := TypedInterfaceMap[step.Use]
if err := json.Unmarshal([]byte(step.In), ret); err != nil {
return nil, err
var LocalStepsStruct = map[string]TypedInterface{
"frpc-config": localsteps.FrpcParameterIn{Service: []localsteps.FrpService{{}}},
}

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
}
return ret, nil

return nil, fmt.Errorf("not found")
}

type Documentation struct {
Expand Down Expand Up @@ -89,20 +106,41 @@ type StepParameter struct {
}

func GetLocalStepDefinition(name string) *StepsInfo {
if _, ok := StepsInfoMap[name]; !ok {
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 {
return nil
}
paraInDoc := GenerateDocumentation(StepsDocStruct[name])
ret := StepsInfoMap[name]
paraInDoc := GenerateDocumentation(RemoteStepsStruct[name])
ret := RemoteStepsInfoMap[name]
ret.Parameters.In = paraInDoc
return &ret
}

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

func ListRemoteStepDefinitions() []StepsInfo {
ret := []StepsInfo{}
for name := range RemoteStepsInfoMap {
paraInDoc := GenerateDocumentation(RemoteStepsStruct[name])
ele := RemoteStepsInfoMap[name]
ele.Parameters.In = paraInDoc
ret = append(ret, ele)
}
Expand Down
File renamed without changes.
26 changes: 26 additions & 0 deletions pkg/customapi/remotesteps/docker_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package remotesteps

import "fmt"

type DockerConfigParameterIn struct {
ServerAddr string `json:"serverAddr" description:"the vps address" required:"true"`
ServerPort int `json:"serverPort" description:"the vps port" required:"true"`
ServerUser string `json:"serverUser" description:"the vps user" required:"true"`
ServerPassword string `json:"serverPassword" description:"the vps password" required:"true"`
}

func (d DockerConfigParameterIn) Validate() error {
if d.ServerAddr == "" {
return fmt.Errorf("serverAddr is required")
}
if d.ServerPort == 0 {
return fmt.Errorf("serverPort is required")
}
if d.ServerUser == "" {
return fmt.Errorf("serverUser is required")
}
if d.ServerPassword == "" {
return fmt.Errorf("serverPassword is required")
}
return nil
}
60 changes: 54 additions & 6 deletions pkg/server/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ func ListLocalStepsHandler(ctx *gin.Context) {
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)
Expand All @@ -53,20 +64,57 @@ func GetLocalStepHandler(ctx *gin.Context) {
ctx.Data(http.StatusOK, "application/json", respData)
}

func GetRemoteStepHandler(ctx *gin.Context) {
name := ctx.Param("name")
step := customapi.GetRemoteStepDefinition(name)
if step == nil {
ctx.AbortWithStatus(http.StatusNotFound)
}
respData, err := json.Marshal(step)
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 CreateOrUpdateWorkflowHandler(ctx *gin.Context) {
workflow := &api.ConfigurationWorkflow{}
ctx.BindJSON(workflow)
for _, step := range workflow.LocalConfigurationSteps {
typedStep, err := customapi.GetTypedConfig(&step)
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)
if err != nil {
klog.Errorf("Validate dns steps failed:%v", err)
ctx.AbortWithError(http.StatusBadRequest, err)
return
}
ctx.Data(http.StatusOK, "application/json", []byte("OK"))
}

func validateSteps(stepType string, steps []api.ConfigurationStep) error {
for _, step := range steps {
typedStep, err := customapi.GetTypedConfig(stepType, &step)
if err != nil {
klog.Errorf("Get local step %s failed:%v", step.Use, err)
ctx.AbortWithError(http.StatusInternalServerError, err)
return
return err
}
if err := typedStep.Validate(); err != nil {
klog.Errorf("Validate local step %s failed:%v", step.Name, err)
ctx.AbortWithError(http.StatusBadRequest, err)
return err
}
}
ctx.Data(http.StatusOK, "application/json", []byte("OK"))

return nil
}
4 changes: 2 additions & 2 deletions pkg/server/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ func initStepRouter(router *gin.Engine, corsHandler gin.HandlerFunc) {
localStepGroup.GET("/:name", GetLocalStepHandler)

remoteStep := router.Group("/api/v1/remotesteps")
remoteStep.GET("", nil)
remoteStep.GET("", ListRemoteStepsHandler)
// Get specific step
remoteStep.GET("/:name", nil)
remoteStep.GET("/:name", GetRemoteStepHandler)
}

func initWorkflowRouter(router *gin.Engine, corsHandler gin.HandlerFunc) {
Expand Down