Merge branch '17944-backend-vocabulary-validation-rebased' into main.
authorLucas Di Pentima <lucas.dipentima@curii.com>
Thu, 11 Nov 2021 17:51:31 +0000 (14:51 -0300)
committerLucas Di Pentima <lucas.dipentima@curii.com>
Thu, 11 Nov 2021 17:51:31 +0000 (14:51 -0300)
Refs #17944

Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas.dipentima@curii.com>

1  2 
doc/admin/upgrading.html.textile.liquid
lib/controller/federation/conn.go
lib/controller/federation/federation_test.go

index 16cbf2e60c0e24fba94e8556bb59175830003115,211b931886bcd3c40e41b1ee7266f01adee060d3..15b8d2c40d4afcabe1efcc30afa6a2c8d939fafe
@@@ -35,7 -35,7 +35,7 @@@ TODO: extract this information based o
  <div class="releasenotes">
  </notextile>
  
- h2(#main). development main (as of 2021-10-27)
+ h2(#main). development main (as of 2021-11-10)
  
  "previous: Upgrading from 2.3.0":#v2_3_0
  
@@@ -46,6 -46,12 +46,12 @@@ When Arvados runs a container via @arva
  * If you already have a robust permanent keepstore infrastructure, you can set @Containers.LocalKeepBlobBuffersPerVCPU@ to 0 to disable this feature and preserve the previous behavior of sending container I/O traffic to your separately provisioned keepstore servers.
  * This feature is enabled only if no volumes use @AccessViaHosts@, and no volumes have underlying @Replication@ less than @Collections.DefaultReplication@. If the feature is configured but cannot be enabled due to an incompatible volume configuration, this will be noted in the @crunch-run.txt@ file in the container log.
  
+ h3. Backend support for vocabulary checking
+ If your installation uses the vocabulary feature on Workbench2, you will need to update the cluster configuration by moving the vocabulary definition file to the node where @controller@ runs, and set the @API.VocabularyPath@ configuration parameter to the local path where the file was placed.
+ This will enable the vocabulary checking cluster-wide, including Workbench2. The @Workbench.VocabularyURL@ configuration parameter is deprecated and will be removed in a future release.
+ You can read more about how this feature works on the "admin page":{{site.baseurl}}/admin/metadata-vocabulary.html.
  h2(#v2_3_0). v2.3.0 (2021-10-27)
  
  "previous: Upgrading to 2.2.0":#v2_2_0
@@@ -292,7 -298,7 +298,7 @@@ Workbench 2 is now ready for regular us
  
  h3. New property vocabulary format for Workbench2
  
- (feature "#14151":https://dev.arvados.org/issues/14151) Workbench2 supports a new vocabulary format and it isn't compatible with the previous one, please read the "workbench2 vocabulary format admin page":{{site.baseurl}}/admin/workbench2-vocabulary.html for more information.
+ (feature "#14151":https://dev.arvados.org/issues/14151) Workbench2 supports a new vocabulary format and it isn't compatible with the previous one, please read the "metadata vocabulary format admin page":{{site.baseurl}}/admin/metadata-vocabulary.html for more information.
  
  h3. Cloud installations only: node manager replaced by arvados-dispatch-cloud
  
@@@ -407,7 -413,7 +413,7 @@@ h3. Python packaging chang
  
  As part of story "#9945":https://dev.arvados.org/issues/9945, the distribution packaging (deb/rpm) of our Python packages has changed. These packages now include a built-in virtualenv to reduce dependencies on system packages. We have also stopped packaging and publishing backports for all the Python dependencies of our packages, as they are no longer needed.
  
 -One practical consequence of this change is that the use of the Arvados Python SDK (aka "import arvados") will require a tweak if the SDK was installed from a distribution package. It now requires the loading of the virtualenv environment from our packages. The "Install documentation for the Arvados Python SDK":/sdk/python/sdk-python.html reflects this change. This does not affect the use of the command line tools (e.g. arv-get, etc.).
 +One practical consequence of this change is that the use of the Arvados Python SDK (aka "import arvados") will require a tweak if the SDK was installed from a distribution package. It now requires the loading of the virtualenv environment from our packages. The "Install documentation for the Arvados Python SDK":{{ site.baseurl }}/sdk/python/sdk-python.html reflects this change. This does not affect the use of the command line tools (e.g. arv-get, etc.).
  
  Python scripts that rely on the distribution Arvados Python SDK packages to import the Arvados SDK will need to be tweaked to load the correct Python environment.
  
index 39e4f2676695bed5fd478a2b1470de1e1d63b6f8,30e1561ee5e917ef8e040c8c38df189021cfa5be..d1bf473d76856abd59bfb35f069e4f47f498e680
@@@ -22,6 -22,7 +22,7 @@@ import 
        "git.arvados.org/arvados.git/sdk/go/arvados"
        "git.arvados.org/arvados.git/sdk/go/auth"
        "git.arvados.org/arvados.git/sdk/go/ctxlog"
+       "git.arvados.org/arvados.git/sdk/go/health"
  )
  
  type Conn struct {
        remotes map[string]backend
  }
  
- func New(cluster *arvados.Cluster) *Conn {
+ func New(cluster *arvados.Cluster, healthFuncs *map[string]health.Func) *Conn {
        local := localdb.NewConn(cluster)
        remotes := map[string]backend{}
        for id, remote := range cluster.RemoteClusters {
                if !remote.Proxy || id == cluster.ClusterID {
                        continue
                }
 -              conn := rpc.NewConn(id, &url.URL{Scheme: remote.Scheme, Host: remote.Host}, remote.Insecure, saltedTokenProvider(local, id))
 +              conn := rpc.NewConn(id, &url.URL{Scheme: remote.Scheme, Host: remote.Host}, remote.Insecure, saltedTokenProvider(cluster, local, id))
                // Older versions of controller rely on the Via header
                // to detect loops.
                conn.SendHeader = http.Header{"Via": {"HTTP/1.1 arvados-controller"}}
                remotes[id] = conn
        }
  
+       if healthFuncs != nil {
+               hf := map[string]health.Func{"vocabulary": local.LastVocabularyError}
+               *healthFuncs = hf
+       }
        return &Conn{
                cluster: cluster,
                local:   local,
@@@ -55,7 -61,7 +61,7 @@@
  // tokens from an incoming request context, determines whether they
  // should (and can) be salted for the given remoteID, and returns the
  // resulting tokens.
 -func saltedTokenProvider(local backend, remoteID string) rpc.TokenProvider {
 +func saltedTokenProvider(cluster *arvados.Cluster, local backend, remoteID string) rpc.TokenProvider {
        return func(ctx context.Context) ([]string, error) {
                var tokens []string
                incoming, ok := auth.FromContext(ctx)
                        return nil, errors.New("no token provided")
                }
                for _, token := range incoming.Tokens {
 +                      if strings.HasPrefix(token, "v2/"+cluster.ClusterID+"-") && remoteID == cluster.Login.LoginCluster {
 +                              // If we did this, the login cluster
 +                              // would call back to us and then
 +                              // reject our response because the
 +                              // user UUID prefix (i.e., the
 +                              // LoginCluster prefix) won't match
 +                              // the token UUID prefix (i.e., our
 +                              // prefix).
 +                              return nil, httpErrorf(http.StatusUnauthorized, "cannot use a locally issued token to forward a request to our login cluster (%s)", remoteID)
 +                      }
                        salted, err := auth.SaltToken(token, remoteID)
                        switch err {
                        case nil:
@@@ -202,6 -198,10 +208,10 @@@ func (conn *Conn) ConfigGet(ctx context
        return json.RawMessage(buf.Bytes()), err
  }
  
+ func (conn *Conn) VocabularyGet(ctx context.Context) (arvados.Vocabulary, error) {
+       return conn.chooseBackend(conn.cluster.ClusterID).VocabularyGet(ctx)
+ }
  func (conn *Conn) Login(ctx context.Context, options arvados.LoginOptions) (arvados.LoginResponse, error) {
        if id := conn.cluster.Login.LoginCluster; id != "" && id != conn.cluster.ClusterID {
                // defer entire login procedure to designated cluster
@@@ -475,6 -475,26 +485,26 @@@ func (conn *Conn) GroupUntrash(ctx cont
        return conn.chooseBackend(options.UUID).GroupUntrash(ctx, options)
  }
  
+ func (conn *Conn) LinkCreate(ctx context.Context, options arvados.CreateOptions) (arvados.Link, error) {
+       return conn.chooseBackend(options.ClusterID).LinkCreate(ctx, options)
+ }
+ func (conn *Conn) LinkUpdate(ctx context.Context, options arvados.UpdateOptions) (arvados.Link, error) {
+       return conn.chooseBackend(options.UUID).LinkUpdate(ctx, options)
+ }
+ func (conn *Conn) LinkGet(ctx context.Context, options arvados.GetOptions) (arvados.Link, error) {
+       return conn.chooseBackend(options.UUID).LinkGet(ctx, options)
+ }
+ func (conn *Conn) LinkList(ctx context.Context, options arvados.ListOptions) (arvados.LinkList, error) {
+       return conn.generated_LinkList(ctx, options)
+ }
+ func (conn *Conn) LinkDelete(ctx context.Context, options arvados.DeleteOptions) (arvados.Link, error) {
+       return conn.chooseBackend(options.UUID).LinkDelete(ctx, options)
+ }
  func (conn *Conn) SpecimenList(ctx context.Context, options arvados.ListOptions) (arvados.SpecimenList, error) {
        return conn.generated_SpecimenList(ctx, options)
  }
index 984d32dc3d9a294fc20bd60b38295aaf890abb37,929d09bc845f51a4851c05a1360a3b5595f115f2..5460e938a66348ec2a98f2a478372ea901c4c235
@@@ -70,7 -70,7 +70,7 @@@ func (s *FederationSuite) SetUpTest(c *
        ctx = ctrlctx.NewWithTransaction(ctx, s.tx)
        s.ctx = ctx
  
-       s.fed = New(s.cluster)
+       s.fed = New(s.cluster, nil)
  }
  
  func (s *FederationSuite) TearDownTest(c *check.C) {
@@@ -93,5 -93,5 +93,5 @@@ func (s *FederationSuite) addHTTPRemote
                Host:   srv.Addr,
                Proxy:  true,
        }
 -      s.fed.remotes[id] = rpc.NewConn(id, &url.URL{Scheme: "http", Host: srv.Addr}, true, saltedTokenProvider(s.fed.local, id))
 +      s.fed.remotes[id] = rpc.NewConn(id, &url.URL{Scheme: "http", Host: srv.Addr}, true, saltedTokenProvider(s.cluster, s.fed.local, id))
  }