diff --git a/cmd/agola/cmd/remotesourcecreate.go b/cmd/agola/cmd/remotesourcecreate.go index 29a88dc..e10f00e 100644 --- a/cmd/agola/cmd/remotesourcecreate.go +++ b/cmd/agola/cmd/remotesourcecreate.go @@ -34,12 +34,14 @@ var cmdRemoteSourceCreate = &cobra.Command{ } type remoteSourceCreateOptions struct { - name string - rsType string - authType string - apiURL string - oauth2ClientID string - oauth2ClientSecret string + name string + rsType string + authType string + apiURL string + oauth2ClientID string + oauth2ClientSecret string + sshHostKey string + skipSSHHostKeyCheck bool } var remoteSourceCreateOpts remoteSourceCreateOptions @@ -53,6 +55,8 @@ func init() { flags.StringVar(&remoteSourceCreateOpts.apiURL, "api-url", "", "remotesource api url") flags.StringVar(&remoteSourceCreateOpts.oauth2ClientID, "clientid", "", "remotesource oauth2 client id") flags.StringVar(&remoteSourceCreateOpts.oauth2ClientSecret, "secret", "", "remotesource oauth2 secret") + flags.StringVar(&remoteSourceCreateOpts.sshHostKey, "ssh-host-key", "", "remotesource ssh public host key") + flags.BoolVarP(&remoteSourceCreateOpts.skipSSHHostKeyCheck, "skip-ssh-host-key-check", "s", false, "skip ssh host key check") cmdRemoteSourceCreate.MarkFlagRequired("name") cmdRemoteSourceCreate.MarkFlagRequired("type") @@ -66,12 +70,14 @@ func remoteSourceCreate(cmd *cobra.Command, args []string) error { gwclient := api.NewClient(gatewayURL, token) req := &api.CreateRemoteSourceRequest{ - Name: remoteSourceCreateOpts.name, - Type: remoteSourceCreateOpts.rsType, - AuthType: remoteSourceCreateOpts.authType, - APIURL: remoteSourceCreateOpts.apiURL, - Oauth2ClientID: remoteSourceCreateOpts.oauth2ClientID, - Oauth2ClientSecret: remoteSourceCreateOpts.oauth2ClientSecret, + Name: remoteSourceCreateOpts.name, + Type: remoteSourceCreateOpts.rsType, + AuthType: remoteSourceCreateOpts.authType, + APIURL: remoteSourceCreateOpts.apiURL, + Oauth2ClientID: remoteSourceCreateOpts.oauth2ClientID, + Oauth2ClientSecret: remoteSourceCreateOpts.oauth2ClientSecret, + SSHHostKey: remoteSourceCreateOpts.sshHostKey, + SkipSSHHostKeyCheck: remoteSourceCreateOpts.skipSSHHostKeyCheck, } log.Infof("creating remotesource") diff --git a/internal/runconfig/runconfig.go b/internal/runconfig/runconfig.go index 111c608..4161fe7 100644 --- a/internal/runconfig/runconfig.go +++ b/internal/runconfig/runconfig.go @@ -62,6 +62,13 @@ mkdir ~/.ssh chmod 700 ~/.ssh touch ~/.ssh/id_rsa chmod 600 ~/.ssh/id_rsa +touch ~/.ssh/known_hosts +chmod 600 ~/.ssh/known_hosts + +# Add public ssh host key +if [ -n "$AGOLA_SSHHOSTKEY" ]; then + echo "$AGOLA_SSHHOSTKEY" >> ~/.ssh/known_hosts +fi # Add repository deploy key (cat < ~/.ssh/id_rsa @@ -69,17 +76,20 @@ $AGOLA_SSHPRIVKEY EOF ) +STRICT_HOST_KEY_CHECKING="yes" + if [ -n "$AGOLA_SKIPSSHHOSTKEYCHECK" ]; then # Disable git host key verification - (cat < ~/.ssh/config + STRICT_HOST_KEY_CHECKING="no" +fi + +(cat < ~/.ssh/config Host $AGOLA_GIT_HOST HostName $AGOLA_GIT_HOST Port $AGOLA_GIT_PORT - StrictHostKeyChecking no - UserKnownHostsFile /dev/null + StrictHostKeyChecking ${STRICT_HOST_KEY_CHECKING} EOF - ) -fi +) git clone $AGOLA_REPOSITORY_URL . git fetch origin $AGOLA_GIT_REF diff --git a/internal/services/gateway/action/remotesource.go b/internal/services/gateway/action/remotesource.go index d064b7d..fcd7e6c 100644 --- a/internal/services/gateway/action/remotesource.go +++ b/internal/services/gateway/action/remotesource.go @@ -46,12 +46,14 @@ func (h *ActionHandler) GetRemoteSources(ctx context.Context, req *GetRemoteSour } type CreateRemoteSourceRequest struct { - Name string - APIURL string - Type string - AuthType string - Oauth2ClientID string - Oauth2ClientSecret string + Name string + APIURL string + Type string + AuthType string + Oauth2ClientID string + Oauth2ClientSecret string + SSHHostKey string + SkipSSHHostKeyCheck bool } func (h *ActionHandler) CreateRemoteSource(ctx context.Context, req *CreateRemoteSourceRequest) (*types.RemoteSource, error) { @@ -91,12 +93,14 @@ func (h *ActionHandler) CreateRemoteSource(ctx context.Context, req *CreateRemot } rs := &types.RemoteSource{ - Name: req.Name, - Type: types.RemoteSourceType(req.Type), - AuthType: types.RemoteSourceAuthType(req.AuthType), - APIURL: req.APIURL, - Oauth2ClientID: req.Oauth2ClientID, - Oauth2ClientSecret: req.Oauth2ClientSecret, + Name: req.Name, + Type: types.RemoteSourceType(req.Type), + AuthType: types.RemoteSourceAuthType(req.AuthType), + APIURL: req.APIURL, + Oauth2ClientID: req.Oauth2ClientID, + Oauth2ClientSecret: req.Oauth2ClientSecret, + SSHHostKey: req.SSHHostKey, + SkipSSHHostKeyCheck: req.SkipSSHHostKeyCheck, } h.log.Infof("creating remotesource") diff --git a/internal/services/gateway/api/remotesource.go b/internal/services/gateway/api/remotesource.go index 9193d31..e53764e 100644 --- a/internal/services/gateway/api/remotesource.go +++ b/internal/services/gateway/api/remotesource.go @@ -29,12 +29,14 @@ import ( ) type CreateRemoteSourceRequest struct { - Name string `json:"name"` - APIURL string `json:"apiurl"` - Type string `json:"type"` - AuthType string `json:"auth_type"` - Oauth2ClientID string `json:"oauth_2_client_id"` - Oauth2ClientSecret string `json:"oauth_2_client_secret"` + Name string `json:"name"` + APIURL string `json:"apiurl"` + Type string `json:"type"` + AuthType string `json:"auth_type"` + Oauth2ClientID string `json:"oauth_2_client_id"` + Oauth2ClientSecret string `json:"oauth_2_client_secret"` + SSHHostKey string `json:"ssh_host_key"` + SkipSSHHostKeyCheck bool `json:"skip_ssh_host_key_check"` } type CreateRemoteSourceHandler struct { @@ -57,12 +59,14 @@ func (h *CreateRemoteSourceHandler) ServeHTTP(w http.ResponseWriter, r *http.Req } creq := &action.CreateRemoteSourceRequest{ - Name: req.Name, - APIURL: req.APIURL, - Type: req.Type, - AuthType: req.AuthType, - Oauth2ClientID: req.Oauth2ClientID, - Oauth2ClientSecret: req.Oauth2ClientSecret, + Name: req.Name, + APIURL: req.APIURL, + Type: req.Type, + AuthType: req.AuthType, + Oauth2ClientID: req.Oauth2ClientID, + Oauth2ClientSecret: req.Oauth2ClientSecret, + SSHHostKey: req.SSHHostKey, + SkipSSHHostKeyCheck: req.SkipSSHHostKeyCheck, } rs, err := h.ah.CreateRemoteSource(ctx, creq) if httpError(w, err) { diff --git a/internal/services/gateway/webhook.go b/internal/services/gateway/webhook.go index 226433f..2ba3b66 100644 --- a/internal/services/gateway/webhook.go +++ b/internal/services/gateway/webhook.go @@ -115,6 +115,7 @@ func (h *webhooksHandler) handleWebhook(r *http.Request) (int, string, error) { var webhookData *types.WebhookData var sshPrivKey string var cloneURL string + var sshHostKey string var skipSSHHostKeyCheck bool var runType types.RunType variables := map[string]string{} @@ -147,7 +148,12 @@ func (h *webhooksHandler) handleWebhook(r *http.Request) (int, string, error) { } sshPrivKey = project.SSHPrivateKey - skipSSHHostKeyCheck = project.SkipSSHHostKeyCheck + sshHostKey = rs.SSHHostKey + // use remotesource skipSSHHostKeyCheck config and override with project config if set to true there + skipSSHHostKeyCheck = rs.SkipSSHHostKeyCheck + if project.SkipSSHHostKeyCheck { + skipSSHHostKeyCheck = project.SkipSSHHostKeyCheck + } runType = types.RunTypeProject webhookData, err = gitSource.ParseWebhook(r) if err != nil { @@ -258,6 +264,9 @@ func (h *webhooksHandler) handleWebhook(r *http.Request) (int, string, error) { "AGOLA_GIT_COMMITSHA": webhookData.CommitSHA, } + if sshHostKey != "" { + env["AGOLA_SSHHOSTKEY"] = sshHostKey + } if skipSSHHostKeyCheck { env["AGOLA_SKIPSSHHOSTKEYCHECK"] = "1" } diff --git a/internal/services/types/types.go b/internal/services/types/types.go index 89e1483..f5da0b8 100644 --- a/internal/services/types/types.go +++ b/internal/services/types/types.go @@ -155,6 +155,10 @@ type RemoteSource struct { // Oauth2 data Oauth2ClientID string `json:"client_id,omitempty"` Oauth2ClientSecret string `json:"client_secret,omitempty"` + + SSHHostKey string `json:"ssh_host_key,omitempty"` // Public ssh host key of the remote source + + SkipSSHHostKeyCheck bool `json:"skip_ssh_host_key_check,omitempty"` } func SourceSupportedAuthTypes(rsType RemoteSourceType) []RemoteSourceAuthType {