cmd/ggactl/commands/common.go (57 lines of code) (raw):

// Copyright 2024 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Package commands provides common helper methods for all commands implemented // by CLI. package commands import ( "encoding/json" "fmt" "io" "github.com/GoogleCloudPlatform/galog" "github.com/GoogleCloudPlatform/google-guest-agent/internal/command" "github.com/spf13/cobra" ) // sendlistener returns the command listener for send command. func sendlistener(sendCmd *cobra.Command) (command.KnownListeners, error) { switch sendCmd.Parent().Name() { case command.ListenerGuestAgent.String(): return command.ListenerGuestAgent, nil case sendCmd.CommandPath(), command.ListenerCorePlugin.String(): return command.ListenerCorePlugin, nil default: return 0, fmt.Errorf("no known listener for command: %s", sendCmd.CommandPath()) } } // NewSendCmd returns a new cobra command that implements generic send JSON command. func NewSendCmd() *cobra.Command { send := &cobra.Command{ Use: "send <json>", Short: "Sends a generic JSON", Long: "Sends a generic JSON. It supports both guest agent and core plugin.", Args: cobra.ExactArgs(1), PreRun: func(cmd *cobra.Command, args []string) { // Disable cmd produced stdout and stderr logs in non-test env to avoid // duplication with galog. if cmd.Context().Value("enable_stdlogs") == nil { cmd.SetOut(io.Discard) cmd.SetErr(io.Discard) } }, RunE: SendCmdRunner, } return send } // isValidRequest checks if request is a valid JSON as expected by command monitor. func isValidRequest(req string) bool { r := &command.Request{} if err := json.Unmarshal([]byte(req), r); err != nil { return false } return true } // SendCmdRunner is the callback to send command. func SendCmdRunner(cmd *cobra.Command, args []string) error { req := args[0] if !isValidRequest(req) { return fmt.Errorf(`invalid request: [%s %s], arg must be a valid JSON like {"Command":"echo"}`, cmd.CommandPath(), req) } lis, err := sendlistener(cmd) if err != nil { return fmt.Errorf("generic send command failed: %w", err) } galog.Debugf("Sending request [%s %s]", cmd.CommandPath(), req) resp := command.SendCommand(cmd.Context(), []byte(req), lis) galog.Infof("Command result: %s", string(resp)) // This is used only for unit testing to capture test outputs. Command on // initialization sets to discard any stdout/stderr messages to avoid any // duplication with `galog`. cmd.Println(string(resp)) return nil }