in pkg/middleware/recorder.go [152:300]
func NewRecorder(cassetteName string) (*Recorder, error) {
rec, err := gorecorder.NewWithOptions(&gorecorder.Options{
CassetteName: cassetteName,
Mode: gorecorder.ModeRecordOnce,
SkipRequestLatency: true,
RealTransport: utils.DefaultTransport,
})
if err != nil {
return nil, err
}
rec.SetReplayableInteractions(false)
var tokenCredential azcore.TokenCredential
var subscriptionID string
var tenantID string
var clientID string
var clientSecret string
var clientCertPath string
var clientCertPasswd string
if rec.IsNewCassette() {
subscriptionID = os.Getenv("AZURE_SUBSCRIPTION_ID")
if subscriptionID == "" {
return nil, errors.New("required environment variable AZURE_SUBSCRIPTION_ID was not supplied")
}
tokenCredential, err = azidentity.NewDefaultAzureCredential(nil)
if err != nil {
return nil, err
}
tenantID = os.Getenv(utils.AzureTenantID)
if tenantID == "" {
return nil, errors.New("required environment variable AZURE_TENANT_ID was not supplied")
}
clientID = os.Getenv(utils.AzureClientID)
if clientID == "" {
return nil, errors.New("required environment variable AZURE_CLIENT_ID was not supplied")
}
clientSecret = os.Getenv("AZURE_CLIENT_SECRET")
clientCertPath = os.Getenv("AZURE_CLIENT_CERT_PATH")
clientCertPasswd = os.Getenv("AZURE_CLIENT_CERT_PASSWD")
if clientSecret == "" && clientCertPath == "" {
return nil, errors.New("either AZURE_CLIENT_SECRET or AZURE_CLIENT_CERT_PATH must be supplied")
}
} else {
// if we are replaying, we won't need auth
// and we use a dummy subscription ID
subscriptionID = uuid.Nil.String()
tokenCredential = DummyTokenCredential(func(ctx context.Context, options policy.TokenRequestOptions) (azcore.AccessToken, error) {
return azcore.AccessToken{}, nil
})
tenantID = "tenantid"
clientID = "clientid"
clientSecret = "clientsecret"
}
rec.AddHook(func(i *cassette.Interaction) error {
//ignore inprogress requests
if strings.Contains(i.Response.Body, "\"status\": \"InProgress\"") {
i.DiscardOnSave = true
return nil
}
if !strings.EqualFold(tenantID, "tenantid") {
i.Request.URL = strings.Replace(i.Request.URL, tenantID, "tenantid", -1)
i.Request.Body = strings.Replace(i.Request.Body, tenantID, "tenantid", -1)
i.Response.Body = strings.Replace(i.Response.Body, tenantID, "tenantid", -1)
if i.Request.Form.Has("tenant_id") {
i.Request.Form.Set("tenant_id", tenantID)
}
}
if !strings.EqualFold(clientID, "clientid") {
i.Request.URL = strings.Replace(i.Request.URL, clientID, "clientid", -1)
i.Request.Body = strings.Replace(i.Request.Body, clientID, "clientid", -1)
i.Response.Body = strings.Replace(i.Response.Body, clientID, "clientid", -1)
if i.Request.Form.Has("client_id") {
i.Request.Form.Set("client_id", "clientid")
}
}
if len(clientSecret) > 0 && !strings.EqualFold(clientSecret, "clientsecret") {
i.Request.URL = strings.Replace(i.Request.URL, clientSecret, "clientsecret", -1)
i.Request.Body = strings.Replace(i.Request.Body, clientSecret, "clientsecret", -1)
i.Response.Body = strings.Replace(i.Response.Body, clientSecret, "clientsecret", -1)
if i.Request.Form.Has("client_secret") {
i.Request.Form.Set("client_secret", "clientsecret")
}
}
if i.Request.Form.Has("client_assertion") {
i.Request.Form.Set("client_assertion", "clientassertion")
i.Request.Body = "client_assertion=clientassertion&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_id=clientid&client_info=1&grant_type=client_credentials&scope=https%3A%2F%2Fmanagement.azure.com%2F.default+openid+offline_access+profile"
}
if strings.Contains(i.Response.Body, "access_token") {
i.Response.Body = `{"token_type":"Bearer","expires_in":86399,"ext_expires_in":86399,"access_token":"faketoken"}`
}
if strings.Contains(i.Response.Body, "-----BEGIN RSA PRIVATE KEY-----") {
i.Response.Body = "{\r\n \"privateKey\": \"-----BEGIN RSA PRIVATE KEY-----\\r\\n\\r\\n-----END RSA PRIVATE KEY-----\\r\\n\",\r\n \"publicKey\": \"ssh-rsa {KEY} generated-by-azure\",\r\n \"id\": \"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/AKS-CIT-SSHPUBLICKEYRESOURCE/providers/Microsoft.Compute/sshPublicKeys/testResource\"\r\n}"
}
if strings.Contains(i.Response.Body, "skiptoken") {
re := regexp.MustCompile(`skiptoken=(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?`)
i.Response.Body = string(re.ReplaceAll([]byte(i.Response.Body), []byte("skiptoken=skiptoken")))
}
if strings.Contains(i.Request.URL, "skiptoken") {
re := regexp.MustCompile(`skiptoken=(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}%3D%3D|[A-Za-z0-9+/]{3}%3D)?`)
i.Request.URL = string(re.ReplaceAll([]byte(i.Request.URL), []byte("skiptoken=skiptoken")))
}
if strings.Contains(i.Request.RequestURI, "skiptoken") {
re := regexp.MustCompile(`skiptoken=(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}%3D%3D|[A-Za-z0-9+/]{3}%3D)?`)
i.Response.Body = string(re.ReplaceAll([]byte(i.Response.Body), []byte("skiptoken=skiptoken")))
}
for _, header := range requestHeadersToRemove {
delete(i.Request.Headers, header)
}
for _, header := range responseHeadersToRemove {
delete(i.Response.Headers, header)
}
i.Request.Body = hideRecordingData(i.Request.Body)
i.Response.Body = hideRecordingData(i.Response.Body)
i.Request.URL = hideUUID(i.Request.URL)
for _, values := range i.Request.Headers {
for i := range values {
values[i] = hideUUID(values[i])
}
}
for _, values := range i.Response.Headers {
for i := range values {
values[i] = hideUUID(values[i])
}
}
return nil
}, gorecorder.BeforeSaveHook)
return &Recorder{
credential: tokenCredential,
rec: rec,
subscriptionID: subscriptionID,
tenantID: tenantID,
clientID: clientID,
clientSecret: clientSecret,
clientCertPath: clientCertPath,
clientCertPasswd: clientCertPasswd,
}, nil
}