Skip to content

Commit b1a148d

Browse files
committed
feat: fully support config file startup
1 parent a54d8c2 commit b1a148d

File tree

10 files changed

+119
-19
lines changed

10 files changed

+119
-19
lines changed

build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ echo "Building frp-panel client only linux binaries..."
2020
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o dist/frp-panel-client-linux-amd64 cmd/frppc/*.go
2121
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o dist/frp-panel-client-linux-arm64 cmd/frppc/*.go
2222
echo "Building frp-panel client only darwin binaries..."
23-
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -o dist/frp-panel-client-darwin-amd64 cmd/frpp/*.go
23+
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -o dist/frp-panel-client-darwin-amd64 cmd/frppc/*.go
2424
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -o dist/frp-panel-client-darwin-arm64 cmd/frppc/*.go
2525

2626
echo "Build Done!"

cmd/frpp/client.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ import (
1313
"github.com/sourcegraph/conc"
1414
)
1515

16-
func runClient(clientID, clientSecret string) {
16+
func runClient() {
17+
var (
18+
clientID = conf.Get().Client.ID
19+
clientSecret = conf.Get().Client.Secret
20+
)
1721
crypto.DefaultSalt = conf.Get().App.Secret
1822
logrus.Infof("start to run client")
1923
if len(clientSecret) == 0 {

cmd/frpp/cmd.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,20 @@ func initCommand() {
3636
Use: "client [-s client secret] [-i client id] [-a app secret] [-r rpc host] [-c rpc port] [-p api port]",
3737
Short: "run managed frpc",
3838
Run: func(cmd *cobra.Command, args []string) {
39-
patchConfig(rpcHost, appSecret, rpcPort, apiPort)
40-
runClient(clientID, clientSecret)
39+
patchConfig(rpcHost, appSecret,
40+
clientID, clientSecret,
41+
apiScheme, rpcPort, apiPort)
42+
runClient()
4143
},
4244
}
4345
serverCmd = &cobra.Command{
4446
Use: "server [-s client secret] [-i client id] [-a app secret] [-r rpc host] [-c rpc port] [-p api port]",
4547
Short: "run managed frps",
4648
Run: func(cmd *cobra.Command, args []string) {
47-
patchConfig(rpcHost, appSecret, rpcPort, apiPort)
48-
runServer(clientID, clientSecret)
49+
patchConfig(rpcHost, appSecret,
50+
clientID, clientSecret,
51+
apiScheme, rpcPort, apiPort)
52+
runServer()
4953
},
5054
}
5155
masterCmd = &cobra.Command{
@@ -82,7 +86,7 @@ func initLogger() {
8286
logrus.SetReportCaller(true)
8387
}
8488

85-
func patchConfig(host, secret string, rpcPort, apiPort int) {
89+
func patchConfig(host, secret, clientID, clientSecret, apiScheme string, rpcPort, apiPort int) {
8690
if len(host) != 0 {
8791
conf.Get().Master.RPCHost = host
8892
conf.Get().Master.APIHost = host
@@ -96,4 +100,13 @@ func patchConfig(host, secret string, rpcPort, apiPort int) {
96100
if apiPort != 0 {
97101
conf.Get().Master.APIPort = apiPort
98102
}
103+
if len(apiScheme) != 0 {
104+
conf.Get().Master.APIScheme = apiScheme
105+
}
106+
if len(clientID) != 0 {
107+
conf.Get().Client.ID = clientID
108+
}
109+
if len(clientSecret) != 0 {
110+
conf.Get().Client.Secret = clientSecret
111+
}
99112
}

cmd/frpp/server.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ import (
1414
"github.com/sourcegraph/conc"
1515
)
1616

17-
func runServer(clientID, clientSecret string) {
17+
func runServer() {
18+
var (
19+
clientID = conf.Get().Client.ID
20+
clientSecret = conf.Get().Client.Secret
21+
)
1822
crypto.DefaultSalt = conf.Get().App.Secret
1923
logrus.Infof("start to run server")
2024

cmd/frppc/client.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ import (
1313
"github.com/sourcegraph/conc"
1414
)
1515

16-
func runClient(clientID, clientSecret string) {
16+
func runClient() {
17+
var (
18+
clientID = conf.Get().Client.ID
19+
clientSecret = conf.Get().Client.Secret
20+
)
1721
crypto.DefaultSalt = conf.Get().App.Secret
1822
logrus.Infof("start to run client")
1923
if len(clientSecret) == 0 {

cmd/frppc/cmd.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,10 @@ func initCommand() {
3434
Use: "client [-s client secret] [-i client id] [-a app secret] [-r rpc host] [-c rpc port] [-p api port]",
3535
Short: "run managed frpc",
3636
Run: func(cmd *cobra.Command, args []string) {
37-
patchConfig(rpcHost, appSecret, rpcPort, apiPort)
38-
runClient(clientID, clientSecret)
37+
patchConfig(rpcHost, appSecret,
38+
clientID, clientSecret,
39+
apiScheme, rpcPort, apiPort)
40+
runClient()
3941
},
4042
}
4143
rootCmd = &cobra.Command{
@@ -58,7 +60,7 @@ func initLogger() {
5860
logrus.SetReportCaller(true)
5961
}
6062

61-
func patchConfig(host, secret string, rpcPort, apiPort int) {
63+
func patchConfig(host, secret, clientID, clientSecret, apiScheme string, rpcPort, apiPort int) {
6264
if len(host) != 0 {
6365
conf.Get().Master.RPCHost = host
6466
conf.Get().Master.APIHost = host
@@ -72,4 +74,13 @@ func patchConfig(host, secret string, rpcPort, apiPort int) {
7274
if apiPort != 0 {
7375
conf.Get().Master.APIPort = apiPort
7476
}
77+
if len(apiScheme) != 0 {
78+
conf.Get().Master.APIScheme = apiScheme
79+
}
80+
if len(clientID) != 0 {
81+
conf.Get().Client.ID = clientID
82+
}
83+
if len(clientSecret) != 0 {
84+
conf.Get().Client.Secret = clientSecret
85+
}
7586
}

conf/settings.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ type Config struct {
3939
Type string `env:"TYPE" env-default:"sqlite3" env-description:"db type, mysql or sqlite3 and so on"`
4040
DSN string `env:"DSN" env-default:"data.db" env-description:"db dsn, for sqlite is path, other is dsn, look at https://github.com/go-sql-driver/mysql#dsn-data-source-name"`
4141
} `env-prefix:"DB_"`
42+
Client struct {
43+
ID string `env:"ID" env-description:"client id"`
44+
Secret string `env:"SECRET" env-description:"client secret"`
45+
} `env-prefix:"CLIENT_"`
4246
}
4347

4448
var (
@@ -56,7 +60,7 @@ func InitConfig() {
5660
)
5761

5862
if err = godotenv.Load(); err != nil {
59-
logrus.Infof("Error loading .env file, will use runtime env")
63+
logrus.WithError(err).Infof("Error loading .env file, will use runtime env")
6064
}
6165

6266
cfg := Config{}

www/components/client_item.tsx

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
} from '@/components/ui/dropdown-menu'
2323
import { useToast } from './ui/use-toast'
2424
import React, { useState } from 'react'
25-
import { ExecCommandStr, LinuxInstallCommand, WindowsInstallCommand } from '@/lib/consts'
25+
import { ClientEnvFile, ExecCommandStr, LinuxInstallCommand, WindowsInstallCommand } from '@/lib/consts'
2626
import { useMutation, useQuery } from '@tanstack/react-query'
2727
import { deleteClient, listClient } from '@/api/client'
2828
import { useRouter } from 'next/router'
@@ -211,6 +211,15 @@ export const ClientActions: React.FC<ClientItemProps> = ({ client, table }) => {
211211
},
212212
})
213213

214+
const createAndDownloadFile = (fileName: string, content: string) => {
215+
var aTag = document.createElement('a');
216+
var blob = new Blob([content]);
217+
aTag.download = fileName;
218+
aTag.href = URL.createObjectURL(blob);
219+
aTag.click();
220+
URL.revokeObjectURL(aTag.href);
221+
}
222+
214223
return (
215224
<Dialog>
216225
<DropdownMenu>
@@ -246,6 +255,20 @@ export const ClientActions: React.FC<ClientItemProps> = ({ client, table }) => {
246255
>
247256
修改客户端配置
248257
</DropdownMenuItem>
258+
<DropdownMenuItem
259+
onClick={() => {
260+
try {
261+
if (platformInfo) {
262+
createAndDownloadFile(`.env`, ClientEnvFile(client, platformInfo))
263+
}
264+
}
265+
catch (error) {
266+
toast({ description: '获取平台信息失败' })
267+
}
268+
}}
269+
>
270+
下载配置文件
271+
</DropdownMenuItem>
249272
<DialogTrigger asChild>
250273
<DropdownMenuItem className="text-destructive">删除</DropdownMenuItem>
251274
</DialogTrigger>
@@ -269,6 +292,6 @@ export const ClientActions: React.FC<ClientItemProps> = ({ client, table }) => {
269292
</DialogClose>
270293
</DialogFooter>
271294
</DialogContent>
272-
</Dialog>
295+
</Dialog >
273296
)
274297
}

www/components/server_item.tsx

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
} from '@/components/ui/dropdown-menu'
2323
import { useToast } from './ui/use-toast'
2424
import React, { useState } from 'react'
25-
import { ExecCommandStr, LinuxInstallCommand, WindowsInstallCommand } from '@/lib/consts'
25+
import { ClientEnvFile, ExecCommandStr, LinuxInstallCommand, WindowsInstallCommand } from '@/lib/consts'
2626
import { useMutation, useQuery } from '@tanstack/react-query'
2727
import { deleteServer, listServer } from '@/api/server'
2828
import { useRouter } from 'next/router'
@@ -221,6 +221,16 @@ export const ServerActions: React.FC<ServerItemProps> = ({ server, table }) => {
221221
toast({ description: '删除失败' })
222222
},
223223
})
224+
225+
const createAndDownloadFile = (fileName: string, content: string) => {
226+
var aTag = document.createElement('a');
227+
var blob = new Blob([content]);
228+
aTag.download = fileName;
229+
aTag.href = URL.createObjectURL(blob);
230+
aTag.click();
231+
URL.revokeObjectURL(aTag.href);
232+
}
233+
224234
return (
225235
<Dialog>
226236
<DropdownMenu>
@@ -261,6 +271,20 @@ export const ServerActions: React.FC<ServerItemProps> = ({ server, table }) => {
261271
>
262272
修改服务端配置
263273
</DropdownMenuItem>
274+
<DropdownMenuItem
275+
onClick={() => {
276+
try {
277+
if (platformInfo) {
278+
createAndDownloadFile(`.env`, ClientEnvFile(server, platformInfo))
279+
}
280+
}
281+
catch (error) {
282+
toast({ description: '获取平台信息失败' })
283+
}
284+
}}
285+
>
286+
下载配置文件
287+
</DropdownMenuItem>
264288
<DialogTrigger asChild>
265289
<DropdownMenuItem className="text-destructive">删除</DropdownMenuItem>
266290
</DialogTrigger>

www/lib/consts.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@ export const ExecCommandStr = <T extends Client | Server>(
2323
info: GetPlatformInfoResponse,
2424
fileName?: string,
2525
) => {
26-
return `${fileName || 'frp-panel'} ${type} -s ${item.secret} -i ${item.id} -a ${info.globalSecret} -r ${
27-
info.masterRpcHost
28-
} -c ${info.masterRpcPort} -p ${info.masterApiPort} -e ${info.masterApiScheme}`
26+
return `${fileName || 'frp-panel'} ${type} -s ${item.secret} -i ${item.id} -a ${info.globalSecret} -r ${info.masterRpcHost
27+
} -c ${info.masterRpcPort} -p ${info.masterApiPort} -e ${info.masterApiScheme}`
2928
}
3029

3130
export const WindowsInstallCommand = <T extends Client | Server>(
@@ -47,3 +46,17 @@ export const LinuxInstallCommand = <T extends Client | Server>(
4746
) => {
4847
return `curl -sSL https://raw.githubusercontent.com/VaalaCat/frp-panel/main/install.sh | bash -s --${ExecCommandStr(type, item, info, ' ')}`
4948
}
49+
50+
export const ClientEnvFile = <T extends Client | Server>(
51+
item: T,
52+
info: GetPlatformInfoResponse,
53+
) => {
54+
return `CLIENT_ID=${item.id}
55+
CLIENT_SECRET=${item.secret}
56+
APP_SECRET=${info.globalSecret}
57+
MASTER_RPC_HOST=${info.masterRpcHost}
58+
MASTER_RPC_PORT=${info.masterRpcPort}
59+
MASTER_API_HOST=${info.masterRpcHost}
60+
MASTER_API_PORT=${info.masterApiPort}
61+
MASTER_API_SCHEME=${info.masterApiScheme}`
62+
}

0 commit comments

Comments
 (0)