Add zertier (#1116)
This commit is contained in:
parent
b420a2d930
commit
78b7c6ce09
8 changed files with 448 additions and 22 deletions
|
@ -89,6 +89,52 @@ paths:
|
||||||
$ref: "#/components/responses/ResponseOK"
|
$ref: "#/components/responses/ResponseOK"
|
||||||
"500":
|
"500":
|
||||||
$ref: "#/components/responses/ResponseInternalServerError"
|
$ref: "#/components/responses/ResponseInternalServerError"
|
||||||
|
/zt/info:
|
||||||
|
get:
|
||||||
|
tags:
|
||||||
|
- Zerotier methods
|
||||||
|
summary: Get Zerotier info
|
||||||
|
description: |-
|
||||||
|
Get Zerotier info.
|
||||||
|
operationId: getZerotierInfo
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
$ref: "#/components/responses/GetZTInfoOK"
|
||||||
|
"500":
|
||||||
|
$ref: "#/components/responses/ResponseInternalServerError"
|
||||||
|
/zt/{network_id}/status:
|
||||||
|
put:
|
||||||
|
tags:
|
||||||
|
- Zerotier methods
|
||||||
|
summary: Set Zerotier network status
|
||||||
|
description: |-
|
||||||
|
Set Zerotier network status.
|
||||||
|
operationId: setZerotierNetworkStatus
|
||||||
|
parameters:
|
||||||
|
- name: network_id
|
||||||
|
in: path
|
||||||
|
description: network id
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
status:
|
||||||
|
enum:
|
||||||
|
- online
|
||||||
|
- offline
|
||||||
|
type: string
|
||||||
|
example: "online"
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
$ref: "#/components/responses/GetZTInfoOK"
|
||||||
|
"500":
|
||||||
|
$ref: "#/components/responses/ResponseInternalServerError"
|
||||||
|
|
||||||
components:
|
components:
|
||||||
securitySchemes:
|
securitySchemes:
|
||||||
access_token:
|
access_token:
|
||||||
|
@ -132,6 +178,13 @@ components:
|
||||||
- properties:
|
- properties:
|
||||||
data:
|
data:
|
||||||
$ref: "#/components/schemas/HealthPorts"
|
$ref: "#/components/schemas/HealthPorts"
|
||||||
|
GetZTInfoOK:
|
||||||
|
description: OK
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
$ref: "#/components/schemas/ZTInfo"
|
||||||
|
|
||||||
|
|
||||||
schemas:
|
schemas:
|
||||||
BaseResponse:
|
BaseResponse:
|
||||||
|
@ -169,3 +222,14 @@ components:
|
||||||
type: integer
|
type: integer
|
||||||
example: 53
|
example: 53
|
||||||
x-go-name: UDP
|
x-go-name: UDP
|
||||||
|
ZTInfo:
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
example: "1234567890"
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
example: "CasaOS"
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
example: "online"
|
|
@ -8,10 +8,12 @@ import (
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/deepmap/oapi-codegen/pkg/runtime"
|
||||||
"github.com/getkin/kin-openapi/openapi3"
|
"github.com/getkin/kin-openapi/openapi3"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
)
|
)
|
||||||
|
@ -20,6 +22,12 @@ const (
|
||||||
Access_tokenScopes = "access_token.Scopes"
|
Access_tokenScopes = "access_token.Scopes"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Defines values for SetZerotierNetworkStatusJSONBodyStatus.
|
||||||
|
const (
|
||||||
|
Offline SetZerotierNetworkStatusJSONBodyStatus = "offline"
|
||||||
|
Online SetZerotierNetworkStatusJSONBodyStatus = "online"
|
||||||
|
)
|
||||||
|
|
||||||
// BaseResponse defines model for BaseResponse.
|
// BaseResponse defines model for BaseResponse.
|
||||||
type BaseResponse struct {
|
type BaseResponse struct {
|
||||||
// Message message returned by server side if there is any
|
// Message message returned by server side if there is any
|
||||||
|
@ -38,6 +46,13 @@ type HealthServices struct {
|
||||||
Running *[]string `json:"running,omitempty"`
|
Running *[]string `json:"running,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ZTInfo defines model for ZTInfo.
|
||||||
|
type ZTInfo struct {
|
||||||
|
Id *string `json:"id,omitempty"`
|
||||||
|
Name *string `json:"name,omitempty"`
|
||||||
|
Status *string `json:"status,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// GetHealthPortsOK defines model for GetHealthPortsOK.
|
// GetHealthPortsOK defines model for GetHealthPortsOK.
|
||||||
type GetHealthPortsOK struct {
|
type GetHealthPortsOK struct {
|
||||||
Data *HealthPorts `json:"data,omitempty"`
|
Data *HealthPorts `json:"data,omitempty"`
|
||||||
|
@ -54,12 +69,26 @@ type GetHealthServicesOK struct {
|
||||||
Message *string `json:"message,omitempty"`
|
Message *string `json:"message,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetZTInfoOK defines model for GetZTInfoOK.
|
||||||
|
type GetZTInfoOK = ZTInfo
|
||||||
|
|
||||||
// ResponseInternalServerError defines model for ResponseInternalServerError.
|
// ResponseInternalServerError defines model for ResponseInternalServerError.
|
||||||
type ResponseInternalServerError = BaseResponse
|
type ResponseInternalServerError = BaseResponse
|
||||||
|
|
||||||
// ResponseOK defines model for ResponseOK.
|
// ResponseOK defines model for ResponseOK.
|
||||||
type ResponseOK = BaseResponse
|
type ResponseOK = BaseResponse
|
||||||
|
|
||||||
|
// SetZerotierNetworkStatusJSONBody defines parameters for SetZerotierNetworkStatus.
|
||||||
|
type SetZerotierNetworkStatusJSONBody struct {
|
||||||
|
Status *SetZerotierNetworkStatusJSONBodyStatus `json:"status,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetZerotierNetworkStatusJSONBodyStatus defines parameters for SetZerotierNetworkStatus.
|
||||||
|
type SetZerotierNetworkStatusJSONBodyStatus string
|
||||||
|
|
||||||
|
// SetZerotierNetworkStatusJSONRequestBody defines body for SetZerotierNetworkStatus for application/json ContentType.
|
||||||
|
type SetZerotierNetworkStatusJSONRequestBody SetZerotierNetworkStatusJSONBody
|
||||||
|
|
||||||
// ServerInterface represents all server handlers.
|
// ServerInterface represents all server handlers.
|
||||||
type ServerInterface interface {
|
type ServerInterface interface {
|
||||||
// Test file methods
|
// Test file methods
|
||||||
|
@ -74,6 +103,12 @@ type ServerInterface interface {
|
||||||
// Get service status
|
// Get service status
|
||||||
// (GET /health/services)
|
// (GET /health/services)
|
||||||
GetHealthServices(ctx echo.Context) error
|
GetHealthServices(ctx echo.Context) error
|
||||||
|
// Get Zerotier info
|
||||||
|
// (GET /zt/info)
|
||||||
|
GetZerotierInfo(ctx echo.Context) error
|
||||||
|
// Set Zerotier network status
|
||||||
|
// (PUT /zt/{network_id}/status)
|
||||||
|
SetZerotierNetworkStatus(ctx echo.Context, networkId string) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// ServerInterfaceWrapper converts echo contexts to parameters.
|
// ServerInterfaceWrapper converts echo contexts to parameters.
|
||||||
|
@ -125,6 +160,35 @@ func (w *ServerInterfaceWrapper) GetHealthServices(ctx echo.Context) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetZerotierInfo converts echo context to params.
|
||||||
|
func (w *ServerInterfaceWrapper) GetZerotierInfo(ctx echo.Context) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
ctx.Set(Access_tokenScopes, []string{""})
|
||||||
|
|
||||||
|
// Invoke the callback with all the unmarshalled arguments
|
||||||
|
err = w.Handler.GetZerotierInfo(ctx)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetZerotierNetworkStatus converts echo context to params.
|
||||||
|
func (w *ServerInterfaceWrapper) SetZerotierNetworkStatus(ctx echo.Context) error {
|
||||||
|
var err error
|
||||||
|
// ------------- Path parameter "network_id" -------------
|
||||||
|
var networkId string
|
||||||
|
|
||||||
|
err = runtime.BindStyledParameterWithLocation("simple", false, "network_id", runtime.ParamLocationPath, ctx.Param("network_id"), &networkId)
|
||||||
|
if err != nil {
|
||||||
|
return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter network_id: %s", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.Set(Access_tokenScopes, []string{""})
|
||||||
|
|
||||||
|
// Invoke the callback with all the unmarshalled arguments
|
||||||
|
err = w.Handler.SetZerotierNetworkStatus(ctx, networkId)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// This is a simple interface which specifies echo.Route addition functions which
|
// This is a simple interface which specifies echo.Route addition functions which
|
||||||
// are present on both echo.Echo and echo.Group, since we want to allow using
|
// are present on both echo.Echo and echo.Group, since we want to allow using
|
||||||
// either of them for path registration
|
// either of them for path registration
|
||||||
|
@ -157,31 +221,36 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
|
||||||
router.GET(baseURL+"/health/logs", wrapper.GetHealthlogs)
|
router.GET(baseURL+"/health/logs", wrapper.GetHealthlogs)
|
||||||
router.GET(baseURL+"/health/ports", wrapper.GetHealthPorts)
|
router.GET(baseURL+"/health/ports", wrapper.GetHealthPorts)
|
||||||
router.GET(baseURL+"/health/services", wrapper.GetHealthServices)
|
router.GET(baseURL+"/health/services", wrapper.GetHealthServices)
|
||||||
|
router.GET(baseURL+"/zt/info", wrapper.GetZerotierInfo)
|
||||||
|
router.PUT(baseURL+"/zt/:network_id/status", wrapper.SetZerotierNetworkStatus)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base64 encoded, gzipped, json marshaled Swagger object
|
// Base64 encoded, gzipped, json marshaled Swagger object
|
||||||
var swaggerSpec = []string{
|
var swaggerSpec = []string{
|
||||||
|
|
||||||
"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",
|
||||||
"DgAA",
|
"vBc9jixrJDqqLMe3dLk2wJcWzyc6qcOVESurHplOuhXa79oZ2BbsZCXYHz70ZDFXpUJVAANSc3NdL7LI",
|
||||||
|
"qxMZeBfnzo+Vh1vhbebgU6URksXtYrXBbW5nYx8MxC9tMn/QNWzdBnfMqqkKJ+7SqtrZrPk3Du5jZJcj",
|
||||||
|
"dvoRYm6t7be2qm6Z8zvWV8enN9O87tDPxm5K/EXSL4MKcxnJ8GKv9WXSBbQFNhfJk9Oj10c7q0Wx0fV1",
|
||||||
|
"cNcHa2exK3S1yyo9QFuVvl4b9/vWKb61wYzrfwMAAP//9tkexLESAAA=",
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSwagger returns the content of the embedded swagger specification file
|
// GetSwagger returns the content of the embedded swagger specification file
|
||||||
|
|
|
@ -4,4 +4,5 @@ const (
|
||||||
SERVICENAME = "casaos"
|
SERVICENAME = "casaos"
|
||||||
VERSION = "0.4.4"
|
VERSION = "0.4.4"
|
||||||
BODY = ""
|
BODY = ""
|
||||||
|
RANW_NAME = "IceWhale-RemoteAccess"
|
||||||
)
|
)
|
||||||
|
|
1
main.go
1
main.go
|
@ -151,6 +151,7 @@ func main() {
|
||||||
"/v1/recover",
|
"/v1/recover",
|
||||||
"/v1/other",
|
"/v1/other",
|
||||||
"/v1/zt",
|
"/v1/zt",
|
||||||
|
"/v1/test",
|
||||||
route.V2APIPath,
|
route.V2APIPath,
|
||||||
route.V2DocPath,
|
route.V2DocPath,
|
||||||
route.V3FilePath,
|
route.V3FilePath,
|
||||||
|
|
78
pkg/utils/httper/zerotier.go
Normal file
78
pkg/utils/httper/zerotier.go
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
package httper
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ZTGet(url string) ([]byte, error) {
|
||||||
|
port, err := ioutil.ReadFile("/var/lib/zerotier-one/zerotier-one.port")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build the target URL
|
||||||
|
targetURL := fmt.Sprintf("http://localhost:%s%s", strings.TrimSpace(string(port)), url)
|
||||||
|
|
||||||
|
// Create a new request
|
||||||
|
req, err := http.NewRequest("GET", targetURL, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the X-ZT1-AUTH header
|
||||||
|
authToken, err := ioutil.ReadFile("/var/lib/zerotier-one/authtoken.secret")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.Header.Set("X-ZT1-AUTH", strings.TrimSpace(string(authToken)))
|
||||||
|
|
||||||
|
client := http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
respBody, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return respBody, nil
|
||||||
|
}
|
||||||
|
func ZTPost(url string, body string) ([]byte, error) {
|
||||||
|
port, err := ioutil.ReadFile("/var/lib/zerotier-one/zerotier-one.port")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// Build the target URL
|
||||||
|
targetURL := fmt.Sprintf("http://localhost:%s%s", strings.TrimSpace(string(port)), url)
|
||||||
|
|
||||||
|
// Create a new request
|
||||||
|
req, err := http.NewRequest("POST", targetURL, strings.NewReader(body))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the X-ZT1-AUTH header
|
||||||
|
authToken, err := ioutil.ReadFile("/var/lib/zerotier-one/authtoken.secret")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
req.Header.Set("X-ZT1-AUTH", strings.TrimSpace(string(authToken)))
|
||||||
|
|
||||||
|
client := http.Client{}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
respBody, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return respBody, nil
|
||||||
|
}
|
|
@ -40,7 +40,7 @@ func InitV1Router() *gin.Engine {
|
||||||
})
|
})
|
||||||
r.GET("/v1/recover/:type", v1.GetRecoverStorage)
|
r.GET("/v1/recover/:type", v1.GetRecoverStorage)
|
||||||
v1Group := r.Group("/v1")
|
v1Group := r.Group("/v1")
|
||||||
r.GET("/v1/zt/*url", v1.AddZerotierToken)
|
r.Any("/v1/test", v1.CheckNetwork)
|
||||||
v1Group.Use(jwt.ExceptLocalhost(func() (*ecdsa.PublicKey, error) { return external.GetPublicKey(config.CommonInfo.RuntimePath) }))
|
v1Group.Use(jwt.ExceptLocalhost(func() (*ecdsa.PublicKey, error) { return external.GetPublicKey(config.CommonInfo.RuntimePath) }))
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -169,6 +169,11 @@ func InitV1Router() *gin.Engine {
|
||||||
v1OtherGroup.GET("/search", v1.GetSearchResult)
|
v1OtherGroup.GET("/search", v1.GetSearchResult)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
v1ZerotierGroup := v1Group.Group("/zt")
|
||||||
|
v1ZerotierGroup.Use()
|
||||||
|
{
|
||||||
|
v1ZerotierGroup.Any("/*url", v1.ZerotierProxy)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return r
|
return r
|
||||||
|
|
|
@ -6,10 +6,13 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/IceWhaleTech/CasaOS/common"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
)
|
)
|
||||||
|
|
||||||
func AddZerotierToken(c *gin.Context) {
|
func ZerotierProxy(c *gin.Context) {
|
||||||
// Read the port number from the file
|
// Read the port number from the file
|
||||||
w := c.Writer
|
w := c.Writer
|
||||||
r := c.Request
|
r := c.Request
|
||||||
|
@ -71,3 +74,136 @@ func copyHeaders(destination, source http.Header) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CheckNetwork(c *gin.Context) {
|
||||||
|
//先获取所有已创建的网络
|
||||||
|
respBody, err := httper.ZTGet("/controller/network")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
networkId := ""
|
||||||
|
address := ""
|
||||||
|
networkNames := gjson.ParseBytes(respBody).Array()
|
||||||
|
for _, v := range networkNames {
|
||||||
|
res, err := httper.ZTGet("/controller/network/" + v.Str)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
name := gjson.GetBytes(res, "name").Str
|
||||||
|
if name == common.RANW_NAME {
|
||||||
|
fmt.Println(string(res))
|
||||||
|
networkId = gjson.GetBytes(res, "id").Str
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(networkId) == 0 {
|
||||||
|
if len(address) == 0 {
|
||||||
|
address = GetAddress()
|
||||||
|
}
|
||||||
|
networkId = CreateNet(address)
|
||||||
|
}
|
||||||
|
res, err := httper.ZTGet("/network")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
joined := false
|
||||||
|
networks := gjson.GetBytes(res, "#.id").Array()
|
||||||
|
for _, v := range networks {
|
||||||
|
if v.Str == networkId {
|
||||||
|
fmt.Println("已加入网络")
|
||||||
|
joined = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !joined {
|
||||||
|
JoinAndUpdateNet(address, networkId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func GetAddress() string {
|
||||||
|
//获取nodeId
|
||||||
|
nodeRes, err := httper.ZTGet("/status")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return gjson.GetBytes(nodeRes, "address").String()
|
||||||
|
}
|
||||||
|
func JoinAndUpdateNet(address, networkId string) {
|
||||||
|
res, err := httper.ZTPost("/network/"+networkId, "")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println(string(res))
|
||||||
|
if len(address) == 0 {
|
||||||
|
address = GetAddress()
|
||||||
|
}
|
||||||
|
b := `{
|
||||||
|
"authorized": true,
|
||||||
|
"activeBridge": true,
|
||||||
|
"ipAssignments": [
|
||||||
|
"10.147.20.1"
|
||||||
|
]
|
||||||
|
}`
|
||||||
|
r, err := httper.ZTPost("/controller/network/"+networkId+"/member/"+address, b)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fmt.Println(string(r))
|
||||||
|
}
|
||||||
|
func CreateNet(address string) string {
|
||||||
|
body := `{
|
||||||
|
"name": "` + common.RANW_NAME + `",
|
||||||
|
"private": false,
|
||||||
|
"v4AssignMode": {
|
||||||
|
"zt": true
|
||||||
|
},
|
||||||
|
"ipAssignmentPools": [
|
||||||
|
{
|
||||||
|
"ipRangeStart": "10.147.20.1",
|
||||||
|
"ipRangeEnd": "10.147.20.254"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"routes": [
|
||||||
|
{
|
||||||
|
"target": "10.147.20.0/24"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"rules": [
|
||||||
|
{
|
||||||
|
"etherType": 2048,
|
||||||
|
"not": true,
|
||||||
|
"or": false,
|
||||||
|
"type": "MATCH_ETHERTYPE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"etherType": 2054,
|
||||||
|
"not": true,
|
||||||
|
"or": false,
|
||||||
|
"type": "MATCH_ETHERTYPE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"etherType": 34525,
|
||||||
|
"not": true,
|
||||||
|
"or": false,
|
||||||
|
"type": "MATCH_ETHERTYPE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ACTION_DROP"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "ACTION_ACCEPT"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}`
|
||||||
|
createRes, err := httper.ZTPost("/controller/network/"+address+"______", body)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return gjson.GetBytes(createRes, "id").Str
|
||||||
|
}
|
||||||
|
|
72
route/v2/zerotier.go
Normal file
72
route/v2/zerotier.go
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
package v2
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/IceWhaleTech/CasaOS-Common/utils"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/codegen"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/common"
|
||||||
|
"github.com/IceWhaleTech/CasaOS/pkg/utils/httper"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/tidwall/gjson"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *CasaOS) SetZerotierNetworkStatus(ctx echo.Context, networkId string) error {
|
||||||
|
ip := `,"via":"10.147.20.256"`
|
||||||
|
status := ctx.Request().PostFormValue("status")
|
||||||
|
if status == "online" {
|
||||||
|
ip = ``
|
||||||
|
}
|
||||||
|
body := `{
|
||||||
|
"routes": [
|
||||||
|
{
|
||||||
|
"target": "10.147.20.0/24"` + ip + `
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}`
|
||||||
|
res, err := httper.ZTPost("/controller/network/"+networkId, body)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return ctx.JSON(http.StatusInternalServerError, codegen.BaseResponse{Message: utils.Ptr(err.Error())})
|
||||||
|
}
|
||||||
|
info := codegen.GetZTInfoOK{}
|
||||||
|
via := gjson.GetBytes(res, "routes.0.via").Str
|
||||||
|
info.Id = utils.Ptr(gjson.GetBytes(res, "id").Str)
|
||||||
|
info.Name = utils.Ptr(gjson.GetBytes(res, "name").Str)
|
||||||
|
if len(via) != 0 {
|
||||||
|
info.Status = utils.Ptr("online")
|
||||||
|
} else {
|
||||||
|
info.Status = utils.Ptr("offline")
|
||||||
|
}
|
||||||
|
return ctx.JSON(http.StatusOK, info)
|
||||||
|
}
|
||||||
|
func (s *CasaOS) GetZerotierInfo(ctx echo.Context) error {
|
||||||
|
info := codegen.GetZTInfoOK{}
|
||||||
|
respBody, err := httper.ZTGet("/controller/network")
|
||||||
|
if err != nil {
|
||||||
|
return ctx.JSON(http.StatusInternalServerError, codegen.BaseResponse{Message: utils.Ptr(err.Error())})
|
||||||
|
}
|
||||||
|
|
||||||
|
networkNames := gjson.ParseBytes(respBody).Array()
|
||||||
|
for _, v := range networkNames {
|
||||||
|
res, err := httper.ZTGet("/controller/network/" + v.Str)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
return ctx.JSON(http.StatusInternalServerError, codegen.BaseResponse{Message: utils.Ptr(err.Error())})
|
||||||
|
}
|
||||||
|
name := gjson.GetBytes(res, "name").Str
|
||||||
|
if name == common.RANW_NAME {
|
||||||
|
via := gjson.GetBytes(res, "routes.0.via").Str
|
||||||
|
info.Id = utils.Ptr(gjson.GetBytes(res, "id").Str)
|
||||||
|
info.Name = &name
|
||||||
|
if len(via) != 0 {
|
||||||
|
info.Status = utils.Ptr("online")
|
||||||
|
} else {
|
||||||
|
info.Status = utils.Ptr("offline")
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ctx.JSON(http.StatusOK, info)
|
||||||
|
}
|
Loading…
Reference in a new issue