diff --git a/main.go b/main.go index 1b08b7a..60e788a 100644 --- a/main.go +++ b/main.go @@ -20,6 +20,7 @@ var ( cfg = struct { Config string `flag:"config,c" default:"config.yaml" description:"Configuration for the uploaders"` LogLevel string `flag:"log-level" default:"info" description:"Log level (debug, info, warn, error, fatal)"` + ValidateOnly bool `flag:"validate-only" default:"false" description:"Only execute validation and prepare functions, do not upload"` VersionAndExit bool `flag:"version" default:"false" description:"Prints current version and exits"` }{} @@ -52,32 +53,16 @@ func main() { os.Exit(0) } - if len(rconfig.Args()) < 2 { //nolint:gomnd - logrus.Fatal("Usage: publish-vod ") - } - configFile, err := config.Load(cfg.Config) if err != nil { logrus.WithError(err).Fatal("loading config") } var ( - ctx = context.Background() - fileName = rconfig.Args()[1] - wg sync.WaitGroup + ctx = context.Background() + wg sync.WaitGroup ) - f, err := os.Open(fileName) - if err != nil { - logrus.WithError(err).Fatal("opening VoD") - } - defer f.Close() //nolint:errcheck // File is closed by process exit - - stat, err := f.Stat() - if err != nil { - logrus.WithError(err).Fatal("getting VoD stat") - } - var ( barPool = pb.NewPool() longestPrefix int @@ -88,15 +73,43 @@ func main() { if u == nil { logrus.Fatalf("unknown uploader %q", c.Type) } + if err = u.ValidateConfig(c.Settings); err != nil { logrus.WithError(err).Fatalf("validating config entry %q", c.Name) } + if err = u.Prepare(ctx, uploader.UploaderOpts{ + Name: c.Name, + Config: c.Settings, + }); err != nil { + logrus.WithError(err).Fatalf("preparing uploader %q", c.Name) + } + if l := len(c.Name); l > longestPrefix { longestPrefix = l } } + if cfg.ValidateOnly { + return + } + + if len(rconfig.Args()) < 2 { //nolint:gomnd + logrus.Fatal("Usage: publish-vod ") + } + + fileName := rconfig.Args()[1] + f, err := os.Open(fileName) + if err != nil { + logrus.WithError(err).Fatal("opening VoD") + } + defer f.Close() //nolint:errcheck // File is closed by process exit + + stat, err := f.Stat() + if err != nil { + logrus.WithError(err).Fatal("getting VoD stat") + } + for i := range configFile.Uploaders { wg.Add(1) diff --git a/pkg/uploader/interface.go b/pkg/uploader/interface.go index 825c201..49c6387 100644 --- a/pkg/uploader/interface.go +++ b/pkg/uploader/interface.go @@ -12,6 +12,7 @@ import ( type ( Uploader interface { + Prepare(ctx context.Context, opts UploaderOpts) error UploadFile(ctx context.Context, opts UploaderOpts) error ValidateConfig(config *fieldcollection.FieldCollection) error } diff --git a/pkg/uploader/sftp/sftp.go b/pkg/uploader/sftp/sftp.go index 153434c..681f0bc 100644 --- a/pkg/uploader/sftp/sftp.go +++ b/pkg/uploader/sftp/sftp.go @@ -25,6 +25,8 @@ var ( _ uploader.Uploader = Uploader{} ) +func (Uploader) Prepare(context.Context, uploader.UploaderOpts) error { return nil } + func (Uploader) UploadFile(ctx context.Context, opts uploader.UploaderOpts) error { socket := os.Getenv("SSH_AUTH_SOCK") conn, err := net.Dial("unix", socket) diff --git a/pkg/uploader/youtube/youtube.go b/pkg/uploader/youtube/youtube.go index 6a08d54..a9697ba 100644 --- a/pkg/uploader/youtube/youtube.go +++ b/pkg/uploader/youtube/youtube.go @@ -27,26 +27,44 @@ var ( _ uploader.Uploader = Uploader{} ) +func (Uploader) Prepare(ctx context.Context, opts uploader.UploaderOpts) error { + _, ts, err := oauth4youtube.GetOAuth2Client(ctx, opts.Config.MustString("vaultKey", nil)) + if err != nil { + return fmt.Errorf("getting oauth credentials: %w", err) + } + + t, err := ts.Token() + if err != nil { + return fmt.Errorf("getting token to store: %w", err) + } + + if err := vaultoauth2.SaveTokenToVault(opts.Config.MustString("vaultKey", nil), t); err != nil { + return fmt.Errorf("storing token to vault: %w", err) + } + + return nil +} + func (Uploader) UploadFile(ctx context.Context, opts uploader.UploaderOpts) error { client, ts, err := oauth4youtube.GetOAuth2Client(ctx, opts.Config.MustString("vaultKey", nil)) if err != nil { - logrus.WithError(err).Fatal("getting oauth credentials") + return fmt.Errorf("getting oauth credentials: %w", err) } defer func() { t, err := ts.Token() if err != nil { - logrus.WithError(err).Fatal("getting token to store back") + logrus.WithError(err).Error("getting token to store back") } if err := vaultoauth2.SaveTokenToVault(opts.Config.MustString("vaultKey", nil), t); err != nil { - logrus.WithError(err).Fatal("storing token back to vault") + logrus.WithError(err).Error("storing token back to vault") } }() service, err := youtube.NewService(ctx, option.WithHTTPClient(client)) if err != nil { - logrus.WithError(err).Fatal("creating YouTube client") + return fmt.Errorf("creating Youtube client: %w", err) } upload := &youtube.Video{ @@ -78,7 +96,7 @@ func (Uploader) UploadFile(ctx context.Context, opts uploader.UploaderOpts) erro Media(progressReader). Do() if err != nil { - logrus.WithError(err).Fatal("inserting video") + return fmt.Errorf("inserting video: %w", err) } opts.FinalMessage("Video uploaded: https://youtu.be/%s", resp.Id) diff --git a/pkg/vault-oauth2/youtube/youtube.go b/pkg/vault-oauth2/youtube/youtube.go index 8830379..06bddaf 100644 --- a/pkg/vault-oauth2/youtube/youtube.go +++ b/pkg/vault-oauth2/youtube/youtube.go @@ -28,7 +28,7 @@ func GetOAuth2Client(ctx context.Context, vaultKey string) (client *http.Client, ClientID: clientID, ClientSecret: clientSecret, Endpoint: google.Endpoint, - RedirectURL: "http://127.0.0.1:8000", + RedirectURL: "http://127.0.0.1:65285", Scopes: []string{youtube.YoutubeUploadScope}, } @@ -39,7 +39,7 @@ func GetOAuth2Client(ctx context.Context, vaultKey string) (client *http.Client, mux := http.NewServeMux() mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { codeChan <- r.URL.Query().Get("code") }) server := &http.Server{ - Addr: ":8000", + Addr: ":65285", Handler: mux, ReadHeaderTimeout: time.Second, }