From dedd06328cd27816857f79c7e9da42eabe57303c Mon Sep 17 00:00:00 2001 From: Ryan Cook Date: Fri, 2 Sep 2022 12:39:05 -0400 Subject: [PATCH] commit of basic auth (#243) * commit of basic auth Signed-off-by: Ryan Cook * fix of docs and additional information Signed-off-by: Ryan Cook Signed-off-by: Ryan Cook --- docs/methods.rst | 36 +++++++++++++++++++++++++++++++++++- docs/running.rst | 4 ++-- examples/config-url.yaml | 2 +- pkg/engine/apply.go | 8 ++++---- pkg/engine/config.go | 13 +++++++++---- pkg/engine/fetchit.go | 14 +++++++++----- pkg/engine/types.go | 4 ++++ 7 files changed, 64 insertions(+), 17 deletions(-) diff --git a/docs/methods.rst b/docs/methods.rst index 1ce1e305..f6551f31 100644 --- a/docs/methods.rst +++ b/docs/methods.rst @@ -6,6 +6,8 @@ and various configuration values that relate to that method. A target is a unique value that holds methods. Mutiple git targets (targetConfigs) can be defined. Methods that can be configured include `Raw`, `Systemd`, `Kube`, `Ansible`, `FileTransfer`, `Prune`, and `ConfigReload`. +Examples of all methods are located in the `FetchIt repository `_ + Dynamic Configuration Reload ============= @@ -18,11 +20,43 @@ pod is required to reload targetConfigs. The following fields are required with configReload: schedule: "*/5 * * * *" - configUrl: https://raw.githubusercontent.com/sallyom/fetchit-config/main/config.yaml + configUrl: https://raw.githubusercontent.com/containers/fetchit/main/examples/config-reload.yaml Changes pushed to the ConfigURL will trigger a reloading of FetchIt target configs. It's recommended to include the ConfigReload in the FetchIt config to enable updates to target configs without requiring a restart. +The configuration above will pull in the file from the repository and reload the FetchIt config. +The YAML above demonstrates the minimal required objects to start FetchIt. Once FetchIt is running, the full configuration file +that is stored in git will be used. + +Dynamic Configuration Reload Using a Private Registry +===================================================== + +The ConfigReload method can be used to reload target configs from a private registry but this comes with the warning to ensure that +the repository is not public. The config.yaml will need to include the credentials to access the private registry. + +When using a GitHub PAT token, the config.yaml will need to include the following fields: +.. code-block:: yaml + + configReload: + schedule: "*/5 * * * *" + pat: github-alphanumeric-token + configUrl: https://raw.githubusercontent.com/containers/fetchit/main/examples/config-reload.yaml + +When using basic authentication the config.yaml will need to include the following fields: + +.. code-block:: yaml + + configReload: + schedule: "*/5 * * * *" + username: bob + passwords: bobpassword + configUrl: https://raw.githubusercontent.com/containers/fetchit/main/examples/config-reload.yaml + +NOTE: This is not recommended for public repositories. As your credentials will need to be in clear text in the config.yaml. + +PAT is the preferred method of authentication when available as the credentials can be reissued or locked. + Methods ======= Various methods are available to lifecycle and manage the container environment on a host. Funcionality also exists to diff --git a/docs/running.rst b/docs/running.rst index cfe29dc2..aea09865 100644 --- a/docs/running.rst +++ b/docs/running.rst @@ -40,7 +40,7 @@ For root .. code-block:: bash - cp systemd/fetchit.root /etc/systemd/system/fetchit.service + cp systemd/fetchit-root.service /etc/systemd/system/fetchit.service systemctl enable fetchit --now @@ -49,7 +49,7 @@ For user ensure that the path for the configuration file `/home/fetchiter/config .. code-block:: bash mkdir -p ~/.config/systemd/user/ - cp systemd/fetchit.user ~/.config/systemd/user/ + cp systemd/fetchit-user.service ~/.config/systemd/user/ systemctl --user enable fetchit --now Manually diff --git a/examples/config-url.yaml b/examples/config-url.yaml index 9a5dc858..d7a87228 100644 --- a/examples/config-url.yaml +++ b/examples/config-url.yaml @@ -1,5 +1,5 @@ # This is an example configReload that is used in testing. Fetchit will start with this config then will load targetConfigs from ./examples/config-reload.yaml # Note: It takes (default) 5 min for raw urls to be updated in GitHub, so this test will wait for 7 min configReload: - configURL: https://raw.githubusercontent.com/josephsawaya/fetchit/fix-target-path/examples/config-reload.yaml + configURL: https://raw.githubusercontent.com/containers/fetchit/main/examples/config-reload.yaml schedule: "*/1 * * * *" diff --git a/pkg/engine/apply.go b/pkg/engine/apply.go index 4b8d5305..dd4d879f 100644 --- a/pkg/engine/apply.go +++ b/pkg/engine/apply.go @@ -61,9 +61,9 @@ func getLatest(target *Target) (plumbing.Hash, error) { return plumbing.Hash{}, utils.WrapErr(err, "Error opening repository %s to fetch latest commit", directory) } - var user string if target.pat != "" { - user = "fetchit" + target.username = "fetchit" + target.password = target.pat } refSpec := config.RefSpec(fmt.Sprintf("+refs/heads/%s:refs/heads/%s", target.branch, target.branch)) @@ -72,8 +72,8 @@ func getLatest(target *Target) (plumbing.Hash, error) { RefSpecs: []config.RefSpec{refSpec, "HEAD:refs/heads/HEAD"}, Depth: 0, Auth: &githttp.BasicAuth{ - Username: user, - Password: target.pat, + Username: target.username, + Password: target.password, }, Progress: nil, Tags: 0, diff --git a/pkg/engine/config.go b/pkg/engine/config.go index 2104a54a..81300300 100644 --- a/pkg/engine/config.go +++ b/pkg/engine/config.go @@ -30,6 +30,8 @@ type ConfigReload struct { Device string `mapstructure:"device"` ConfigPath string `mapstructure:"configPath"` Pat string `mapstructure:"pat"` + Username string `mapstructure:"username"` + Password string `mapstructure:"password"` } func (c *ConfigReload) GetKind() string { @@ -56,7 +58,7 @@ func (c *ConfigReload) Process(ctx, conn context.Context, skew int) { // CheckForConfigUpdates downloads & places config file in defaultConfigPath // if the downloaded config file differs from what's currently on the system. if envURL != "" { - restart := checkForConfigUpdates(envURL, true, false, c.Pat) + restart := checkForConfigUpdates(envURL, true, false, c.Pat, c.Username, c.Password) if !restart { return } @@ -85,12 +87,12 @@ func (c *ConfigReload) Apply(ctx, conn context.Context, currentState, desiredSta // in defaultConfigPath in fetchit container (/opt/mount/config.yaml). // This runs with the initial startup as well as with scheduled ConfigReload runs, // if $FETCHIT_CONFIG_URL is set. -func checkForConfigUpdates(envURL string, existsAlready bool, initial bool, pat string) bool { +func checkForConfigUpdates(envURL string, existsAlready bool, initial bool, pat, username, password string) bool { // envURL is either set by user or set to match a configURL in a configReload if envURL == "" { return false } - reset, err := downloadUpdateConfigFile(envURL, existsAlready, initial, pat) + reset, err := downloadUpdateConfigFile(envURL, existsAlready, initial, pat, username, password) if err != nil { logger.Info(err) } @@ -153,7 +155,7 @@ func checkForDisconUpdates(device, configPath string, existsAlready bool, initia } // downloadUpdateConfig returns true if config was updated in fetchit pod -func downloadUpdateConfigFile(urlStr string, existsAlready, initial bool, pat string) (bool, error) { +func downloadUpdateConfigFile(urlStr string, existsAlready, initial bool, pat, username, password string) (bool, error) { _, err := url.Parse(urlStr) if err != nil { return false, fmt.Errorf("unable to parse config file url %s: %v", urlStr, err) @@ -172,6 +174,9 @@ func downloadUpdateConfigFile(urlStr string, existsAlready, initial bool, pat st req.Header.Add("Authorization", "token "+pat) req.Header.Add("Accept", "application/vnd.github.v3+json") } + if username != "" && password != "" { + req.SetBasicAuth(username, password) + } resp, err := client.Do(req) if err != nil { return false, err diff --git a/pkg/engine/fetchit.go b/pkg/engine/fetchit.go index dde37f79..5ab6240f 100644 --- a/pkg/engine/fetchit.go +++ b/pkg/engine/fetchit.go @@ -186,6 +186,8 @@ func (fc *FetchitConfig) InitConfig(initial bool) *Fetchit { var config *FetchitConfig envURL := os.Getenv("FETCHIT_CONFIG_URL") pat := "" + username := "" + password := "" // user will pass path on local system, but it must be mounted at the defaultConfigPath in fetchit pod // regardless of where the config file is on the host, fetchit will read the configFile from within @@ -203,7 +205,7 @@ func (fc *FetchitConfig) InitConfig(initial bool) *Fetchit { // Only run this from initial startup and only after trying to populate the config from a local file. // because CheckForConfigUpdates also runs with each processConfig, so if !initial this is already done // If configURL is passed in, a config file on disk has priority on the initial run. - _ = checkForConfigUpdates(envURL, false, true, pat) + _ = checkForConfigUpdates(envURL, false, true, pat, username, password) } // if config is not yet populated, fc.CheckForConfigUpdates has placed the config @@ -235,6 +237,8 @@ func getMethodTargetScheds(targetConfigs []*TargetConfig, fetchit *Fetchit) *Fet url: tc.Url, device: tc.Device, pat: tc.Pat, + username: tc.Username, + password: tc.Password, branch: tc.Branch, disconnected: tc.Disconnected, } @@ -367,14 +371,14 @@ func getClone(target *Target) error { if !exists { logger.Infof("git clone %s %s --recursive", target.url, target.branch) - var user string if target.pat != "" { - user = "fetchit" + target.username = "fetchit" + target.password = target.pat } _, err = git.PlainClone(absPath, false, &git.CloneOptions{ Auth: &githttp.BasicAuth{ - Username: user, // the value of this field should not matter when using a PAT - Password: target.pat, + Username: target.username, // the value of this field should not matter when using a PAT + Password: target.password, }, URL: target.url, ReferenceName: plumbing.ReferenceName(fmt.Sprintf("refs/heads/%s", target.branch)), diff --git a/pkg/engine/types.go b/pkg/engine/types.go index d8b84f5b..aca9c533 100644 --- a/pkg/engine/types.go +++ b/pkg/engine/types.go @@ -33,6 +33,8 @@ type TargetConfig struct { Name string `mapstructure:"name"` Url string `mapstructure:"url"` Pat string `mapstructure:"pat"` + Username string `mapstructure:"username"` + Password string `mapstructure:"password"` Device string `mapstructure:"device"` Disconnected bool `mapstructure:"disconnected"` VerifyCommitsInfo *VerifyCommitsInfo `mapstructure:"verifyCommitsInfo"` @@ -52,6 +54,8 @@ type TargetConfig struct { type Target struct { url string pat string + username string + password string device string localPath string branch string