Skip to content

add provisioners command#252

Merged
astromechza merged 24 commits intoscore-spec:mainfrom
lekaf974:feat/add-provisioners-cmd
Mar 1, 2025
Merged

add provisioners command#252
astromechza merged 24 commits intoscore-spec:mainfrom
lekaf974:feat/add-provisioners-cmd

Conversation

@lekaf974
Copy link
Copy Markdown
Contributor

@lekaf974 lekaf974 commented Jan 24, 2025

Description

What does this PR do?

Fix #237

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • New chore (expected functionality to be implemented)

Checklist:

  • My change requires a change to the documentation.
    • I have updated the documentation accordingly.
  • I've signed off with an email address that matches the commit author.

@lekaf974
Copy link
Copy Markdown
Contributor Author

lekaf974 commented Jan 24, 2025

@astromechza this is a draft like a starting point. I have exposed type and class on the interface can you take a look and let me know if I am on the good track or if it could have a cleaner way to achieve it before I move forward.
Thanks

also output with current implementation:

go run cmd/score-compose/main.go provisioners list
INFO: Listing provisioners in project 'test1'
INFO: Class: (any), Type: volume
INFO: Class: (any), Type: service-port
INFO: Class: (any), Type: redis
INFO: Class: (any), Type: postgres
INFO: Class: (any), Type: s3
INFO: Class: (any), Type: amqp
INFO: Class: (any), Type: dns
INFO: Class: (any), Type: route
INFO: Class: (any), Type: mongodb
INFO: Class: (any), Type: mysql
INFO: Class: (any), Type: kafka-topic
INFO: Class: (any), Type: elasticsearch

@lekaf974
Copy link
Copy Markdown
Contributor Author

Last changes pushed give

go run cmd/score-compose/main.go provisioners list
INFO: Listing provisioners in project 'test1'
+-------+-----------+--------------------------------+
| TYPE  |   CLASS   |            OUTPUTS             |
+-------+-----------+--------------------------------+
| mysql | (any)     | host, port, name, database,    |
|       |           | username, password             |
| mssql | database  | server, port, connection, tcp, |
|       |           | database, username, password   |
| mssql | database  | server, port, connection, tcp, |
|       |           | database, username, password   |
| amqp  | messaging | host, port, vhost, username,   |
|       |           | password                       |
+-------+-----------+--------------------------------+

@lekaf974
Copy link
Copy Markdown
Contributor Author

@astromechza could you have a look and tell me if I am on the good track or if you see a more elegant way to extract outputs value ?

@lekaf974
Copy link
Copy Markdown
Contributor Author

also all tests are ok

matthieu@pop-os:~/Repos/github/score/score-compose$ go test ./...
?       github.com/score-spec/score-compose/cmd/score-compose   [no test files]
?       github.com/score-spec/score-compose/internal/logging    [no test files]
?       github.com/score-spec/score-compose/internal/project    [no test files]
ok      github.com/score-spec/score-compose/internal/command    3.351s
ok      github.com/score-spec/score-compose/internal/compose    (cached)
ok      github.com/score-spec/score-compose/internal/provisioners       (cached)
ok      github.com/score-spec/score-compose/internal/provisioners/cmdprov       (cached)
ok      github.com/score-spec/score-compose/internal/provisioners/envprov       (cached)
ok      github.com/score-spec/score-compose/internal/provisioners/loader        (cached)
ok      github.com/score-spec/score-compose/internal/provisioners/templateprov  (cached)
ok      github.com/score-spec/score-compose/internal/util       (cached)
ok      github.com/score-spec/score-compose/internal/version    (cached)

@lekaf974
Copy link
Copy Markdown
Contributor Author

lekaf974 commented Feb 1, 2025

With latest changes I have params also

+--------------+-----------+------------------+--------------------------------+
|     TYPE     |   CLASS   |      PARAMS      |            OUTPUTS             |
+--------------+-----------+------------------+--------------------------------+
| mysql        | (any)     |                  | host, port, name, database,    |
|              |           |                  | username, password             |
| mssql        | database  |                  | server, port, connection, tcp, |
|              |           |                  | database, username, password   |
| route        | (any)     | port, host, path |                                |
| mssql        | database  |                  | server, port, connection, tcp, |
|              |           |                  | database, username, password   |
| amqp         | messaging |                  | host, port, vhost, username,   |
|              |           |                  | password                       |
| service-port | (any)     | workload, port   | hostname, port                 |
+--------------+-----------+------------------+--------------------------------+

@lekaf974 lekaf974 marked this pull request as ready for review February 1, 2025 15:01
Copy link
Copy Markdown

@delca85 delca85 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look very good, I'd propose to add some unit tests for the more complex provisioner to check their behaviour in isolation.

@lekaf974
Copy link
Copy Markdown
Contributor Author

lekaf974 commented Feb 4, 2025

thanks @delca85 I'll add more tests on both

@lekaf974 lekaf974 force-pushed the feat/add-provisioners-cmd branch from 66d84af to 10d5089 Compare February 5, 2025 02:33
@lekaf974 lekaf974 requested a review from delca85 February 5, 2025 03:29
Copy link
Copy Markdown

@delca85 delca85 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @lekaf974 for adding the tests, I've just one more question than I think this is good to go 🚀

@mathieu-benoit
Copy link
Copy Markdown
Contributor

Another thoughts, @lekaf974, I'm wondering if sorting alpabetically both the type and the params/outputs would improve the UX and how users will read/consume this output?

@lekaf974
Copy link
Copy Markdown
Contributor Author

lekaf974 commented Feb 5, 2025

Another thoughts, @lekaf974, I'm wondering if sorting alpabetically both the type and the params/outputs would improve the UX and how users will read/consume this output?

Perfect will see how I can do it

@lekaf974
Copy link
Copy Markdown
Contributor Author

lekaf974 commented Feb 6, 2025

lastest output after applied changes requested

~$ score-compose provisioners list
+---------------+-------+------------------+--------------------------------+
|     TYPE      | CLASS |      PARAMS      |            OUTPUTS             |
+---------------+-------+------------------+--------------------------------+
| amqp          | (any) |                  | host, password, port,          |
|               |       |                  | username, vhost                |
+---------------+-------+------------------+--------------------------------+
| dns           | (any) |                  | host                           |
+---------------+-------+------------------+--------------------------------+
| elasticsearch | (any) |                  | host, password, port, username |
+---------------+-------+------------------+--------------------------------+
| kafka-topic   | (any) |                  | host, name, num_partitions,    |
|               |       |                  | port                           |
+---------------+-------+------------------+--------------------------------+
| mongodb       | (any) |                  | connection, host, mongodb,     |
|               |       |                  | password, port, username       |
+---------------+-------+------------------+--------------------------------+
| mysql         | (any) |                  | database, host, name,          |
|               |       |                  | password, port, username       |
+---------------+-------+------------------+--------------------------------+
| postgres      | (any) |                  | database, host, name,          |
|               |       |                  | password, port, username       |
+---------------+-------+------------------+--------------------------------+
| redis         | (any) |                  | host, password, port, username |
+---------------+-------+------------------+--------------------------------+
| route         | (any) | host, path, port |                                |
+---------------+-------+------------------+--------------------------------+
| s3            | (any) |                  | access_key_id,                 |
|               |       |                  | aws_access_key_id,             |
|               |       |                  | aws_secret_key, bucket,        |
|               |       |                  | endpoint, http, region,        |
|               |       |                  | secret_key                     |
+---------------+-------+------------------+--------------------------------+
| service-port  | (any) | port, workload   | hostname, port                 |
+---------------+-------+------------------+--------------------------------+
| volume        | (any) |                  | source, type                   |
+---------------+-------+------------------+--------------------------------+

@mathieu-benoit
Copy link
Copy Markdown
Contributor

mathieu-benoit commented Feb 6, 2025

@lekaf974 @astromechza, in addition to this default table format (awesome!) and out of curiosity, -o json could be very interesting to more easily process this output, but assuming that it's out of scope of this PR for now and that we will create a future issue/PR for this? Or do we want to tackle this here?

@lekaf974
Copy link
Copy Markdown
Contributor Author

lekaf974 commented Feb 6, 2025

@lekaf974 @astromechza, in addition to this default table format (awesome!) and out of curiosity, -o json could be very interesting to more easily process this output, but assuming that it's out of scope of this PR for now and that we will create a future issue/PR for this? Or do we want to tackle this here?

Perhaps we could do it in a second Ticket ? But I could add it here, it looks not a big work since we have already the data

@mathieu-benoit
Copy link
Copy Markdown
Contributor

mathieu-benoit commented Feb 6, 2025

Perhaps we could do it in a second Ticket ?

Yes for sure, totally fine with that. Up to you ;)

Copy link
Copy Markdown

@delca85 delca85 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thank you very much for your work @lekaf974 !

@lekaf974
Copy link
Copy Markdown
Contributor Author

lekaf974 commented Feb 7, 2025

LGTM! Thank you very much for your work @lekaf974 !

I am happy to contribute, i am trying to improve my development skills in Golang so just give it a try!

@lekaf974
Copy link
Copy Markdown
Contributor Author

Any updates ?

@mathieu-benoit
Copy link
Copy Markdown
Contributor

@astromechza, one last review on this one please? Thanks!

Copy link
Copy Markdown
Member

@astromechza astromechza left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I've been slow, been on holiday, but getting back now!

return []string{}
}
re := regexp.MustCompile(`\w+:`)
matches := re.FindAllString(p.OutputsTemplate, -1)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry I've been slow getting back to this, but this has flaws and is an NP-hard problem in general (you can't know the result without evaluating the template). The Params() function above has the same issue.

Please just hardcode the expected outputs and supported parameters as fields in the provisioner, and backfill the existing default provisioners to have the correct values.

This makes it simpler, and means we can enforce the values elsewhere in score-compose (probably in a separate ticket):

  1. During provisioner execution, we can validate that the parameters passed in are all in the Params() list of the provisioner.
  2. After provisioner execution, we can validate that the outputs returned from the driver are all in the Outputs() list.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll take a look during next week on your point, thanks for feedback

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, sorry for the run-around on this :)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@astromechza I was not able to work on this last week but got time now. Can you give more details about what you have in mind here

Please just hardcode the expected outputs and supported parameters as fields in the provisioner, and backfill the existing default provisioners to have the correct values.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lekaf974 I mean, in the provisioner data structure that we read from yaml, support a supported_params and expected_outputs field, both string arrays.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@astromechza added expected_output fields, can you confirm I am on the good track before I continue with supported_params

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lekaf974 yeah this is looking good! just 2 comments now

Signed-off-by: lekaf974 <matthieu.evrin@gmail.com>
…s to interface

Signed-off-by: lekaf974 <matthieu.evrin@gmail.com>
Signed-off-by: lekaf974 <matthieu.evrin@gmail.com>
Signed-off-by: lekaf974 <matthieu.evrin@gmail.com>
Signed-off-by: lekaf974 <matthieu.evrin@gmail.com>
Signed-off-by: lekaf974 <matthieu.evrin@gmail.com>
… order

Signed-off-by: lekaf974 <matthieu.evrin@gmail.com>
Signed-off-by: lekaf974 <matthieu.evrin@gmail.com>
Signed-off-by: lekaf974 <matthieu.evrin@gmail.com>
Signed-off-by: lekaf974 <matthieu.evrin@gmail.com>
Signed-off-by: lekaf974 <matthieu.evrin@gmail.com>
@lekaf974 lekaf974 force-pushed the feat/add-provisioners-cmd branch from b95f63d to d06efef Compare February 26, 2025 04:03
@lekaf974
Copy link
Copy Markdown
Contributor Author

lekaf974 commented Feb 26, 2025

Finally added json output support with same fields for now

~$ score-compose provisioners list --help
The list command will list out the provisioners. This requires an active score compose state
after 'init' or 'generate' has been run. The list of provisioners will be empty if no provisioners are defined.

Usage:
  score-compose provisioners list [--format table|json] [flags]

Flags:
  -f, --format string   Format of the output: table (default), json (default "table")
  -h, --help            help for list

Global Flags:
      --quiet           Mute any logging output
  -v, --verbose count   Increase log verbosity and detail by specifying this flag one or more times
~$ score-compose provisioners list --format json
[
  {
    "Type": "amqp",
    "Class": "(any)",
    "Params": "",
    "Outputs": "host, password, port, username, vhost"
  },
  {
    "Type": "dns",
    "Class": "(any)",
    "Params": "",
    "Outputs": "host"
  },
  {
    "Type": "elasticsearch",
    "Class": "(any)",
    "Params": "",
    "Outputs": "host, password, port, username"
  },
  {
    "Type": "kafka-topic",
    "Class": "(any)",
    "Params": "",
    "Outputs": "host, name, num_partitions, port"
  },
  {
    "Type": "mongodb",
    "Class": "(any)",
    "Params": "",
    "Outputs": "connection, host, mongodb, password, port, username"
  },
  {
    "Type": "mysql",
    "Class": "(any)",
    "Params": "",
    "Outputs": "database, host, name, password, port, username"
  },
  {
    "Type": "postgres",
    "Class": "(any)",
    "Params": "",
    "Outputs": "database, host, name, password, port, username"
  },
  {
    "Type": "redis",
    "Class": "(any)",
    "Params": "",
    "Outputs": "host, password, port, username"
  },
  {
    "Type": "route",
    "Class": "(any)",
    "Params": "host, path, port",
    "Outputs": ""
  },
  {
    "Type": "s3",
    "Class": "(any)",
    "Params": "",
    "Outputs": "access_key_id, aws_access_key_id, aws_secret_key, bucket, endpoint, http, region, secret_key"
  },
  {
    "Type": "service-port",
    "Class": "(any)",
    "Params": "port, workload",
    "Outputs": "hostname, port"
  },
  {
    "Type": "volume",
    "Class": "(any)",
    "Params": "",
    "Outputs": "source, type"
  }
]

Signed-off-by: lekaf974 <matthieu.evrin@gmail.com>
Signed-off-by: lekaf974 <matthieu.evrin@gmail.com>
Signed-off-by: lekaf974 <matthieu.evrin@gmail.com>
return []string{}
}
re := regexp.MustCompile(`\w+:`)
matches := re.FindAllString(p.OutputsTemplate, -1)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lekaf974 yeah this is looking good! just 2 comments now

Signed-off-by: lekaf974 <matthieu.evrin@gmail.com>
@lekaf974
Copy link
Copy Markdown
Contributor Author

integrate last changes requested

@mathieu-benoit last question

what would be the better format

 {
    "Type": "service-port",
    "Class": "(any)",
    "Params": "port, workload",
    "Outputs": "hostname, port"
  }

or

{
    "Type": "service-port",
    "Class": "(any)",
    "Params": [
      "port",
      "workload"
    ],
    "Outputs": [
      "hostname",
      "port"
    ]
  }

@lekaf974
Copy link
Copy Markdown
Contributor Author

lekaf974 commented Feb 28, 2025

opening score-spec/docs#161 to update documentation accordingly to those changes

Signed-off-by: lekaf974 <matthieu.evrin@gmail.com>
Signed-off-by: lekaf974 <matthieu.evrin@gmail.com>
@mathieu-benoit
Copy link
Copy Markdown
Contributor

I would vote for the 2nd which is more json compliant, right?

@lekaf974
Copy link
Copy Markdown
Contributor Author

I would vote for the 2nd which is more json compliant, right?

Yes, it makes sense to me and I changed it this way in the last implementation.

Copy link
Copy Markdown
Contributor

@mathieu-benoit mathieu-benoit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, impressive contribution, thanks @lekaf974!

Copy link
Copy Markdown
Member

@astromechza astromechza left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, definitely array of strings please @lekaf974. Looks good!

@astromechza astromechza merged commit 4bb24e8 into score-spec:main Mar 1, 2025
4 checks passed
@astromechza
Copy link
Copy Markdown
Member

Thank you for your contribution @lekaf974

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feature request] Add a new score-compose provisioners list command

4 participants