Skip to content

Commit 5f412a2

Browse files
authored
Merge branch 'master' into dependabot/go_modules/go-6a3dbd348c
2 parents 6b13b0f + f5bf5aa commit 5f412a2

20 files changed

+154
-80
lines changed

api/module.go

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ import (
1313
"github.com/voxpupuli/webhook-go/lib/queue"
1414
)
1515

16-
// Module Controller
16+
// ModuleController handles module deployment.
1717
type ModuleController struct{}
1818

19-
// DeployModule takes int the current Gin context and parses the request
20-
// data into a variable then executes the r10k module deploy either through
21-
// a direct local execution of the r10k deploy module command
19+
// DeployModule handles the deployment of a Puppet module via r10k.
20+
// It parses the incoming webhook data, constructs the r10k command,
21+
// and either queues the deployment or executes it immediately.
2222
func (m ModuleController) DeployModule(c *gin.Context) {
2323
var data parsers.Data
2424
var h helpers.Helper
@@ -35,6 +35,7 @@ func (m ModuleController) DeployModule(c *gin.Context) {
3535
// Parse the data from the request and error if parsing fails
3636
err := data.ParseData(c)
3737
if err != nil {
38+
// Respond with error if parsing fails, notify ChatOps if enabled.
3839
c.JSON(http.StatusInternalServerError, gin.H{"message": "Error Parsing Webhook", "error": err})
3940
c.Abort()
4041
if conf.ChatOps.Enabled {
@@ -43,6 +44,7 @@ func (m ModuleController) DeployModule(c *gin.Context) {
4344
return
4445
}
4546

47+
// Handle optional branch parameter, fallback to default branch if not provided.
4648
useBranch := c.Query("branch_only")
4749
if useBranch != "" {
4850
branch := ""
@@ -55,12 +57,13 @@ func (m ModuleController) DeployModule(c *gin.Context) {
5557
cmd = append(cmd, branch)
5658
}
5759

60+
// Validate module name with optional override from query parameters.
5861
module := data.ModuleName
5962
overrideModule := c.Query("module_name")
60-
// Restrictions to Puppet module names are: 1) begin with lowercase letter, 2) contain lowercase, digits or underscores
6163
if overrideModule != "" {
6264
match, _ := regexp.MatchString("^[a-z][a-z0-9_]*$", overrideModule)
6365
if !match {
66+
// Invalid module name, respond with error and notify ChatOps.
6467
c.JSON(http.StatusInternalServerError, gin.H{"message": "Invalid module name"})
6568
c.Abort()
6669
err = fmt.Errorf("invalid module name: module name does not match the expected pattern; got: %s, pattern: ^[a-z][a-z0-9_]*$", overrideModule)
@@ -72,26 +75,16 @@ func (m ModuleController) DeployModule(c *gin.Context) {
7275
module = overrideModule
7376
}
7477

75-
// Append module name and r10k configuration to the cmd string slice
78+
// Append module name and r10k configuration to the command string slice.
7679
cmd = append(cmd, module)
7780
cmd = append(cmd, fmt.Sprintf("--config=%s", h.GetR10kConfig()))
7881

79-
// Set additional optional r10k flags if they are set
82+
// Set additional optional r10k flags if they are enabled.
8083
if conf.R10k.Verbose {
8184
cmd = append(cmd, "-v")
8285
}
8386

84-
// Pass the command to the execute function and act on the result and any error
85-
// that is returned
86-
//
87-
// On an error this will:
88-
// * Log the error and command
89-
// * Respond with an HTTP 500 error and return the command result in JSON format
90-
// * Abort the request
91-
// * Notify ChatOps service if enabled
92-
//
93-
// On success this will:
94-
// * Respond with an HTTP 202 and the result in JSON format
87+
// Execute or queue the command based on server configuration.
9588
var res interface{}
9689
if conf.Server.Queue.Enabled {
9790
res, err = queue.AddToQueue("module", data.ModuleName, cmd)
@@ -103,6 +96,7 @@ func (m ModuleController) DeployModule(c *gin.Context) {
10396
}
10497
}
10598

99+
// Handle error response, notify ChatOps if enabled.
106100
if err != nil {
107101
c.JSON(http.StatusInternalServerError, res)
108102
c.Abort()
@@ -112,6 +106,7 @@ func (m ModuleController) DeployModule(c *gin.Context) {
112106
return
113107
}
114108

109+
// On success, respond with HTTP 202 and notify ChatOps if enabled.
115110
c.JSON(http.StatusAccepted, res)
116111
if conf.ChatOps.Enabled {
117112
conn.PostMessage(http.StatusAccepted, data.ModuleName, res)

cmd/root.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@ import (
88
"github.com/voxpupuli/webhook-go/config"
99
)
1010

11+
// cfgFile is the path to the configuration file, given by the user as a flag
1112
var cfgFile string
1213

14+
// version is the current version of the application
1315
var version = "0.0.0"
1416

17+
// rootCmd is the root command for the application
18+
// It is used to set up the application, and is the entry point for the Cobra CLI
1519
var rootCmd = &cobra.Command{
1620
Use: "webhook-go",
1721
Version: version,
@@ -21,23 +25,26 @@ var rootCmd = &cobra.Command{
2125
API endpoint.`,
2226
}
2327

28+
// Execute is the main entry point for the application, called from main.go, and is used to execute the root command
2429
func Execute() {
2530
if err := rootCmd.Execute(); err != nil {
2631
fmt.Println(err)
2732
os.Exit(1)
2833
}
2934
}
3035

36+
// init is called when the package loads, and is used to set up the root command, and the configuration file flag
3137
func init() {
32-
cobra.OnInitialize(initConfig)
38+
cobra.OnInitialize(initConfig) // tells Cobra to call the initConfig function before executing any command.
3339

34-
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is ./webhook.yml)")
40+
rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is ./webhook.yml)") // adds a flag to the root command that allows the user to specify a configuration file
3541
}
3642

43+
// initConfig reads in config file and ENV variables if set.
3744
func initConfig() {
3845
if cfgFile != "" {
39-
config.Init(&cfgFile)
46+
config.Init(&cfgFile) // Expecting a path to a configuration file
4047
} else {
41-
config.Init(nil)
48+
config.Init(nil) // No path given, use defaults
4249
}
4350
}

cmd/server.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
/*
22
Copyright © 2022 NAME HERE <EMAIL ADDRESS>
3-
43
*/
54
package cmd
65

@@ -9,17 +8,16 @@ import (
98
"github.com/voxpupuli/webhook-go/server"
109
)
1110

12-
// serverCmd represents the server command
11+
// serverCmd starts the Webhook-go server, allowing it to process webhook requests.
1312
var serverCmd = &cobra.Command{
1413
Use: "server",
1514
Short: "Start the Webhook-go server",
16-
Long: ``,
1715
Run: startServer,
1816
}
1917

18+
// init adds serverCmd to the root command.
2019
func init() {
2120
rootCmd.AddCommand(serverCmd)
22-
2321
// Here you will define your flags and configuration settings.
2422

2523
// Cobra supports Persistent Flags which will work for this command
@@ -31,6 +29,7 @@ func init() {
3129
// serverCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
3230
}
3331

32+
// startServer initializes and starts the server.
3433
func startServer(cmd *cobra.Command, args []string) {
3534
server.Init()
3635
}

config/config.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
var config Config
1111

12+
// Config is a struct that holds the configuration for the application
1213
type Config struct {
1314
Server struct {
1415
Protected bool `mapstructure:"protected"`
@@ -47,10 +48,12 @@ type Config struct {
4748
} `mapstructure:"r10k"`
4849
}
4950

51+
// Init reads in the configuration file and populates the Config struct
5052
func Init(path *string) {
5153
var err error
52-
v := viper.New()
54+
v := viper.New() // creates a new Viper instance
5355

56+
// If a path is given, use it, otherwise, use the default
5457
if path != nil {
5558
v.SetConfigFile(*path)
5659
} else {
@@ -61,19 +64,20 @@ func Init(path *string) {
6164
v.AddConfigPath("../config/")
6265
v.AddConfigPath("config/")
6366
}
64-
err = v.ReadInConfig()
67+
err = v.ReadInConfig() // reads the configuration file
6568
if err != nil {
6669
log.Fatalf("error on parsing config file: %v", err)
6770
}
6871

69-
v = setDefaults(v)
72+
v = setDefaults(v) // sets the default values for the configuration
7073

71-
err = v.Unmarshal(&config)
74+
err = v.Unmarshal(&config) // converts the configuration into the Config struct
7275
if err != nil {
7376
log.Fatalf("Unable to read config file: %v", err)
7477
}
7578
}
7679

80+
// Provides defualt values in case of config file doesn't define some fields
7781
func setDefaults(v *viper.Viper) *viper.Viper {
7882
v.SetDefault("server.port", 4000)
7983
v.SetDefault("server.protected", false)
@@ -94,13 +98,16 @@ func setDefaults(v *viper.Viper) *viper.Viper {
9498
return v
9599
}
96100

101+
// This utility function adjusts relative paths.
102+
// If a path doesn't start with / (indicating it’s not an absolute path), it prepends the basedir to make it a proper path.
97103
func relativePath(basedir string, path *string) {
98104
p := *path
99105
if len(p) > 0 && p[0] != '/' {
100106
*path = filepath.Join(basedir, p)
101107
}
102108
}
103109

110+
// This function simply returns the currently loaded configuration
104111
func GetConfig() Config {
105112
return config
106113
}

lib/chatops/chatops.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,28 +5,34 @@ import (
55
"strconv"
66
)
77

8+
// ChatOps defines the configuration for interacting with various chat services.
89
type ChatOps struct {
9-
Service string
10-
Channel string
11-
User string
12-
AuthToken string
13-
ServerURI *string
14-
TestMode bool
15-
TestURL *string
10+
Service string // Chat service (e.g., "slack", "rocketchat", "teams").
11+
Channel string // Target channel or room.
12+
User string // User initiating the action.
13+
AuthToken string // Authentication token for the chat service.
14+
ServerURI *string // Optional server URI for self-hosted services.
15+
TestMode bool // Indicates if the operation is in test mode.
16+
TestURL *string // URL for testing purposes, if applicable.
1617
}
1718

19+
// ChatOpsResponse captures the response details from a chat service after a message is posted.
1820
type ChatOpsResponse struct {
1921
Timestamp string
2022
Channel string
2123
}
2224

25+
// ChatAttachment represents the structure of a message attachment in chat services like Slack.
2326
type ChatAttachment struct {
2427
AuthorName string
2528
Title string
2629
Text string
27-
Color string
30+
Color string // Color to indicate status (e.g., success, failure).
2831
}
2932

33+
// PostMessage sends a formatted message to the configured chat service based on the HTTP status code
34+
// and target environment. It returns a ChatOpsResponse or an error if posting fails.
35+
// Supports Slack, Rocket.Chat, and Microsoft Teams.
3036
func (c *ChatOps) PostMessage(code int, target string, output interface{}) (*ChatOpsResponse, error) {
3137
var resp ChatOpsResponse
3238

@@ -56,6 +62,8 @@ func (c *ChatOps) PostMessage(code int, target string, output interface{}) (*Cha
5662
return &resp, nil
5763
}
5864

65+
// formatMessage generates a ChatAttachment based on the HTTP status code and target environment.
66+
// The message is used to notify the result of a Puppet environment deployment.
5967
func (c *ChatOps) formatMessage(code int, target string) ChatAttachment {
6068
var message ChatAttachment
6169

lib/chatops/rocketchat.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,42 @@ import (
88
"github.com/pandatix/gocket-chat/api/chat"
99
)
1010

11+
// rocketChat posts a message to a Rocket.Chat channel using the provided HTTP status code and target environment.
12+
// It returns a PostMessageResponse or an error if the operation fails.
13+
// ServerURI must be provided as part of the ChatOps configuration.
1114
func (c *ChatOps) rocketChat(code int, target string) (*chat.PostMessageResponse, error) {
15+
// Ensure ServerURI is set before proceeding.
1216
if c.ServerURI == nil {
1317
return nil, fmt.Errorf("A ServerURI must be specified to use RocketChat")
1418
}
1519

1620
client := &http.Client{}
1721

22+
// Initialize RocketChat client with the provided ServerURI, AuthToken, and User credentials.
1823
rc, err := gochat.NewRocketClient(client, *c.ServerURI, c.AuthToken, c.User)
1924
if err != nil {
2025
return nil, err
2126
}
2227

23-
var attachments []chat.Attachement
28+
// Format the message based on the HTTP status code and target environment.
2429
msg := c.formatMessage(code, target)
2530

31+
// Prepare attachments for the message.
32+
var attachments []chat.Attachement
2633
attachments = append(attachments, chat.Attachement{
2734
AuthorName: msg.AuthorName,
2835
Title: msg.Title,
2936
Color: msg.Color,
3037
Text: msg.Text,
3138
})
3239

40+
// Set the parameters for posting the message to the specified channel.
3341
pmp := chat.PostMessageParams{
3442
Channel: c.Channel,
3543
Attachements: &attachments,
3644
}
3745

46+
// Post the message to RocketChat.
3847
res, err := chat.PostMessage(rc, pmp)
3948
if err != nil {
4049
return nil, err

lib/chatops/slack.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"github.com/slack-go/slack"
55
)
66

7+
// slack posts a message to a Slack channel based on the HTTP status code and target.
8+
// Returns the channel, timestamp, or an error if the operation fails.
79
func (c *ChatOps) slack(code int, target string) (*string, *string, error) {
810
var sapi *slack.Client
911
if c.TestMode {

lib/helpers/branch.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"github.com/voxpupuli/webhook-go/lib/parsers"
55
)
66

7+
// GetBranch returns the branch name from the parsed data. If the branch was deleted, it returns the defaultBranch.
78
func (h *Helper) GetBranch(data parsers.Data, defaultBranch string) string {
89
if data.Deleted {
910
return defaultBranch

lib/helpers/environment.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import (
44
"fmt"
55
)
66

7+
// GetEnvironment constructs and returns an environment name by combining the prefix and branch.
8+
// If either is empty, it normalizes the branch name. Allows optional uppercase transformation.
79
func (h *Helper) GetEnvironment(branch, prefix string, allowUppercase bool) string {
810
if prefix == "" || branch == "" {
911
return h.Normalize(allowUppercase, branch)

lib/helpers/r10k-config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import "github.com/voxpupuli/webhook-go/config"
44

55
const ConfigFile = "/etc/puppetlabs/r10k/r10k.yaml"
66

7+
// GetR10kConfig retrieves the R10k configuration file path.
8+
// If no custom path is set in the configuration, it returns the default path.
79
func (h *Helper) GetR10kConfig() string {
810
conf := config.GetConfig().R10k
911
confPath := conf.ConfigPath

0 commit comments

Comments
 (0)