diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 000000000..78dfac3a7 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,14 @@ +FROM mcr.microsoft.com/dotnet/sdk:6.0 + +RUN apt-get update + +RUN apt-get install -y iputils-ping procps + +RUN echo Installing Code Generator CLI + +RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - +RUN apt-get install -y nodejs build-essential default-jre +RUN npm install @openapitools/openapi-generator-cli -g + +RUN echo Done! + diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 000000000..49e36288f --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,33 @@ +{ + "name": "Dev Container", + "dockerFile": "Dockerfile", + "runArgs": [ "--cap-add=SYS_PTRACE", "--security-opt", "seccomp=unconfined" ], + + // Use 'settings' to set *default* container specific settings.json values on container create. + // You can edit these settings after create using File > Preferences > Settings > Remote. + // "settings": { + // "terminal.integrated.shell.linux": "/bin/bash", + // "lldb.executable": "/usr/bin/lldb" + // }, + + // Use 'appPort' to create a container with published ports. If the port isn't working, be sure + // your server accepts connections from all interfaces (0.0.0.0 or '*'), not just localhost. + // "appPort": [], + + // Uncomment the next line to run commands after the container is created. + // "postCreateCommand": "rustc --version", + + // Comment out the next line to run as root + // "remoteUser": "vscode", + + // Uncomment the line below to mount your local usersecrets into the devcontainer from a Windows OS + // "mounts": [ "source=${localEnv:APPDATA}/Microsoft/UserSecrets,target=/root/.microsoft/usersecrets,type=bind" ], + + // Uncomment the line below to mount your local usersecrets into the devcontainer from a Mac/Linux OS + // "mounts": [ "source=${localEnv:HOME}/.microsoft/usersecrets,target=/root/.microsoft/usersecrets,type=bind" ], + + // Add the IDs of extensions you want installed when the container is created in the array below. + "extensions": [ + "ms-dotnettools.csharp" + ] +} diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..e2f16e900 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,7 @@ +# This is a comment. +# Each line is a file pattern followed by one or more owners. + +# Setting build up so that license changes and CODEOWNERS changes +# require admin approval. + +* @vaughanknight diff --git a/.github/ISSUE_TEMPLATE/bug-report.yml b/.github/ISSUE_TEMPLATE/bug-report.yml new file mode 100644 index 000000000..a61de6a02 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.yml @@ -0,0 +1,50 @@ +name: Bug Report +description: File a bug report +title: "[Bug]: " +labels: ["bug", "triage"] +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this bug report! + - type: input + id: contact + attributes: + label: Contact Details + description: How can we get in touch with you if we need more info? + placeholder: ex. email@example.com + validations: + required: false + - type: textarea + id: what-happened + attributes: + label: What happened? + description: Also tell us, what did you expect to happen? + placeholder: Tell us what you see! + value: "A bug happened!" + validations: + required: true + - type: dropdown + id: client + attributes: + label: client + description: What client of the Carbon Aware SDK are you running? + options: + - WebAPI (Default) + - CLI + validations: + required: true + - type: textarea + id: logs + attributes: + label: Relevant log output + description: Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. + render: shell + - type: checkboxes + id: terms + attributes: + label: Code of Conduct + description: By submitting this issue, you agree to follow the [Way We Work](https://github.com/Green-Software-Foundation/standards_wg/blob/main/the_way_we_work.md) + options: + - label: I agree to follow this project's Code of Conduct + required: true \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..0c1b0edea --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Green Software Foundation Membership Enquiries + url: https://greensoftware.foundation/join-us/ + about: Join the Green Software Foundation + - name: Carbon Aware SDK Project Proposal + url: https://greensoftware.foundation/projects/carbon-aware-sdk + about: GSF Page on Carbon Aware SDK \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/contribution-issue.yml b/.github/ISSUE_TEMPLATE/contribution-issue.yml new file mode 100644 index 000000000..908ea3312 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/contribution-issue.yml @@ -0,0 +1,37 @@ +name: Feature Contribution +description: Contribute a Feature +title: "[Feature Contribution]: " +labels: ["feature", "triage"] +assignees: + - vaughanknight +body: + - type: markdown + attributes: + value: | + Thank you for wanting to contribute to the Carbon Aware SDK! Please fill out this Issue Template with your feature contribution. + - type: textarea + id: feature-desc + attributes: + label: What happened? + description: Please Describe the need for the feature + placeholder: User stories, feature specifications, contribution benefits. + value: "Feature XYZ will perform function ABC and enable development for project 123." + validations: + required: true + - type: checkboxes + id: terms + attributes: + label: Code of Conduct + description: By submitting this issue, you agree to follow the [Way We Work](https://github.com/Green-Software-Foundation/standards_wg/blob/main/the_way_we_work.md) + options: + - label: I agree to follow this project's Code of Conduct + required: true + - type: checkboxes + id: commitment + attributes: + label: Feature Commitment + description: By submitting this issue, you commit to contributing the feature outlined here. + options: + - label: I commit to contributing this feature as a PR and working with the GSF to merge this feature into the Carbon Aware SDK. + required: true + \ No newline at end of file diff --git a/.github/codecov.yaml b/.github/codecov.yaml new file mode 100644 index 000000000..0f3091b93 --- /dev/null +++ b/.github/codecov.yaml @@ -0,0 +1,20 @@ +codecov: + require_ci_to_pass: no + +coverage: + precision: 2 + round: down + range: "70...100" + +parsers: + gcov: + branch_detection: + conditional: yes + loop: yes + method: no + macro: no + +comment: + layout: "reach,diff,flags,files" + behavior: default + require_changes: no \ No newline at end of file diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..9fa9ceb3e --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,27 @@ +Issue Number: (Link to Github Issue or Azure Dev Ops Task/Story) + +## Summary +One sentence summary of PR + +## Changes + +- List of comprehensive changes + +## Checklist + +- [ ] Local Tests Passing? +- [ ] CICD and Pipeline Tests Passing? +- [ ] Added any new Tests? +- [ ] Documentation Updates Made? +- [ ] Are there any API Changes? If yes, please describe below. +- [ ] This is not a breaking change. If it is, please describe it below. + +## Are there API Changes? +If yes, what are the expected API Changes? Please link to an API-Comparison workflow with the API Diff. + +## Is this a breaking change? +If yes, what workflow does this break? + +## Anything else? +Other comments, collaborators, etc. +This PR Closes Issue # diff --git a/.github/workflows/build-cli-dotnet.yaml b/.github/workflows/build-cli-dotnet.yaml new file mode 100644 index 000000000..86e667aba --- /dev/null +++ b/.github/workflows/build-cli-dotnet.yaml @@ -0,0 +1,34 @@ +name: BUILD CLI in DOTNET + +on: + push: + paths: + - 'src/**' + - '.github/workflows/**' + pull_request: + branches: [ dev, main ] + paths: + - 'src/**' + +jobs: + build: + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./src + steps: + + - uses: actions/checkout@v2 + - name: Setup .NET + uses: actions/setup-dotnet@v1 + with: + dotnet-version: 6.0.x + + - name: Restore dependencies + run: dotnet restore + + - name: Build + run: dotnet build --no-restore + + - name: Unit Tests + run: dotnet test --no-build --verbosity normal \ No newline at end of file diff --git a/.github/workflows/build-webapi.yaml b/.github/workflows/build-webapi.yaml new file mode 100644 index 000000000..acb7fd5de --- /dev/null +++ b/.github/workflows/build-webapi.yaml @@ -0,0 +1,130 @@ +name: Docker Web API Build + +on: + push: + branches: [ dev, main ] + pull_request: + branches: [ dev, main ] + paths: + - 'src/**' + - '.github/workflows/**' + +env: + DOCKERFILE_PATH: "CarbonAware.WebApi/src/Dockerfile" + HEALTH_ENDPOINT: "0.0.0.0:8080/health" + DATA_ENDPOINT: "0.0.0.0:8080/emissions/bylocation?location=eastus" + DLL_FILE_PATH: "./bin/Release/net6.0/CarbonAware.WebApi.dll" + DOTNET_SRC_DIR: "./src" + +jobs: + container-dotnet-build: + runs-on: ubuntu-latest + container: + image: mcr.microsoft.com/dotnet/sdk:6.0 + steps: + - uses: actions/checkout@v3 + + - name: Setup .NET Core SDK 6 + uses: actions/setup-dotnet@v2 + with: + dotnet-version: '6.0.x' + include-prerelease: false + + - name: Install dependencies + run: dotnet restore + working-directory: ${{ env.DOTNET_SRC_DIR }} + + - name: Install tools + run: dotnet tool restore + working-directory: ${{ env.DOTNET_SRC_DIR }}/CarbonAware.WebApi/src + + - name: Build + run: dotnet build --configuration Release --no-restore + working-directory: ${{ env.DOTNET_SRC_DIR }} + + - name: Unit Test + Code Coverage + run: dotnet test --filter TestCategory=Unit --no-restore --verbosity normal /p:CollectCoverage=true /p:CoverletOutputFormat=json + working-directory: ${{ env.DOTNET_SRC_DIR }} + + - name: Integration Test + Code Coverage + run: dotnet test --filter TestCategory=Integration --no-restore --verbosity normal /p:CollectCoverage=true /p:MergeWith=\"./coverage.json\" /p:CoverletOutputFormat=\"json,opencover\" + working-directory: ${{ env.DOTNET_SRC_DIR }} + + - name: Codecov + uses: codecov/codecov-action@v2 + with: + directory: ${{ env.DOTNET_SRC_DIR }} + + - name: Generate Open API + run: dotnet tool run swagger tofile --output ./api/v1/swagger.yaml --yaml ${{ env.DLL_FILE_PATH }} v1 + working-directory: ./src/CarbonAware.WebApi/src + + - name: Upload artifact + uses: actions/upload-artifact@v1 + with: + name: pr-swagger.yaml + path: src/CarbonAware.WebApi/src/api/v1/swagger.yaml + + container-validation: + runs-on: ubuntu-latest + steps: + - name: Checkout Repository + uses: actions/checkout@v2 + + - name: Docker Target Final + run: docker build . -f ${DOCKERFILE_PATH} -t ca-api + working-directory: ./src + + - name: Docker Run Container + run: | + docker run -d --name runnable-container -p 8080:80 ca-api + docker container ls + + - name: Docker WGET Health Endpoint + run: | + wget -t 5 --waitretry=5 ${HEALTH_ENDPOINT} + + - name: Docker WGET Data Endpoint + run: | + wget -t 5 --waitretry=5 ${DATA_ENDPOINT} + + api-comparison: + needs: container-dotnet-build + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./src/CarbonAware.WebApi/src + container: + image: mcr.microsoft.com/dotnet/sdk + steps: + - name: Checkout Dev Branch + uses: actions/checkout@v3 + with: + ref: dev + - name: Setup .NET Core SDK 6 + uses: actions/setup-dotnet@v2 + with: + dotnet-version: '6.0.x' + include-prerelease: false + - name: Install dependencies + run: dotnet restore + working-directory: ${{ env.DOTNET_SRC_DIR }} + - name: Install tools + run: dotnet tool restore + - name: Build + run: dotnet build --configuration Release --no-restore + working-directory: ${{ env.DOTNET_SRC_DIR }} + - name: Generate Open API + run: dotnet tool run swagger tofile --output ./api/v1/swagger.yaml --yaml ${{ env.DLL_FILE_PATH }} v1 + - name: Upload dev artifact + uses: actions/upload-artifact@v1 + with: + name: dev-swagger.yaml + path: src/CarbonAware.WebApi/src/api/v1/swagger.yaml + - uses: actions/download-artifact@v3 + with: + name: pr-swagger.yaml + path: ./src/CarbonAware.WebApi/src/api/v1/pr-swagger.yaml + - name: API Diff Comparison + run: | + diff ./api/v1/pr-swagger.yaml ./api/v1/swagger.yaml && echo "No API Changes detected" || echo "::warning:: API Changed" diff --git a/.github/workflows/codeQL-analysis.yaml b/.github/workflows/codeQL-analysis.yaml new file mode 100644 index 000000000..14e3d69f3 --- /dev/null +++ b/.github/workflows/codeQL-analysis.yaml @@ -0,0 +1,81 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "Code Security Scan with CodeQL" + +on: + push: + pull_request: + # The branches below must be a subset of the branches above + branches: [ dev, main ] + schedule: + - cron: '42 23 * * 5' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'csharp' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Learn more about CodeQL language support at https://git.io/codeql-language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + - name: Setup .NET + uses: actions/setup-dotnet@v1 + with: + dotnet-version: '6.0' + + - name: Restore dependencies + run: dotnet restore + working-directory: './src/' + - name: Build + run: dotnet build --no-restore + working-directory: './src/' + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + #- name: Autobuild + # uses: github/codeql-action/autobuild@v1 + + # ℹ️ Command-line programs to run using the OS shell. + # πŸ“š https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 diff --git a/.github/workflows/dev_carbon-aware-api.yml b/.github/workflows/dev_carbon-aware-api.yml new file mode 100644 index 000000000..9eb8aba88 --- /dev/null +++ b/.github/workflows/dev_carbon-aware-api.yml @@ -0,0 +1,59 @@ +# Docs for the Azure Web Apps Deploy action: https://github.com/Azure/webapps-deploy +# More GitHub Actions for Azure: https://github.com/Azure/actions + +name: Build and deploy ASP.Net Core app to Azure Web App - carbon-aware-api + +on: + push: + branches: + - dev + workflow_dispatch: + +jobs: + build: + runs-on: windows-latest + + steps: + - uses: actions/checkout@v2 + + - name: Set up .NET Core + uses: actions/setup-dotnet@v1 + with: + dotnet-version: '6.0.x' + include-prerelease: true + + - name: Build with dotnet + working-directory: src/CarbonAware.WebApi/src + run: dotnet build --configuration Release + + - name: dotnet publish + working-directory: src/CarbonAware.WebApi/src + run: dotnet publish -c Release -o ${{env.DOTNET_ROOT}}/myapp + + - name: Upload artifact for deployment job + uses: actions/upload-artifact@v2 + with: + name: CarbonAwareApi + path: ${{env.DOTNET_ROOT}}/myapp + + deploy: + runs-on: windows-latest + needs: build + environment: + name: 'Production' + url: ${{ steps.deploy-to-webapp.outputs.webapp-url }} + + steps: + - name: Download artifact from build job + uses: actions/download-artifact@v2 + with: + name: CarbonAwareApi + + - name: Deploy to Azure Web App + id: deploy-to-webapp + uses: azure/webapps-deploy@v2 + with: + app-name: 'carbon-aware-api' + slot-name: 'Production' + publish-profile: ${{ secrets.AZUREAPPSERVICE_PUBLISHPROFILE_D9BE266F4F034E79818711107BC7DDC5 }} + package: . diff --git a/.github/workflows/run-sdkCLI-githubaction.yml b/.github/workflows/run-sdkCLI-githubaction.yml new file mode 100644 index 000000000..76d4687fc --- /dev/null +++ b/.github/workflows/run-sdkCLI-githubaction.yml @@ -0,0 +1,28 @@ +name: using CarboneAware Github action in sample pipeline + +on: + push: + paths: + - 'src/**' + - '.github/workflows/**' + pull_request: + branches: [ dev, main ] + paths: + - 'src/**' + + +jobs: + build: + runs-on: ubuntu-latest + steps: + - name: CarboneAWare metrics + id: carboneaware-metrics + uses: Green-Software-Foundation/carbon-aware-sdk@sdkCLI-githubaction # here "sdkCLI-githubaction" is the name of the branch + with: + location: westeurope,francecentral,westus + #config: /carbon-aware.json + #fromTime: + #toTime: + + - name: Deplpoy Workload to Selected Region + run: echo deploying ML Training Job to Region "${{ steps.carboneaware-metrics.outputs.LowestEmissionsLocation}}" diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..a5bcc250f --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +~$* +*.tmp +*.dll +*.pdb +*.suo +.suo +.vs + +bin +out +obj +build +TestResults + +/src/clients/generated + +# Build-gen'd OpenAPI Spec +src/CarbonAware.WebApi/src/CarbonAware.WebApi.xml + +# Include ONLY launch/task files in .vscode +!.vscode/ +.vscode/* +!.vscode/launch.json +!.vscode/tasks.json +.DS_Store + +samples/watttime-registration/settings.py + +# exclude local settings to easily set up your repo from the appsettings.local.json.temlpate +appsettings.local.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 000000000..254cce3e8 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,36 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": ".NET Core Launch (web)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + "program": "${workspaceFolder}/src/CarbonAware.WebApi/src/bin/Debug/net6.0/CarbonAware.WebApi.dll", + "args": [], + "cwd": "${workspaceFolder}/src/CarbonAware.WebApi/", + "stopAtEntry": false, + "serverReadyAction": { + "action": "openExternally", + "pattern": "\\bNow listening on:\\s+(https?://\\S+)", + "uriFormat": "%s/swagger" + }, + "env": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "sourceFileMap": { + "/Views": "${workspaceFolder}/Views" + } + }, + + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach" + } + + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..74b3341d7 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "omnisharp.useModernNet": true +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 000000000..27e517a12 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,46 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/src/CarbonAware.WebApi/src/CarbonAware.WebApi.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": ".NET Core Test with debugger", + "type": "process", + "isBackground": true, + "command": "dotnet", + "args": [ + "test", + "CarbonAwareSDK.sln" + ], + "options": + { + "cwd": "${workspaceFolder}/src/", + "env": + { + "VSTEST_HOST_DEBUG": "1" + }, + }, + "group": "test", + "presentation": + { + "echo": true, + "reveal": "always", + "focus": false, + "panel": "shared" + }, + "problemMatcher": [] + } + ] +} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..9128a0f36 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,42 @@ +# GSF Member Contribution Guide + +Welcome to the GSF Carbon Aware SDK, and thank you for contributing to this project. This guide outlines the steps for working within the Carbon Aware SDK and the approved contribution process that members should follow. + +**Please contact the project owners for individual contributions. Working Group meetings and the internal communication channels are only open to GSF Members.** + +## Table of Contents + +- [GSF Member Contribution Guide](#gsf-member-contribution-guide) + - [Table of Contents](#table-of-contents) + - [Summary Steps](#summary-steps) + - [Public Issues](#public-issues) + +## Summary Steps + +For the following: + +"Member and "Contributor" refer to the GSF member looking to make a feature contribution. +"Chair" refers to the Chair, Co-Chair or other accountable authority within GSF. + +1. Submit a Public Issue using the Issue Template +2. The Issue will be looked at by a Chair and approved. +3. The Contributor is assigned an "Approved Reviewer" who will help shepherd the feature into the GSF Repository +4. Fork `GSF/carbon-aware-sdk/dev` into a member repository, `member/carbon-aware-sdk/dev` +5. Open a Draft PR from `member/dev` into `GSF/carbon-aware-sdk/dev` using the PR Template +6. Once development is over, the Approved Reviewer pushes the PR into the "Ready for Review" state +7. If the Chair accepts the PR, it merges into `GSF/carbon-aware-sdk/dev` + +## Public Issues + +All contributions to the GSF are tracked through public issues. Please make a public issue and fill out details on the proposed feature contribution. The issue serves as a commitment by the contributor to developing the feature. + +The Issue is **not** a feature request, but tracks expected feature work. Please do **not** open an issue to request features. + +## Collaborating With the WG + +1. Create a [new Issue](https://github.com/Green-Software-Foundation/standards_wg/issues/new) +2. Discuss Issue with WG --> Create PR if required +3. PR to be submitted against the **DEV feature branch** +4. PR discussed with the WG. If agreed, the WG Chair will merge into **DEV Feature branch** +![GSF Single-Trunk Based Branch Flow](/docs/images/single-trunk-branch.svg) +5. See [The Way we Work](https://github.com/Green-Software-Foundation/standards_wg/blob/main/the_way_we_work.md) for futher details. diff --git a/GettingStarted.md b/GettingStarted.md new file mode 100644 index 000000000..8bbebc6e7 --- /dev/null +++ b/GettingStarted.md @@ -0,0 +1,269 @@ +# Getting Started + +This SDK has several entry points: + +- You can run the application using the [CLI](./src/CarbonAware.CLI). + +- You can build a container containing the [WebAPI](./src/CarbonAware.WebApi) and connect via REST requests. + +- (Future) You can install the Nuget package and make requests directly. ([tracked here](https://github.com/Green-Software-Foundation/carbon-aware-sdk/issues/40)) + +Each of these has configuration requirements which are detailed below. You can also visit the [quickstart.md](docs/quickstart.md) guide for a step-by-step process for running the CLI locally, deploying the Web API locally, polling the API via HTTP requests or generating and using client libraries (Python example). + +## Pre-requisites + +Make sure you have installed the following pre-requisites: + +- dotnet core SDK [https://dotnet.microsoft.com/en-us/download](https://dotnet.microsoft.com/en-us/download) +- WattTime account - See [instruction on WattTime](https://www.watttime.org/api-documentation/#register-new-user) for details (or use our python samples as described [here](samples/watttime-registration/readme.md)). + +## Data Sources + +We intend to support multiple data sources for carbon data. At this time, only a JSON file and [WattTime](https://www.watttime.org/) are supported. To use WattTime data, you'll need to acquire a license from them and set the appropriate configuration information. + +## Configuration + +This project uses standard [Microsoft.Extensions.Configuration](https://docs.microsoft.com/en-us/dotnet/core/extensions/configuration) mechanisms. + +The WebAPI project uses standard configuration sources provided by [ASPNetCore](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/). Please review this link to understand how configuration is loaded and the priority of that configuration. + +Please note that configuration is hierarchical. The last configuration source loaded that contains a configuration value will be the value that's used. This means that if the same configuration value is found in both appsettings.json and as an environment variable, the value from the environment variable will be the value that's applied. + +### Configuration options + +#### Environment variables +When adding values via environment variables, we recommend that you use the double underscore form, rather than the colon form. Colons won't work in non-windows environment. For example: + +```bash + CarbonAwareVars__CarbonIntensityDataSource="WattTime" +``` + +Note that double underscores are used to represent dotted notation or child elements that you see in the JSON below. For example, to set proxy information using environment variables, you'd do this: + +```bash + CarbonAwareVars__Proxy__UseProxy +``` + +#### Local project settings + +You have the possibility to use an untracked local settings file to override the project settings (that is loaded after the environement variables and will therefore superseed any variables of the same name). + +Todo so, rename a copy of the local template called `appsettings.local.json.template` to `appsettings.local.json`. +Remove the first line of (invalid comments) and update the variables accordingly. + +### CarbonAwareSDK Specific Configuration + +#### CarbonAwareVars + +Used to configure specific values that affect how the application gets data and the routes exposed. The configuration looks like this: + +```json +{ + "carbonAwareVars": { + "carbonIntensityDataSource": "", + "webApiRoutePrefix": "", + "proxy": { + "useProxy": false, + "url": "", + "username": "", + "password": "" + } + } +} +``` + +##### carbonIntensityDataSource + +Must be one of the following: `None, JSON, WattTime`. + +If set to `WattTime`, WattTime configuration must also be supplied. + +`None` is the default, and if this value is supplied, an exception will be thrown at startup. + +`JSON` will result in the data being loaded from a [json file](./src/CarbonAware.DataSources.Json/test-data-azure-emissions.json) compiled into the project. You should not use these values in production, since they are static and don't represent carbon intensity accurately. + +##### webApiRoutePrefix + +Used to add a prefix to all routes in the WebApi project. Must start with a `/`. Invalid paths will cause an exception to be thrown at startup. + +By default, all controllers are off of the root path. For example: + +```bash +http://localhost/emissions +``` + +If this prefix is set, it will allow calls to controllers using the prefix, which can be helpful for cross cluster calls, or when proxies strip out information from headers. For example, if this value is set to: + +```bash +/mydepartment/myapp +``` + +Then calls can be made that look like this: + +```bash +http://localhost/mydepartment/myapp/emissions +``` + +Note that the controllers still respond off of the root path. + +##### proxy + +This value is used to set proxy information in situations where internet egress requires a proxy. For proxy values to be used `useProxy` must be set to `true`. Other values should be set as needed for your environment. + +### WattTime Configuration + +If using the WattTime datasource, WattTime configuration is required. + +```json +{ + "wattTimeClient":{ + "username": "", + "password": "", + "baseUrl": "https://api2.watttime.org/v2/" + } +} +``` +> **Sign up for a test account:** To create an account, follow these steps : https://www.watttime.org/api-documentation/#best-practices-for-api-usage + +#### username + +The username you receive from WattTime. This value is required when using a WattTime datasource. + +#### password + +The WattTime password for the username supplied. This value is required when using a WattTime datasource. + +#### baseUrl + +The url to use when connecting to WattTime. Defaults to [https://api2.watttime.org/v2/](https://api2.watttime.org/v2/). + +In normal use, you shouldn't need to set this value, but this value can be used to enable integration testing scenarios or if the WattTime url should change in the future. + +### Logging Configuration + +This project is using standard [Microsoft.Extensions.Logging](https://docs.microsoft.com/en-us/dotnet/core/extensions/logging?tabs=command-line). To configure different log levels, please see the documentation at this link. + +### Tracing and Monitoring Configuration +Application monitoring and tracing can be configured using the `TelemetryProvider` variable in the application configuration. + +```bash +CarbonAwareVars__TelemetryProvider="ApplicationInsights" +``` +This application is integrated with Application Insights for monitoring purposes. The telemetry collected in the app is pushed to AppInsights and can be tracked for logs, exceptions, traces and more. To connect to your Application Insights instance, configure the `ApplicationInsights_Connection_String` variable. + +```bash +ApplicationInsights_Connection_String="AppInsightsConnectionString" +``` + +You can alternatively configure using Instrumentation Key by setting the `AppInsights_InstrumentationKey` variable. However, Microsoft is ending technical support for instrumentation key–based configuration of the Application Insights feature soon. ConnectionString-based configuration should be used over InstrumentationKey. For more details, please refer to https://docs.microsoft.com/en-us/azure/azure-monitor/app/sdk-connection-string?tabs=net. + +```bash +AppInsights_InstrumentationKey="AppInsightsInstrumentationKey" +``` + +### Verbosity +You can configure the verbosity of the application error messages by setting the 'VerboseApi' enviroment variable. Typically, you would set this value to 'true' in the development or staging regions. When set to 'true', a detailed stack trace would be presented for any errors in the request. +```bash +CarbonAwareVars__VerboseApi="true" +``` + +### JsonDataConfiguration data file location + +By setting `JsonDataSourceConfiguration__DataFileLocation=newdataset.json` property when `CarbonAwareVars__CarbonIntensityDataSource=JSON` is set or there is not data source defined (`JSON` is by default), the user can specify a file that can contains custom `EmissionsData` sets. The file should be located under the `/src/data/data-sources/` directory that is part of the repository. At build time, all the JSON files under `/src/data/data-sources/` are copied over the destination directory `/src/CarbonAware.WebApi/src/bin/[Debug|Publish]/net6.0/data-sources/json` that is part of the `CarbonAware.WebApi` assembly. Also the file can be placed where the assembly `CarbonAware.WebApi.dll` is located under `data-sources/json` directory. For instance, if the application is installed under `/app`, copy the file to `/app/data-sources/json`. This can be done before the application starts by setting `JsonDataSourceConfiguration__DataFileLocation` environment variable. + +```sh +cp /newdataset.json /app/data-sources/json +export CarbonAwareVars__CarbonIntensityDataSource=JSON +export JsonDataSourceConfiguration__DataFileLocation=newdataset.json +dotnet /app/CarbonAware.WebApi.dll +``` + +As soon a first request is performed, a log entry shows: + +```text +info: CarbonAware.DataSources.Json.JsonDataSource[0] + Reading Json data from /app/data-sources/json/newdataset.json +``` + +### WattTimeClient Caching BalancingAuthority +To improve performance communicating with the WattTime API service, the client caches the data mapping location coordinates to balancing authorities. By default, this data is stored in an in-memory cache for `86400` seconds, but expiration can be configured using the setting `BalancingAuthorityCacheTTL` (Set to "0" to not use cache). The regional boundaries of a balancing authority tend to be stable, but as they can change, the [WattTime documentation](https://www.watttime.org/api-documentation/#determine-grid-region) recommends not caching for longer than 1 month. +```bash +WattTimeClient__BalancingAuthorityCacheTTL="90" +``` + +### Sample Environment Variable Configuration Using WattTime + +```bash +CarbonAwareVars__CarbonIntensityDataSource="WattTime" +CarbonAwareVars__WebApiRoutePrefix="/microsoft/cse/fsi" +CarbonAwareVars__Proxy__UseProxy=true +CarbonAwareVars__Proxy__Url="http://10.10.10.1" +CarbonAwareVars__Proxy__Username="proxyUsername" +CarbonAwareVars__Proxy__Password="proxyPassword" +WattTimeClient__Username="wattTimeUsername" +WattTimeClient__Password="wattTimePassword" +``` + +### Sample Json Configuration Using WattTime + +```json +{ + "carbonAwareVars": { + "carbonIntensityDataSource": "WattTime", + "webApiRoutePrefix": "/microsoft/cse/fsi", + "proxy": { + "useProxy": true, + "url": "http://10.10.10.1", + "username": "proxyUsername", + "password": "proxyPassword" + } + }, + "wattTimeClient":{ + "username": "wattTimeUsername", + "password": "wattTimePassword", + } +} +``` + +## Publish WebAPI with container + +You can publish Web API for Carbon Aware SDK with container. This instruction shows how to build / run container image with [Podman](https://podman.io/). + +### Build container image + +Following commands build the container which named to `carbon-aware-sdk-webapi` from sources. + +```bash +$ cd src +$ podman build -t carbon-aware-sdk-webapi -f CarbonAware.WebApi/src/Dockerfile . +``` + +### Run Web API container + +Carbon Aware SDK Web API publishes the service on Port 80, so you need to map it to local port. Following commands maps it to Port 8080. + +You also need to configure the SDK with environment variables. They are minimum set when you use WattTime as a data source. + +```bash +$ podman run -it --rm -p 8080:80 \ + -e CarbonAwareVars__CarbonIntensityDataSource="WattTime" \ + -e WattTimeClient__Username="wattTimeUsername" \ + -e WattTimeClient__Password="wattTimePassword" \ + carbon-aware-sdk-webapi +``` + +When you success to run the container, you can access it via HTTP client. + +```bash +$ curl -s http://localhost:8080/emissions/forecasts/current?location=westus2 | jq +[ + { + "generatedAt": "2022-08-10T14:10:00+00:00", + "optimalDataPoint": { + "location": "GCPD", + "timestamp": "2022-08-10T20:40:00+00:00", + "duration": 5, + "value": 440.4361702590741 + }, + : +``` diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000..19f87d86c --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Green Software Foundation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 28ed04526..2547f05c9 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,107 @@ +[![Join #CarbonHack22](images/hackathon-banner.png)](https://grnsft.org/hack22) + +**Decarbonize Software. 40K Top Prize.** + +Carbon Hack 22, the best carbon aware software solution built using the [Carbon Aware SDK and API](https://github.com/Green-Software-Foundation/carbon-aware-sdk) wins $40K with a total prize pool of $90K. + +We're running weekly webinars to talk about the hackathon, demo the SDK and API, talk to hackathon participants and answer any questions. To register for the next one click this link πŸ‘‰ https://grnsft.org/hack22/webinar + +For the duration of the hackathon you can try a hosted version of the API with real-data, try it out here πŸ‘‰ https://grnsft.org/hack22/api + +A carbon aware application does more when the electricity is clean, and less when it's dirty. Whether your specialty is machine learning, web, mobile, cloud, IoT or anything in between you can make any type of application carbon aware with the Carbon Aware SDK and API. Review [FAQ doc](https://grnsft.org/hack22/FAQ) to learn more about the SDK. + +You can compete by yourself or join another team if you don't have an idea! Visit our [Project Ideas Matchmaking doc](https://docs.google.com/document/d/14VQZwFe-Q8bxf1TbsNNOXfTT37BFGVfUfk0MzP7rE6c/edit#) where you can find teams to join. + + + +Competition starts on Oct 13 and runs for 3 weeks. + +Hackathon ends with a two-minute pitch presentation on Nov 10, judged by global industry leaders from [Accenture](https://www.linkedin.com/company/accenture/), [Avanade](https://www.linkedin.com/company/avanade/), [Boston Consulting Group (BCG)](https://www.linkedin.com/company/boston-consulting-group/), [Globant](https://www.linkedin.com/company/globant/), [Goldman Sachs](https://www.linkedin.com/company/goldman-sachs/), [Intel Corporation](https://www.linkedin.com/company/intel-corporation/), [Thoughtworks](https://www.linkedin.com/company/thoughtworks/), and [UBS](https://www.linkedin.com/company/ubs/). Hosted by the [Green Software Foundation](https://greensoftware.foundation/). + +If you are convinced already and want to signup to the hackathon register at https://grnsft.org/hack22. + # Carbon Aware SDK -Carbon-Aware Core SDK +You can reduce the carbon footprint of your application by just running things at different times and in different locations. That is because not all electricity is produced in the same way. Most is produced through burning fossil fuels, some is produced using cleaner sources like wind and solar. + +When software does more when the electricity is clean and do less when the electricity is dirty, or runs in a location where the energy is cleaner, we call this **carbon aware software**. + +The Carbon Aware SDK helps you build the carbon aware software solutions with the intelligence to use the greenest energy sources. Run them at the greenest time, or in the greenest locations, or both! Capture consistent telemetry and report on your emissions reduction and make informed decisions. + +With the Carbon Aware SDK you can build software that chooses to run when the wind is blowing, enable systems to follow the sun, moving around the world to where energy is the greenest, and create tools that give insights and help software innovators to make greener software decisions. All of this helps reduce carbon emissions. + +Get started on creating sustainable software innovation for a greener future today! + +# Getting Started + +Head on over to the [Getting Started Guide](./GettingStarted.md) to get up and running. + +# What is the Carbon Aware SDK? + +At its core the Carbon Aware SDK is a WebApi and Command Line Interface (CLI) to assist in building carbon aware software. The functionality across the CLI and WebApi is identical by design. + +## The WebApi +The WebApi is the preferred deployment within large organisations to centralise management and increase control and auditability, especially in regulated environments. It can be deployed as a container for easy management, and can be deployed alongside an application within a cluster or separately. + +![WebApi Screenshot](./images/screenshot_web_api.png) + +## The CLI + +The CLI tends to be handy for legacy integration and non-cloud deployments, where a command-line can be used. This tends to be common with legacy DevOps pipelines to drive deployment for integration testing where you can test your deployment in the greenest location. + +![WebApi Screenshot](./images/screenshot_cli.png) + +# Who Is Using the Carbon Aware SDK? + +The Carbon Aware SDK is being used by large and small companies around the world. Some of the world’s biggest enterprises and software companies, through to start-ups. + +Machine Learning (ML) workloads are a great example of long running compute intensive workloads, that often are also not time critical. By moving these workloads to a different time, the carbon emissions from the ML training can be reduced by up to 15%, and by moving the location of the training this can be reduced even further, at times by up to 50% or more. + +# What does the SDK/API provide that 3rd party data providers such as WattTime or ElectricityMap do not? +Many of the benefits tend to relate to removing the tight coupling of an application from the 3rd party data source it is using, and allow the application to focus on the sustainability impact it is looking to drive. This abstraction allows for changing of data providers, data provider aggregation, centralised management, auditability and traceability, and more. + +## Collaborative Effort +The Carbon Aware SDK is a collaborative effort between companies around the world, with the intention of providing a platform that everyone can use. This means the API will be striving towards what solves the highest impact issues with diverse perspectives from these organisation and contributors. + +## Standardization +Something we are driving with the Carbon Aware SDK is towards standardisation of the interface into these data providers. This ultimately will help to drive SCI calculations in the future, and also helps to drive innovation. The 3rd party API’s do differ, and the results can vary in units, from lbCO2/kWh to gCO2/Wh. The Carbon Aware SDK will take care of all conversions to a standardised gCO2/kWh, which becomes increasingly valuable with aggregated data sources. + +Standardisation also helps drive innovation. For example, if a 3rd party develops tools to scale Kubernetes clusters based on emissions, they can build against the Carbon Aware SDK. If you want to use this 3rd party tool, the SDK allows the tool to plug in _your_ choice of data providers, not _their_ choice of data provider. In this way the standardisation drives innovation and flexibility of choice. + +The intention is to have other compatible tooling and software that leverages the Carbon Aware SDK to obtain emissions data, while being agnostic to the data provider. + +## Centralised secret and key management +The ability to manage keys to 3rd party API’s can be centralised with the Carbon Aware API. This means that any changes to keys or rotation can be done in a centralised and controlled manner without exposing the keys to application development teams. + +It also can be upgraded across all applications within an organisation when centralised, with new data sources being added without consuming applications to make any changes. + +In addition, the need for the Carbon Aware SDK is something that has been identified by some of the largest enterprises when looking to drive innovation within their own organisations by centralising the capability within their business, creating green software engineering practices and providing the API internally across their organisation. + +## Auditability +Due to the API being centralised, this gives you the ability to audit a controlled environment for when decisions are made. With increasing regulatory need, the ability to prove sustainability actions and impact will need to be from highly trusted sources, and having centralised management provides this capability. + +## Aggregated Sources +A feature we have in the roadmap is the ability aggregate data sources across multiple providers. Different data providers have different levels of granularity depending on region, and it may be that data provider A is preferred in Japan, while data provider B is preferred in US regions. + +Similarly, you may have your own data for your data centres that you would prefer to use for on premises workloads, which you can combine in aggregate with 3rd party data providers. + +# Is it possible to retrieve energy mix information from the SDK? +Energy mix (the percentages that are from different energy soruces i.e. coal, nuclear, wind, gas, solar, tidal, hydro etc) is not provided in the API to date. This may be a feature we will consider in the future. The SDK provides emissions percentage information only at the moment. + +# Contributing + +The Carbon Aware SDK is open for contribution! Want to contribute? Check out the [contribution guide](./CONTRIBUTING.md). + +# Green Software Foundation Project Summary + +The Carbon Aware SDK is a project as part of the [Green Software Foundation](https://greensoftware.foundation/) (GSF) and the GSF Open Source Working Group. + +## Appointments + +- Chair/Project lead - Vaughan Knight (Microsoft) +- Vice Chair - Szymon Duchniewicz (Avanade) + +## GSF Project Scope + +For developers to build carbon aware software, there is a need for a unified baseline to be implemented. The Carbon Aware Core SDK is a project to build a common core, that is flexible, agnostic, and open, allowing software and systems to build around carbon aware capabilities, and provide the information so those systems themselves become carbon aware. + +The Carbon Aware Core API will look to standardise and simplify carbon awareness for developers through a unified API, command line interface, and modular carbon-aware-logic plugin architecture. diff --git a/action.yml b/action.yml new file mode 100644 index 000000000..cfcb3b7f9 --- /dev/null +++ b/action.yml @@ -0,0 +1,45 @@ +name: 'CarboneAware GitHub Action' +description: 'A Github Action to enable the creation of carbon aware applications, applications that do more when the electricity is clean and do less when the electricity is dirty' +branding: + icon: activity + color: purple +inputs: + location: + description: + 'Required. The location is a comma seperated list of named locations or regions specific to the emissions data provided.' + required: true + config: + description: + 'Custom carbon aware configuration file' + required: false + default: '/carbon-aware.json' + lowest: + description: + 'Only return the lowest emission result of all matching results' + required: false + fromTime: + description: + 'The desired date and time to retrieve the emissions for. Defaults to "now". ' + required: false + toTime: + description: + 'The date and time to get the emissions to when looking across a time window.' + required: false + default: 'now' + verbose: + description: + 'Set output to verbose messages.' + required: false + +runs: + using: 'docker' + image: 'Dockerfile' + args: + - ${{ inputs.location }} + - ${{ inputs.config }} + - '--lowest' + + +outputs: + LowestEmissionsLocation: # id of the output + description: 'The Region with Lowet Carbon Emissions, within the list of specified regions as input, at the specified time frame.' diff --git a/docs/architecture/data-sources.md b/docs/architecture/data-sources.md new file mode 100644 index 000000000..dd064fa26 --- /dev/null +++ b/docs/architecture/data-sources.md @@ -0,0 +1,49 @@ +# Data Sources + +Data sources allow developers easily integrate different data providers into the carbon aware SDK ([WattTime](https://www.wattime.org), [ElectricityMap](https://static.electricitymap.org), etc) to be made available to all higher level user-interfaces (WebAPI, CLI, etc), while avoiding the details of how to interact with any specific provider. + +## Creating a New Data Source + +To create a new data source, create a new dotnet project with the following steps: + +```sh +cd src +dotnet new classlib --name CarbonAware.DataSources.MyNewDataSource -o CarbonAware.DataSources/CarbonAware.DataSources.MyNewDataSource/src +dotnet sln add CarbonAware.DataSources/CarbonAware.DataSources.MyNewDataSource/src/CarbonAware.DataSources.MyNewDataSource.csproj +dotnet add CarbonAware.DataSources/CarbonAware.DataSources.MyNewDataSource/src/CarbonAware.DataSources.MyNewDataSource.csproj reference CarbonAware/src/CarbonAware.csproj +cd CarbonAware.DataSources/CarbonAware.DataSources.MyNewDataSource/src +dotnet add package Microsoft.Extensions.DependencyInjection +``` + +Add unit tests: + +```sh +cd src +dotnet new nunit --name CarbonAware.DataSources.MyNewDataSource.Tests -o CarbonAware.DataSources/CarbonAware.DataSources.MyNewDataSource/test +dotnet sln CarbonAwareSDK.sln add CarbonAware.DataSources/CarbonAware.DataSources.MyNewDataSource/test/CarbonAware.DataSources.MyNewDataSource.Tests.csproj +cd CarbonAware.DataSources/CarbonAware.DataSources.MyNewDataSource +dotnet add tests/CarbonAware.DataSources.MyNewDataSource.Tests.csproj reference src/CarbonAware.DataSources.MyNewDataSource.csproj +``` + +Create a Service Collection Extension in the `Configuration` directory: + +```sh +cd src/CarbonAware.DataSources/CarbonAware.DataSources.MyNewDataSource/src +mkdir Configuration +touch Configuration\ServiceCollectionExtensions.cs +``` + +```csharp +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection.Extensions; + +namespace CarbonAware.DataSources.MyNewDataSource.Configuration; + +public static class ServiceCollectionExtensions +{ + public static void AddMyNewDataSource(this IServiceCollection services) + { + // ... register your data source with the IServiceCollection instance + } +} +``` diff --git a/docs/architecture/decisions/0000-ladr-template.md b/docs/architecture/decisions/0000-ladr-template.md new file mode 100644 index 000000000..b3c5c09ec --- /dev/null +++ b/docs/architecture/decisions/0000-ladr-template.md @@ -0,0 +1,38 @@ +# 1. Title +> Anything quoted, such as this, should be removed in the final template and is provided for guidance only + +## Status + +[Proposed, Accepted, Deprecated, Superseded] + +## Context + +## Decision + +## Consequences + +## Green Impact +[Positive, Neutral, Negative] + +> Does this ADR have a notable positive, neutral, or negative impact in relation to the Principles of Green Software. +> +> Include the major impact considerations across CPU intensity, hardware, network, behavioural, usage. Avoid minor impact concerns to give focus. It does not need to be detailed and in depth, but it should be clear in explaining why it's considered positive, neutral, or negative. +> +> Neutral cases may at times be self explanatory and a description won't be required. +> +> If it is negative, is there any plan or action to revisit this decision? +> +> If the ADR is a Green focused ADR, the section detail can simply say "Refer to the above". +> ### Positive example +> * ADR: Moved to elastic servers to reduce costs. +> * Green Impact: +> * Positive. Elastic servers reduce hardware requirements and also reduce compute intensity during low demand periods. +> ### Neutral example +> * ADR: Moved to different version of Tensorflow for feature +> * Green Impact: +> * Neutral +> ### Negative example +> * ADR: Moved to static VM deployment from elastic due to platform bug +> * Green Impact: +> * Negative. Static VM's will require a higher hardware and CPU intensity at all times. Once the bug is resolved we will look to move back to elastic. This is tracked via Issue #... + diff --git a/docs/architecture/decisions/0001-record-architecture-decisions.md b/docs/architecture/decisions/0001-record-architecture-decisions.md new file mode 100644 index 000000000..2794b9d8c --- /dev/null +++ b/docs/architecture/decisions/0001-record-architecture-decisions.md @@ -0,0 +1,18 @@ +# 1. Record Architecture Decisions + +## Status +Accepted + +## Context +We need to record the architectural decisions made on this project. + +## Decision +We will use Architecture Decision Records, as described by Michael Nygard in this article: http://thinkrelevance.com/blog/2011/11/15/documenting-architecture-decisions + +## Consequences +See Michael Nygard's article, linked above. + +## Green Impact +Positive + +By ensuring all architecture decisions have green software considerations, we will endeavour this to drive greener software engineering behaviours. \ No newline at end of file diff --git a/docs/architecture/decisions/0002-dev-containers.md b/docs/architecture/decisions/0002-dev-containers.md new file mode 100644 index 000000000..963b11d04 --- /dev/null +++ b/docs/architecture/decisions/0002-dev-containers.md @@ -0,0 +1,24 @@ +# 2. Dev Containers + +## Status +Accepted + +## Context +Development activities require consistency for all developers to have the same level of access to create Greeen Software as much as possible. The barrier to entry should be as low as possible, the need to install the correct versions, and get started with a pre-configured developer environment is key to leveraging an ASK. The focus should be on "creating green software" as soon as possible, as opposed to "getting ready to install the environment to create green software". + +In addition consistency between developer environments, the ability to resolve issues, debug fellow contributor issues should be as consistent as possible. + +## Decision +All developer experience and documentation should be focused on the dev container experience. Any platform dependent documentation (for now) should be kept minimal. + +## Consequences +All platforms will have consistency, allowing for faster development of the SDK, and more focus on features vs platform dependencies. + +Platform dependenct implementations and deployments will not have a focus as they are abstracted. + +## Green Impact +Positive + +By creating consistency in the developer environment we can ensure green practices can be considered across all developer environments. This consistency removes the compute minutes/hours of setup and time lost debugging across environments, and testing time due to consistency across all environments. + +Operating a dev container requires similar CPU intensity with higher memory requirements. Developers are highly likely to already meet these hardware requirements and be using dev containers (no additional hardware required). \ No newline at end of file diff --git a/docs/architecture/decisions/0003-command-line-params-to-config.md b/docs/architecture/decisions/0003-command-line-params-to-config.md new file mode 100644 index 000000000..742be25b6 --- /dev/null +++ b/docs/architecture/decisions/0003-command-line-params-to-config.md @@ -0,0 +1,30 @@ +# 3. Move Command Line Parameters to Config File + +## Status +Accepted + +## Context +The CLI works currently through a variety of command line parameters, and while this works for the current array of options, it is unlikely to cater for future needs. + +With a dynamic plugin based architecture, plugins will require a variety of custom configurations that can not be predetermined by the command line. + +To handle this we need to abstract this complexity of "how" the SDK is configured from the command line parameters. + +## Decision +The decisions is to move all command line parameters other than time "-t --time -toTime" and location "-l --location" parameters to a standard "carbon-aware.config". The only other command line parameters that will remain are "-h --help" and a new command line parameter to define the configuration file location "-c --config". + +The file will be a json file due to json being widely known, and static data files already being in json, so this will not introduce any other dependencies or skills. + +## Consequences +This will mean the application will have a standalone executable + a config file. + +The usage focus becomes more of "when" and "where" vs "how". "How" is now configured. + +Regardless of plugin, the command line parameters will always be the same. This will create more consistency. Due to this, testing command line will now be consistent across plugins due to the configuration file being the only change. + +For native integration to the SDK, this configuration would usually be in code. This can still occur, however it would not be possible to store this configuration externally if required, making the native code configurable also. + +Configuration may differ betweeen platforms/languages - however this would be the case via command line. This means there will be consistency in the command line between platforms, hiding platform depdendencies from the parameters and moved to the config. + +## Green Impact +Neutral \ No newline at end of file diff --git a/docs/architecture/decisions/0004-documentation.md b/docs/architecture/decisions/0004-documentation.md new file mode 100644 index 000000000..0025803f6 --- /dev/null +++ b/docs/architecture/decisions/0004-documentation.md @@ -0,0 +1,95 @@ +# 4. Documentation + +## Status + +Accepted + +## Context + +There are README.md files in many different directories and little clarity as to who that documentation is meant to serve. Some are focused on users operating the software, others on developers extending the software, sometimes both in the same file. There are also various other markdown files with a wide range of completeness. As a user it is hard to know where to look to run the software and as a developer it is unclear where new documentation should live and for whom it needs to be written. + +## Decision + +Documents containing metadata about the repository/project or communicating organizational processes shall live at the root. Examples include the project overview `README.md`, `CONTRIBUTING.md`, `LICENSE.md`, etc. + +All documentation regarding the usage, extension, or additional development of the carbon-aware-sdk software shall live in the `/docs` directory. + +Documentation focused on using the software as-is (CLI installation, configuration docs, running the web API, etc) shall be kept separate from documentation focused on developing new features or extending the sdk. + +No documentation shall live outside the `root` or `/docs` directories. All other `README.md` files must only contain relative links back to the appropriate `/docs` file. EG: + +> `./src/CarbonAware.WebApi/README.md` +> +> ```markdown +> # CarbonAware.WebApi +> +> * [Getting started](/docs/carbon-aware-webapi.md) +> * [Architecture](/docs/architecture/overview.md) +> ``` + +To enforce file consistency for readers and authors, documentation will be linted using [markdownlint](https://github.com/DavidAnson/markdownlint/tree/main). + +## Consequences + +### Immediate Changes + +If this structure is accepted the follow changes would be required to align the repository: + +* placeholder files in `/carbon-aware-sdk` are deleted. +* `/carbon-aware-sdk/license.md` is moved to `/LICENSE.md` +* `/carbon-aware-sdk/Readme.md` content is rehomed to `/README.md` as appropriate. +* `/images/placehold.md` is deleted. +* `/images` directory is moved to `/docs/images`. +* `GettingStarted.md` content is rehomed to the `/docs` directory as appropriate. +* Content from the `README.md` files in the `/src` directory/sub-directories (detailed below) are rehomed to new files in the `/docs` directory. + * `src\README.md` + * `src\CarbonAware.Aggregators\src\CarbonAware\README.md` + * `src\CarbonAware.LocationSources\CarbonAware.LocationSources.Azure\README.md` + * `src\CarbonAware.Tools\CarbonAware.Tools.AWSRegionTestDataGenerator\README.md` + * `src\CarbonAware.Tools\CarbonAware.Tools.AzureRegionTestDataGenerator\README.md` + * `src\CarbonAware.Tools\CarbonAware.Tools.WattTimeClient\src\README.md` + * `src\CarbonAware.WebApi\src\README.md` + * `src\CarbonAware\src\docs\README.md` +* Minor formatting changes made to all files to address existing linting warning. + +More examples provided in the [Appendix](#appendix). + +### Longer Term Impact + +In the current [monorepo](https://en.wikipedia.org/wiki/Monorepo) structure, this change should make documentation easier to find, use, and write. However, this type of consolidation is non-trivial to separate out (especially as it grows) should the project decide to split components into different repositories in the future. + +## Green Impact + +Neutral + +## Appendix + +Here is an example of what this repository's documentation may look like following implementation of this ADR proposal: + +```text +./ + ┣ docs/ + ┃ ┣ architecture/ + ┃ ┃ ┣ decisions/ + ┃ ┃ ┃ ┣ 0000-ladr-template.md + ┃ ┃ ┃ ┣ 0001-record-architecture-decisions.md + ┃ ┃ ┃ ┣ 0002-dev-containers.md + ┃ ┃ ┃ ┣ 0003-command-line-params-to-config.md + ┃ ┃ ┃ β”— 0004-documentation.md + ┃ ┃ ┣ overview.md + ┃ ┃ ┣ user-interfaces.md + ┃ ┃ ┣ aggregators.md + ┃ ┃ β”— data-sources.md + ┃ ┣ quickstart.md + ┃ ┣ configuration.md + ┃ ┣ carbon-aware-webapi.md + ┃ β”— carbon-aware-cli.md + ┣ samples/ + ┃ ┣ helmexample/ + ┃ ┃ β”— README.md + ┃ β”— python-proxy-server/ + ┃ β”— README.md + ┣ README.md + ┣ CONTRIBUTIING.md + β”— LICENSE.md +``` diff --git a/docs/carbon-aware-cli.md b/docs/carbon-aware-cli.md new file mode 100644 index 000000000..f7d8ecd05 --- /dev/null +++ b/docs/carbon-aware-cli.md @@ -0,0 +1,102 @@ +# Carbon Aware CLI + +The CLI is best for use with systems you can not change the code in but can invoke command line. For example - build pipelines. + +The CLI exposes the primary `getEmissionsByLocationsAndTime` SDK methods via command line and outputs the results as json to stdout. + +> You can use the CLI via a docker image. + +## Format + +`$ CarbonAwareCLI -t