{"id":34221299,"url":"https://github.com/nobl9/nobl9-openslo","last_synced_at":"2026-05-21T00:10:28.831Z","repository":{"id":289820056,"uuid":"935068989","full_name":"nobl9/nobl9-openslo","owner":"nobl9","description":"Go library for converting between OpenSLO specification and Nobl9 configuration 🔄","archived":false,"fork":false,"pushed_at":"2026-05-20T16:06:51.000Z","size":174,"stargazers_count":2,"open_issues_count":6,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2026-05-20T20:12:22.173Z","etag":null,"topics":["nobl9","openslo","slo"],"latest_commit_sha":null,"homepage":"https://www.nobl9.com/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nobl9.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-02-18T21:15:54.000Z","updated_at":"2026-03-02T00:57:08.000Z","dependencies_parsed_at":"2026-01-01T16:02:59.888Z","dependency_job_id":null,"html_url":"https://github.com/nobl9/nobl9-openslo","commit_stats":null,"previous_names":["nobl9/nobl9-openslo"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/nobl9/nobl9-openslo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nobl9%2Fnobl9-openslo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nobl9%2Fnobl9-openslo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nobl9%2Fnobl9-openslo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nobl9%2Fnobl9-openslo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nobl9","download_url":"https://codeload.github.com/nobl9/nobl9-openslo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nobl9%2Fnobl9-openslo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33281512,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-20T15:12:43.734Z","status":"ssl_error","status_checked_at":"2026-05-20T15:12:42.300Z","response_time":356,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["nobl9","openslo","slo"],"created_at":"2025-12-15T23:11:10.859Z","updated_at":"2026-05-21T00:10:26.789Z","avatar_url":"https://github.com/nobl9.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# nobl9-openslo\n\n[OpenSLO](https://openslo.com) converter for Nobl9!\n\nConvert OpenSLO schema to\n[Nobl9 configuration](https://docs.nobl9.com/yaml-guide) with ease 🚀\n\n\u003e [!TIP]\n\u003e Starting with [sloctl](https://github.com/nobl9/sloctl)\n\u003e [version 0.12.0](https://github.com/nobl9/sloctl/releases/tag/v0.12.0)\n\u003e OpenSLO converter is available as a CLI through `sloctl convert openslo` command.\n\n## Installation\n\nTo add the latest version to your Go module, run:\n\n```sh\ngo get github.com/nobl9/nobl9-go\n```\n\n## Usage\n\n```go\npackage main\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"log\"\n\n\t\"github.com/OpenSLO/go-sdk/pkg/openslosdk\"\n\t\"github.com/nobl9/nobl9-go/sdk\"\n\t\"github.com/nobl9/nobl9-openslo/pkg/openslotonobl9\"\n)\n\nconst opensloData = `\napiVersion: openslo/v1\nkind: Service\nmetadata:\n  annotations:\n    nobl9.com/metadata.project: non-default\n    my.domain/custom: foo\n  name: example-service\nspec:\n  description: Example service description\n`\n\nfunc main() {\n\t// Read OpenSLO objects.\n\tobjects, err := openslosdk.Decode(bytes.NewBufferString(opensloData), openslosdk.FormatYAML)\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to read OpenSLO objects: %v\", err)\n\t}\n\t// Convert OpenSLO to Nobl9.\n\tnobl9Objects, err := openslotonobl9.Convert(objects)\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to convert OpenSLO to Nobl9: %v\", err)\n\t}\n\t// Create Nobl9 SDK client.\n\tclient, err := sdk.DefaultClient()\n\tif err != nil {\n\t\tlog.Fatalf(\"failed to create Nobl9 SDK client: %v\", err)\n\t}\n\t// Apply the objects.\n\tif err = client.Objects().V1().Apply(context.Background(), nobl9Objects); err != nil {\n\t\tlog.Fatalf(\"failed to apply Nobl9 objects: %v\", err)\n\t}\n}\n```\n\n## How it works\n\n1. Resolve object references by either inlining or exporting dependent objects.\n2. Validate decoded and resolved OpenSLO objects according to OpenSLO-defined rules.\n3. Validate decoded and resolved OpenSLO objects according to Nobl9-defined,\n   custom rules.\n4. Convert OpenSLO objects to Nobl9 objects.\n\n### Objects mapping\n\nThe following OpenSLO objects map to Nobl9 schema:\n\n\u003c!-- markdownlint-disable MD013 --\u003e\n| OpenSLO object             | Nobl9 object        | Supported | Extra rules                                                                                |\n|----------------------------|---------------------|:---------:|--------------------------------------------------------------------------------------------|\n| v1.Service                 | v1alpha.Service     |     ✅    |                                                                                            |\n| v1.SLO                     | v1alpha.SLO         |     ✅    |                                                                                            |\n| v1.SLI                     | -                   |     ✖️    | Inlined when referenced by SLO.                                                            |\n| v1.DataSource              | v1alpha.Agent       |     ✅    | By default, an Agent connection is created. Use annotations to create a Direct connection. |\n| v1.AlertPolicy             | v1alpha.AlertPolicy |     ✅    |                                                                                            |\n| v1.AlertCondition          | -                   |     ✖️    | Inlined when referenced by AlertPolicy.                                                    |\n| v1.AlertNotificationTarget | v1.AlertMethod      |     ✅    |                                                                                            |\n\u003c!-- markdownlint-enable MD013 --\u003e\n\nGeneric fields in the OpenSLO schema also have additional rules applied.\n\n#### v1.SLI\n\n`spec.metricSource.spec` field is directly converted to a matching Nobl9\nmetric spec based on the `metricSource.type` field.\n\nExample:\n\n```yaml\n# OpenSLO input:\nmetricSource:\n  type: prometheus\n  spec:\n    promql: sum(http_request_duration_seconds_count{handler=\"/api/v1/slos\"})\n# Nobl9 output:\nquery:\n  prometheus:\n    promql: sum(http_request_duration_seconds_count{handler=\"/api/v1/slos\"})\n```\n\nEach field within `metricSource.spec` must correspond exactly to the\ndefinitions in Nobl9's `query.\u003cmetricSource.type\u003e`.\n\n#### v1.DataSource\n\nSimilar to [_v1.SLI_](#v1sli), the `spec.type` field is used to determine the type\nof Nobl9 data source details, and `spec.connectionDetails` content must match\nNobl9's definition for that data source type.\n\nExample:\n\n```yaml\n# OpenSLO input:\ntype: appDynamics\nconnectionDetails:\n  accountName: nobl9\n  clientID: dev-agent@nobl9\n  clientName: dev-agent\n  clientSecret: secret\n  url: https://example.com\n# Nobl9 output:\nappDynamics:\n  accountName: nobl9\n  clientID: dev-agent@nobl9\n  clientName: dev-agent\n  clientSecret: secret\n  url: https://example.com\n```\n\n### Inlining and exporting rules\n\nThe list of objects passed to the `Convert` method must include all\nobjects referenced within that list.\nFor instance, if `v1.SLO` named _my-slo_ references `v1.SLI` named _my-sli_,\nthen the list must contain `v1.SLI` named _my-sli_.\n\n#### v1.SLO\n\n- `spec.indicatorRef` inlines `v1.SLI`.\n- `spec.alertPolicies[*].alertPolicyRef` inlines `v1.AlertPolicy`.\n  The inlining is done recursively, so that objects referenced by `v1.AlertPolicy`\n  are inlined in the inlined `v1.AlertPolicy`.\n- `spec.alertPolicies[*]` (inlined version) is exported.\n\n#### v1.AlertPolicy\n\n- `spec.conditions[*].conditionRef` inlines `v1.AlertCondition`.\n- `spec.notificationTargets[*]` (inlined version) is exported.\n\n### Modifying Nobl9 objects\n\nEach field in the resulting Nobl9 object can be modified\nusing the `metadata.annotations` field in the OpenSLO object.\nTo change a field in the resulting Nobl9 object, provide an\nannotation in the following format:\n\n```text\nnobl9.com/\u003cfield_path\u003e: \u003cvalue\u003e\n```\n\nExample:\n\n```yaml\n# Input:\napiVersion: openslo/v1\nkind: Service\nmetadata:\n  annotations:\n    nobl9.com/metadata.project: non-default\n    my.domain/custom: foo\n  name: example-service\nspec:\n  description: Example service description\n# Output:\napiVersion: n9/v1alpha\nkind: Service\nmetadata:\n  annotations:\n    my.domain/custom: foo\n  project: non-default\n  name: example-service\nspec:\n  description: Example service description\n```\n\nCommon use cases:\n\n- `nobl9.com/metadata.project` sets the project for the object.\n- `nobl9.com/kind` sets the service kind for the object.\n  This applies only to `DataSource`, allowing\n  users to specify `DataSource` conversion to either `Agent` or `Direct`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnobl9%2Fnobl9-openslo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnobl9%2Fnobl9-openslo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnobl9%2Fnobl9-openslo/lists"}