You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
3.3 KiB

  1. package command
  2. import (
  3. "context"
  4. "fmt"
  5. "net/http"
  6. "github.com/chrislusf/seaweedfs/weed/glog"
  7. "github.com/chrislusf/seaweedfs/weed/iamapi"
  8. "github.com/chrislusf/seaweedfs/weed/pb"
  9. "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
  10. "github.com/chrislusf/seaweedfs/weed/security"
  11. "github.com/chrislusf/seaweedfs/weed/util"
  12. "github.com/gorilla/mux"
  13. "time"
  14. )
  15. var (
  16. iamStandaloneOptions IamOptions
  17. )
  18. type IamOptions struct {
  19. filer *string
  20. masters *string
  21. ip *string
  22. port *int
  23. }
  24. func init() {
  25. cmdIam.Run = runIam // break init cycle
  26. iamStandaloneOptions.filer = cmdIam.Flag.String("filer", "localhost:8888", "filer server address")
  27. iamStandaloneOptions.masters = cmdIam.Flag.String("master", "localhost:9333", "comma-separated master servers")
  28. iamStandaloneOptions.ip = cmdIam.Flag.String("ip", util.DetectedHostAddress(), "iam server http listen ip address")
  29. iamStandaloneOptions.port = cmdIam.Flag.Int("port", 8111, "iam server http listen port")
  30. }
  31. var cmdIam = &Command{
  32. UsageLine: "iam [-port=8111] [-filer=<ip:port>] [-masters=<ip:port>,<ip:port>]",
  33. Short: "start a iam API compatible server",
  34. Long: "start a iam API compatible server.",
  35. }
  36. func runIam(cmd *Command, args []string) bool {
  37. return iamStandaloneOptions.startIamServer()
  38. }
  39. func (iamopt *IamOptions) startIamServer() bool {
  40. filerAddress := pb.ServerAddress(*iamopt.filer)
  41. util.LoadConfiguration("security", false)
  42. grpcDialOption := security.LoadClientTLS(util.GetViper(), "grpc.client")
  43. for {
  44. err := pb.WithGrpcFilerClient(false, filerAddress, grpcDialOption, func(client filer_pb.SeaweedFilerClient) error {
  45. resp, err := client.GetFilerConfiguration(context.Background(), &filer_pb.GetFilerConfigurationRequest{})
  46. if err != nil {
  47. return fmt.Errorf("get filer %s configuration: %v", filerAddress, err)
  48. }
  49. glog.V(0).Infof("IAM read filer configuration: %s", resp)
  50. return nil
  51. })
  52. if err != nil {
  53. glog.V(0).Infof("wait to connect to filer %s grpc address %s", *iamopt.filer, filerAddress.ToGrpcAddress())
  54. time.Sleep(time.Second)
  55. } else {
  56. glog.V(0).Infof("connected to filer %s grpc address %s", *iamopt.filer, filerAddress.ToGrpcAddress())
  57. break
  58. }
  59. }
  60. masters := pb.ServerAddresses(*iamopt.masters).ToAddresses()
  61. router := mux.NewRouter().SkipClean(true)
  62. _, iamApiServer_err := iamapi.NewIamApiServer(router, &iamapi.IamServerOption{
  63. Masters: masters,
  64. Filer: filerAddress,
  65. Port: *iamopt.port,
  66. GrpcDialOption: grpcDialOption,
  67. })
  68. glog.V(0).Info("NewIamApiServer created")
  69. if iamApiServer_err != nil {
  70. glog.Fatalf("IAM API Server startup error: %v", iamApiServer_err)
  71. }
  72. httpS := &http.Server{Handler: router}
  73. listenAddress := fmt.Sprintf(":%d", *iamopt.port)
  74. iamApiListener, iamApiLocalListener, err := util.NewIpAndLocalListeners(*iamopt.ip, *iamopt.port, time.Duration(10)*time.Second)
  75. if err != nil {
  76. glog.Fatalf("IAM API Server listener on %s error: %v", listenAddress, err)
  77. }
  78. glog.V(0).Infof("Start Seaweed IAM API Server %s at http port %d", util.Version(), *iamopt.port)
  79. if iamApiLocalListener != nil {
  80. go func() {
  81. if err = httpS.Serve(iamApiLocalListener); err != nil {
  82. glog.Errorf("IAM API Server Fail to serve: %v", err)
  83. }
  84. }()
  85. }
  86. if err = httpS.Serve(iamApiListener); err != nil {
  87. glog.Fatalf("IAM API Server Fail to serve: %v", err)
  88. }
  89. return true
  90. }