Git Product home page Git Product logo

Comments (13)

greenled avatar greenled commented on July 18, 2024

Thank you @kaotika for putting all this together. I'll give it a shot later.

from portainer-stack-utils.

greenled avatar greenled commented on July 18, 2024

FTR, this thread started in #20.

from portainer-stack-utils.

greenled avatar greenled commented on July 18, 2024

@kaotika while adding config and secret management would in deed make the tool more powerful, it would also be a first step towards a "reinventing the wheel" situation. Soon it could get like "what about container management?", "and image management?", "and network management?", and ... after a while it would end up being a bad copy of the Docker client, and something practically impossible for me to maintain.

I have an idea that solves most parts of this issue. As the Portainer API exposes an endpoint's Docker API through /api/endpoint/{id}/docker, this tool could accept requests from a local Docker client and proxy them to the exposed Docker API. This would allow to run docker ... commads in a remote Docker daemon like in a local one (see #29).

What do you think?

from portainer-stack-utils.

kaotika avatar kaotika commented on July 18, 2024

@greenled this sounds like a great idea. I'am mostly happy with docker, except the absence of propper access control.

from portainer-stack-utils.

greenled avatar greenled commented on July 18, 2024

@kaotika please check out 2.0.0-alpha.3 release. It includes a first aproximation to proxying requests from a Docker client to Portainer, which should fulfill your config and secret management needs.

from portainer-stack-utils.

kaotika avatar kaotika commented on July 18, 2024

@greenled Wow, this is great! I did a quick check and basically it works. Great job! 🥇

What's not working, is creating a stack with configs. The proxy crashed with FATA. (the number always changes...is it important?, I ran the proxy with --log-level=debug)
I tried to track down the issue and find out, that creating a config or a secret works, but does not set the proper ownership to the logged in user. I assume, that prevents the stack deploy to work properly. Most likely this is a problem with portainer, rather psu.

from portainer-stack-utils.

greenled avatar greenled commented on July 18, 2024

@kaotika I found the root cause of the error. When a config/secret or any other Docker resource is created with the proxy method no resource control policy is added for it, so by default it belongs to administrators only. Creating a Docker resource in Portainer's web UI takes two calls: one to /api/endpoint/{id}/docker to create the resource and another one to /api/resource_controls to create a resource control for it. I'm working on a command for PSU to create/read/update/remove such resource controls.

I am considering two designs:

3 generic commands:

psu resource access set <--type container|volume|service|secret|config|stack|network> <--resource resourceId> <--public | --teams <commaSeparatedTeamIds> | --users <commaSeparatedUserIds>> [--subresources <commaSeparatedSubresourceIds>]
psu resource access get <--type <container|volume|service|secret|config|stack|network>> <--resource <resourceId>>
psu resource access clear <--type <container|volume|service|secret|config|stack|network>> <--resource <resourceId>>

21 specific commands (3 for each of the 7 resource types, no --type flag, and resource id passed as an argument):

psu container access set <containerID> <--public | --teams <commaSeparatedTeamIds> | --users <commaSeparatedUserIds>> [--subresources <commaSeparatedSubresourceIds>]
psu container access get <containerID>
psu container access clear <containerID>
psu volume access set <volumeID> <--public | --teams <commaSeparatedTeamIds> | --users <commaSeparatedUserIds>> [--subresources <commaSeparatedSubresourceIds>]
psu volume access get <volumeID>
psu volume access clear <volumeID>
psu service access set <serviceID> <--public | --teams <commaSeparatedTeamIds> | --users <commaSeparatedUserIds>> [--subresources <commaSeparatedSubresourceIds>]
psu service access get <serviceID>
psu service access clear <serviceID>
psu secret access set <secretID><--public | --teams <commaSeparatedTeamIds> | --users <commaSeparatedUserIds>> [--subresources <commaSeparatedSubresourceIds>]
psu secret access get <secretID>
psu secret access clear <secretID>
psu config access set <configID><--public | --teams <commaSeparatedTeamIds> | --users <commaSeparatedUserIds>> [--subresources <commaSeparatedSubresourceIds>]
psu config access get <configID>
psu config access clear <configID>
psu stack access set <stackID><--public | --teams <commaSeparatedTeamIds> | --users <commaSeparatedUserIds>> [--subresources <commaSeparatedSubresourceIds>]
psu stack access get <stackID>
psu stack access clear <stackID>
psu network access set <networkID><--public | --teams <commaSeparatedTeamIds> | --users <commaSeparatedUserIds>> [--subresources <commaSeparatedSubresourceIds>]
psu network access get <networkID>
psu network access clear <networkID>

I would go with the second design as it's less error prone, focuses on the client user instead of the API, and follows the Docker client sintax without overlapping. Though, those 21 new commands look intimidating. Maybe if I find a way to generate them at runtime...

Which variant do you think would fit better? Or maybe you have another idea?

from portainer-stack-utils.

greenled avatar greenled commented on July 18, 2024

@deviantony please could you give some clarification here. I see Portainer injects a Portainer field with access control information in the JSON responses for inspecting Docker resources. This is widely used in the web UI, but it's not documented anywhere I could find. Is this part of the Portainer public API? Is it ok if I build on top of this? I would use this feature in the implementation of the ... access get ... commands described above.

from portainer-stack-utils.

deviantony avatar deviantony commented on July 18, 2024

@greenled

Indeed, Portainer decorates all the Docker resources GET operation responses with a Portainer property if a resource control exists for the specified Docker resource.

This property is an object containing a ResourceControl object based on the definition available at: https://github.com/portainer/portainer/blob/develop/api/portainer.go#L441-L457

If no resource control is applied on the resource, this resource is considered to be manageable by Administrator users only.

I'm not sure why you would need to manage all the existing type of resource controls that we can set via Portainer as I thought this tool was only used to manage stacks. If that is the case, just manage resource controls set on stacks. When sending requests through the Portainer API, Portainer will take care of retrieving all the resources (and resource controls) associated to the stack.

So for example, if you set a restricted access on a stack, when you list containers Portainer will read the label associated to each container and if the stack label exists (com.docker.stack.namespace in Swarm stack for example) it will automatically decorate the resource with the stack resource control.

from portainer-stack-utils.

greenled avatar greenled commented on July 18, 2024

Thank you for the info @deviantony. The example you provide works for resources created with the stack. The idea of managing resource control came from the need of using external configs and secrets in the deployed stacks (see #20), which can be generalized to using external: true resources when deploying stacks.

Portainer admin users can create and use resources by querying /endpoints/{Id}/docker, but in order for this to work for non-admin users they have to set proper resource control after creation. Any Docker resource can fall in the "external" category when deploying a stack, that's why I want to add resource control commands for each kind of resource.

from portainer-stack-utils.

greenled avatar greenled commented on July 18, 2024

BTW @kaotika, the number in the log after FATA represents how many seconds have passed since program started.

from portainer-stack-utils.

kaotika avatar kaotika commented on July 18, 2024

@greenled I think the design to just set the correct resources is the way to go. Everything else seems to complicated.

from portainer-stack-utils.

greenled avatar greenled commented on July 18, 2024

@kaotika on a second thought, design could be an even simpler (I think) mix of both aproaches. As removing an access control is the same as setting it to public, no clear commands. As I see little to no point in getting access control information in commandline (better use the web UI), no get commands. And the endpoint has to be specified, implicit or explicit.

psu stack access <stackName> <--admins | --private | --public> [--endpoint <endpointName>]
psu volume access <volumeName> <--admins | --private | --public> [--endpoint <endpointName>]
psu container access <containerName|containerID> <--admins | --private | --public> [--endpoint <endpointName>]
psu service access <serviceName|serviceID> <--admins | --private | --public> [--endpoint <endpointName>]
psu secret access <secretName|secretID> <--admins | --private | --public> [--endpoint <endpointName>]
psu config access <configName|configID> <--admins | --private | --public> [--endpoint <endpointName>]
psu network access <networkName|networkID> <--admins | --private | --public> [--endpoint <endpointName>]
  • --admins administrators only
  • --private current user only
  • --public all users

This new draft intentionally leaves users and groups lists out. They could be added later, as it involves a higher complexity.

from portainer-stack-utils.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.