diff --git a/.github/workflows/clear-notify-cache.yaml b/.github/workflows/clear-notify-cache.yaml new file mode 100644 index 000000000..47276762e --- /dev/null +++ b/.github/workflows/clear-notify-cache.yaml @@ -0,0 +1,37 @@ +name: Reusable Clear Cache Workflow + +on: + workflow_call: + inputs: + environment: + required: true + type: string + secrets: + CACHE_CLEAR_USER_NAME: + required: true + CACHE_CLEAR_CLIENT_SECRET: + required: true + API_URL: + required: true + +jobs: + clear-cache: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v2 + with: + node-version: "14" + + - name: Install dependencies + run: npm install jsonwebtoken axios + + - name: Call API to clear cache + env: + CACHE_CLEAR_USER_NAME: ${{ secrets.CACHE_CLEAR_USER_NAME }} + CACHE_CLEAR_CLIENT_SECRET: ${{ secrets.CACHE_CLEAR_CLIENT_SECRET }} + API_URL: ${{ secrets.API_URL }} + run: node scripts/clear-cache.js diff --git a/.github/workflows/merge_to_main_staging.yaml b/.github/workflows/merge_to_main_staging.yaml index 46b2c4d38..beb99777d 100644 --- a/.github/workflows/merge_to_main_staging.yaml +++ b/.github/workflows/merge_to_main_staging.yaml @@ -60,7 +60,7 @@ jobs: with: config_file: /var/tmp/staging.ovpn client_key: ${{ secrets.STAGING_OVPN_CLIENT_KEY }} - echo_config: false + echo_config: false - name: Decrypt staging env run: | @@ -128,4 +128,12 @@ jobs: if: ${{ failure() }} run: | json="{'text':' Manifests Merge To Staging CI is failing in !'}" - curl -X POST -H 'Content-type: application/json' --data "$json" ${{ secrets.SLACK_WEBHOOK }} \ No newline at end of file + curl -X POST -H 'Content-type: application/json' --data "$json" ${{ secrets.SLACK_WEBHOOK }} + + clear-cache: + needs: kubectl-apply + uses: ./.github/workflows/clear-notify-cache.yaml + secrets: + CACHE_CLEAR_USER_NAME: ${{ secrets.STAGING_CACHE_CLEAR_USER_NAME }} + CACHE_CLEAR_CLIENT_SECRET: ${{ secrets.STAGING_CACHE_CLEAR_CLIENT_SECRET }} + API_URL: ${{ secrets.STAGING_API_URL }} diff --git a/scripts/clear-cache.js b/scripts/clear-cache.js new file mode 100644 index 000000000..aa6d55b54 --- /dev/null +++ b/scripts/clear-cache.js @@ -0,0 +1,38 @@ +const jwt = require('jsonwebtoken'); +const axios = require('axios'); + +const payload = { + iss: process.env.CACHE_CLEAR_USER_NAME, + iat: Math.floor(Date.now() / 1000), + exp: Math.floor(Date.now() / 1000) + (60 * 60), // 1 hour from now +}; +const options = { + algorithm: 'HS256', + header: { + alg: 'HS256', + typ: 'JWT' + } +}; + +const token = jwt.sign(payload, process.env.CACHE_CLEAR_CLIENT_SECRET, options); + +try { + const decoded = jwt.verify(token, process.env.CACHE_CLEAR_CLIENT_SECRET, { algorithms: ['HS256'] }); + console.log('Token verified successfully. Payload:', decoded); +} catch (err) { + console.error('Token verification failed:', err.message); +} + +axios.post(process.env.API_URL + '/cache-clear', null, { + headers: { + 'Authorization': `Bearer ${token}`, + 'Content-Type': 'application/json' + } +}) + .then(response => { + console.log('API call successful:', response.data); + }) + .catch(error => { + console.error('Error calling API:', error.response ? error.response.data : error.message); + process.exit(1); + }); \ No newline at end of file diff --git a/scripts/clear_cache.js b/scripts/clear_cache.js deleted file mode 100644 index e27210786..000000000 --- a/scripts/clear_cache.js +++ /dev/null @@ -1,63 +0,0 @@ -const { exec } = require('child_process'); -const crypto = require('crypto'); - -// Function to base64url encode -function base64urlEncode(str) { - return Buffer.from(str) - .toString('base64') - .replace(/=/g, '') - .replace(/\+/g, '-') - .replace(/\//g, '_'); -} - -// Function to create HMAC SHA-256 signature -function createHmacSignature(secret, data) { - return crypto.createHmac('sha256', secret).update(data).digest('base64') - .replace(/=/g, '') - .replace(/\+/g, '-') - .replace(/\//g, '_'); -} - -// Parse command-line arguments -const args = process.argv.slice(2); -const adminUsername = args[0]; -const adminSecret = args[1]; -const apiEndpoint = args[2]; - -if (!adminUsername || !adminSecret || !apiEndpoint) { - console.error('Usage: node clear_cache.js '); - process.exit(1); -} - -// Create header and payload -const header = { alg: "HS256", typ: "JWT" }; -const payload = { - iss: adminUsername, - iat: Math.round(Date.now() / 1000) -}; - -// Base64url encode header and payload -const headerEncoded = base64urlEncode(JSON.stringify(header)); -const payloadEncoded = base64urlEncode(JSON.stringify(payload)); - -// Create the signature -const signature = createHmacSignature(adminSecret, `${headerEncoded}.${payloadEncoded}`); - -// Create the full token -const jwt = `${headerEncoded}.${payloadEncoded}.${signature}`; - -// Use curl to call the API -const curlCommand = `curl -s -o /dev/null -w "%{http_code}" -X POST ${apiEndpoint} -H "Authorization: Bearer ${jwt}"`; - -exec(curlCommand, (error, stdout, stderr) => { - if (error) { - console.error(`Error calling the cache-clear API.`); - return; - } - const httpCode = stdout.trim(); - if (httpCode === '201') { - console.log('Cache cleared successfully.'); - } else { - console.error(`Failed to clear cache. HTTP status code: ${httpCode}`); - } -}); \ No newline at end of file